Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Jun 2014 20:24:17 +0000 (UTC)
From:      "Pedro F. Giffuni" <pfg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r267746 - stable/10/usr.bin/patch
Message-ID:  <201406222024.s5MKOH9G050393@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pfg
Date: Sun Jun 22 20:24:17 2014
New Revision: 267746
URL: http://svnweb.freebsd.org/changeset/base/267746

Log:
  MFC	r267490:
  patch: unsign the line length to avoid overflows.
  
  Patch(1) uses a short int for the line length, which is usually
  sufficient for regular diffs, but makes no effort to signal
  when there is an overflow.
  
  Change the line length to an unsigned short int to better use
  the fact that a length is never negative.  The change is loosely
  inspired on a related change in DragonFly, but we avoid spending
  more memory than necessary.
  
  While here adjust the messages to be clearer on what is happening.

Modified:
  stable/10/usr.bin/patch/patch.c
  stable/10/usr.bin/patch/pch.c
  stable/10/usr.bin/patch/pch.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.bin/patch/patch.c
==============================================================================
--- stable/10/usr.bin/patch/patch.c	Sun Jun 22 20:13:57 2014	(r267745)
+++ stable/10/usr.bin/patch/patch.c	Sun Jun 22 20:24:17 2014	(r267746)
@@ -742,14 +742,18 @@ abort_context_hunk(void)
 static void
 rej_line(int ch, LINENUM i)
 {
-	size_t len;
+	unsigned short len;
 	const char *line = pfetch(i);
 
-	len = strlen(line);
+	len = strnlen(line, USHRT_MAX);
 
 	fprintf(rejfp, "%c%s", ch, line);
-	if (len == 0 || line[len-1] != '\n')
-		fprintf(rejfp, "\n\\ No newline at end of file\n");
+	if (len == 0 || line[len-1] != '\n') {
+		if (len >= USHRT_MAX)
+			fprintf(rejfp, "\n\\ Line too long\n");
+		else
+			fprintf(rejfp, "\n\\ No newline at end of line\n");
+	}
 }
 
 static void
@@ -1016,7 +1020,7 @@ patch_match(LINENUM base, LINENUM offset
 	LINENUM		pat_lines = pch_ptrn_lines() - fuzz;
 	const char	*ilineptr;
 	const char	*plineptr;
-	short		plinelen;
+	unsigned short	plinelen;
 
 	for (iline = base + offset + fuzz; pline <= pat_lines; pline++, iline++) {
 		ilineptr = ifetch(iline, offset >= 0);

Modified: stable/10/usr.bin/patch/pch.c
==============================================================================
--- stable/10/usr.bin/patch/pch.c	Sun Jun 22 20:13:57 2014	(r267745)
+++ stable/10/usr.bin/patch/pch.c	Sun Jun 22 20:24:17 2014	(r267746)
@@ -56,7 +56,7 @@ static LINENUM	p_max;		/* max allowed va
 static LINENUM	p_context = 3;	/* # of context lines */
 static LINENUM	p_input_line = 0;	/* current line # from patch file */
 static char	**p_line = NULL;/* the text of the hunk */
-static short	*p_len = NULL;	/* length of each line */
+static unsigned short	*p_len = NULL; /* length of each line */
 static char	*p_char = NULL;	/* +, -, and ! */
 static int	hunkmax = INITHUNKMAX;	/* size of above arrays to begin with */
 static int	p_indent;	/* indent to patch */
@@ -134,7 +134,7 @@ set_hunkmax(void)
 	if (p_line == NULL)
 		p_line = malloc(hunkmax * sizeof(char *));
 	if (p_len == NULL)
-		p_len = malloc(hunkmax * sizeof(short));
+		p_len = malloc(hunkmax * sizeof(unsigned short));
 	if (p_char == NULL)
 		p_char = malloc(hunkmax * sizeof(char));
 }
@@ -151,7 +151,7 @@ grow_hunkmax(void)
 		fatal("Internal memory allocation error\n");
 
 	p_line = reallocf(p_line, new_hunkmax * sizeof(char *));
-	p_len = reallocf(p_len, new_hunkmax * sizeof(short));
+	p_len = reallocf(p_len, new_hunkmax * sizeof(unsigned short));
 	p_char = reallocf(p_char, new_hunkmax * sizeof(char));
 
 	if (p_line != NULL && p_len != NULL && p_char != NULL) {
@@ -1201,7 +1201,7 @@ bool
 pch_swap(void)
 {
 	char	**tp_line;	/* the text of the hunk */
-	short	*tp_len;	/* length of each line */
+	unsigned short	*tp_len;/* length of each line */
 	char	*tp_char;	/* +, -, and ! */
 	LINENUM	i;
 	LINENUM	n;
@@ -1358,7 +1358,7 @@ pch_context(void)
 /*
  * Return the length of a particular patch line.
  */
-short
+unsigned short
 pch_line_len(LINENUM line)
 {
 	return p_len[line];

Modified: stable/10/usr.bin/patch/pch.h
==============================================================================
--- stable/10/usr.bin/patch/pch.h	Sun Jun 22 20:13:57 2014	(r267745)
+++ stable/10/usr.bin/patch/pch.h	Sun Jun 22 20:24:17 2014	(r267746)
@@ -44,7 +44,7 @@ bool		there_is_another_patch(void);
 bool		another_hunk(void);
 bool		pch_swap(void);
 char		*pfetch(LINENUM);
-short		pch_line_len(LINENUM);
+unsigned short	pch_line_len(LINENUM);
 LINENUM		pch_first(void);
 LINENUM		pch_ptrn_lines(void);
 LINENUM		pch_newfirst(void);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406222024.s5MKOH9G050393>