Hi,

the hunk size is basically limitated to MAXHUNKSIZE, although the
implementation consideres it as a soft limit:  it's possible to get one
step above this limit.  It's set to 100,000 but hunkmax can be legally
set to 128,000...

This diff unifies the grow check and avoids calling realloc() again and
again until enough space is available.  Instead, it calculates the size
once and therefore calls the realloc()s only once, too.

The point of this diff is to cover the cases in which MAXHUNKSIZE is not
checked.  Having a slightly better performance is just an additional
benefit.


Tobias

Index: pch.c
===================================================================
RCS file: /cvs/src/usr.bin/patch/pch.c,v
retrieving revision 1.42
diff -u -p -r1.42 pch.c
--- pch.c       17 Nov 2014 10:58:09 -0000      1.42
+++ pch.c       17 Nov 2014 15:26:38 -0000
@@ -68,7 +68,7 @@ static LINENUM        p_bfake = -1;   /* beg of f
 static FILE    *pfp = NULL;    /* patch file pointer */
 static char    *bestguess = NULL;      /* guess at correct filename */
 
-static void    grow_hunkmax(void);
+static void    grow_hunkmax(int);
 static int     intuit_diff_type(void);
 static void    next_intuit_at(off_t, LINENUM);
 static void    skip_to(off_t, LINENUM);
@@ -134,17 +134,23 @@ set_hunkmax(void)
 }
 
 /*
- * Enlarge the arrays containing the current hunk of patch.
+ * Enlarge the arrays containing the current hunk of patch for the
+ * specified amount of lines.
  */
 static void
-grow_hunkmax(void)
+grow_hunkmax(int req_size)
 {
        int             new_hunkmax;
        char            **new_p_line;
        short           *new_p_len;
        char            *new_p_char;
 
-       new_hunkmax = hunkmax * 2;
+       if (req_size > MAXHUNKSIZE)
+               fatal("hunk too large (%ld lines) at line %ld: %s",
+                   req_size, p_input_line, buf);
+
+       for (new_hunkmax = hunkmax; req_size >= new_hunkmax; new_hunkmax *= 2)
+               ;
 
        if (p_line == NULL || p_len == NULL || p_char == NULL)
                fatal("Internal memory allocation error\n");
@@ -595,8 +601,8 @@ another_hunk(void)
 
                                /* we need this much at least */
                                p_max = p_ptrn_lines + 6;
-                               while (p_max >= hunkmax)
-                                       grow_hunkmax();
+                               if (p_max >= hunkmax)
+                                       grow_hunkmax(p_max);
                                p_max = hunkmax;
                                break;
                        case '-':
@@ -662,11 +668,8 @@ another_hunk(void)
                                                p_newfirst = 1;
                                        }
                                        p_max = p_repl_lines + p_end;
-                                       if (p_max > MAXHUNKSIZE)
-                                               fatal("hunk too large (%ld 
lines) at line %ld: %s",
-                                                   p_max, p_input_line, buf);
-                                       while (p_max >= hunkmax)
-                                               grow_hunkmax();
+                                       if (p_max >= hunkmax)
+                                               grow_hunkmax(p_max);
                                        if (p_repl_lines != ptrn_copiable &&
                                            (p_context != 0 || p_repl_lines != 
1))
                                                repl_could_be_missing = false;
@@ -882,8 +885,8 @@ hunk_done:
                if (!p_ptrn_lines)
                        p_first++;      /* do append rather than insert */
                p_max = p_ptrn_lines + p_repl_lines + 1;
-               while (p_max >= hunkmax)
-                       grow_hunkmax();
+               if (p_max >= hunkmax)
+                       grow_hunkmax(p_max);
                fillsrc = 1;
                filldst = fillsrc + p_ptrn_lines;
                p_end = filldst + p_repl_lines;
@@ -1040,11 +1043,8 @@ hunk_done:
                if (hunk_type == 'd')
                        min++;
                p_end = p_ptrn_lines + 1 + max - min + 1;
-               if (p_end > MAXHUNKSIZE)
-                       fatal("hunk too large (%ld lines) at line %ld: %s",
-                           p_end, p_input_line, buf);
-               while (p_end >= hunkmax)
-                       grow_hunkmax();
+               if (p_end >= hunkmax)
+                       grow_hunkmax(p_end);
                p_newfirst = min;
                p_repl_lines = max - min + 1;
                snprintf(buf, sizeof buf, "*** %ld,%ld\n", p_first,

Reply via email to