]> git.ipfire.org Git - thirdparty/make.git/commitdiff
Fix bug #2238: the read.c:eval() function was not entirely reentrant.
authorPaul Smith <psmith@gnu.org>
Thu, 30 Jan 2003 07:49:17 +0000 (07:49 +0000)
committerPaul Smith <psmith@gnu.org>
Thu, 30 Jan 2003 07:49:17 +0000 (07:49 +0000)
Apply patch #1022: fix a memory corruption on very long target-specific
variable definition lines.

ChangeLog
read.c
tests/ChangeLog
tests/scripts/features/targetvars
tests/scripts/functions/call
tests/scripts/functions/eval

index 8f7aef2946b1d5f0e47a023821e5e20b72698c19..2b3ebc7e979f5653e8be5b67cd886a7d41ae9d22 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2003-01-30  Paul D. Smith  <psmith@gnu.org>
 
+       * read.c (eval): eval() was not fully reentrant, because the
+       collapsed buffer was static.  Change it to be an automatic
+       variable so that eval() can be invoked recursively.
+       Fixes bug # 2238.
+       (eval): Apply patch # 1022: fix memory reference error on long
+       target-specific variable lines.
+       Patch provided by Steve Brown <Steve.Brown@macquarie.com>.
+
        * function.c (check_numeric): Combine the is_numeric() function
        into this function, since it's only called from one place.
        Constify this function.  Have it print the incorrect string in the
diff --git a/read.c b/read.c
index a0bf5caa834e340e6c498ef159cd80bf855112f1..47d727b5680e0339af763ba877ae40d05375bc2d 100644 (file)
--- a/read.c
+++ b/read.c
@@ -452,8 +452,8 @@ eval_buffer (char *buffer)
 static int
 eval (struct ebuffer *ebuf, int set_default)
 {
-  static char *collapsed = 0;
-  static unsigned int collapsed_length = 0;
+  char *collapsed = 0;
+  unsigned int collapsed_length = 0;
   unsigned int commands_len = 200;
   char *commands;
   unsigned int commands_idx = 0;
@@ -566,9 +566,7 @@ eval (struct ebuffer *ebuf, int set_default)
       if (collapsed_length < linelen+1)
        {
          collapsed_length = linelen+1;
-         if (collapsed != 0)
-           free (collapsed);
-         collapsed = (char *) xmalloc (collapsed_length);
+         collapsed = (char *) xrealloc (collapsed, collapsed_length);
        }
       strcpy (collapsed, line);
       /* Collapse continuation lines.  */
@@ -1034,11 +1032,13 @@ eval (struct ebuffer *ebuf, int set_default)
            of the unparsed section of p2, for later.  */
         if (*lb_next != '\0')
           {
-            unsigned int l = p2 - variable_buffer;
+            unsigned int l = p - variable_buffer;
+            unsigned int l2 = p2 - variable_buffer;
             plen = strlen (p2);
             (void) variable_buffer_output (p2+plen,
                                            lb_next, strlen (lb_next)+1);
-            p2 = variable_buffer + l;
+            p = variable_buffer + l;
+            p2 = variable_buffer + l2;
           }
 
         /* See if it's an "override" or "export" keyword; if so see if what
@@ -1069,9 +1069,11 @@ eval (struct ebuffer *ebuf, int set_default)
                after it.  */
             if (semip)
               {
+                unsigned int l = p - variable_buffer;
                 *(--semip) = ';';
                 variable_buffer_output (p2 + strlen (p2),
                                         semip, strlen (semip)+1);
+                p = variable_buffer + l;
               }
             record_target_var (filenames, p, two_colon, v_origin, exported,
                                fstart);
@@ -1234,6 +1236,8 @@ eval (struct ebuffer *ebuf, int set_default)
   /* At eof, record the last rule.  */
   record_waiting_files ();
 
+  if (collapsed)
+    free ((char *) collapsed);
   free ((char *) commands);
 
   return 1;
index fe096107146dd831f66489a9228c6a9f94bdee41..39bf62fcfc5b746f8308913326955e999f83e670 100644 (file)
@@ -1,5 +1,12 @@
 2003-01-30  Paul D. Smith  <psmith@gnu.org>
 
+       * scripts/features/targetvars: Test very long target-specific
+       variable definition lines (longer than the default make buffer
+       length).  Tests patch # 1022.
+
+       * scripts/functions/eval: Test very recursive $(eval ...) calls
+       with simple variable expansion (bug #2238).
+
        * scripts/functions/word: Test error handling for word and
        wordlist functions (bug #2407).
 
index 2375f719782603bcf7d6d62c4902bb45f5c12c87..3989340c1c30cff40f719dbab78c6d0ab32cc6ea 100644 (file)
@@ -248,4 +248,23 @@ $answer = "ok ok foo pat\nok ok foo pat\n";
 &compare_output($answer, &get_logfile(1));
 
 
+# Test #16
+# Test target-specific variables with very long command line
+# (> make default buffer length)
+
+$makefile7 = &get_tmpfile;
+
+open(MAKEFILE, "> $makefile7");
+print MAKEFILE <<'EOF';
+base_metals_fmd_reports.sun5 base_metals_fmd_reports CreateRealPositions        CreateMarginFunds deals_changed_since : BUILD_OBJ=$(shell if [ -f               "build_information.generate" ]; then echo "$(OBJ_DIR)/build_information.o"; else echo "no build information"; fi  )
+
+deals_changed_since: ; @echo $(BUILD_OBJ)
+
+EOF
+close(MAKEFILE);
+
+&run_make_with_options("$makefile7", '', &get_logfile);
+$answer = "no build information\n";
+&compare_output($answer, &get_logfile(1));
+
 1;
index efee4769b4d7ff28c176ee69225998ceab325878..f3c5470851c6eeaff930b5c8affc9bc6788d4071 100644 (file)
@@ -66,7 +66,6 @@ close(MAKEFILE);
 
 &run_make_with_options($makefile, "", &get_logfile);
 $answer = "foo bar\ndefault file file\nb d f\n\n\nb\nbar foo baz\nfoo bar baz blarp quux \n";
-
 &compare_output($answer, &get_logfile(1));
 
 
@@ -94,10 +93,7 @@ EOF
 close(MAKEFILE);
 
 &run_make_with_options($makefile2, "", &get_logfile);
-
-# Create the answer to what should be produced by this Makefile
 $answer = "1 2 3 4 5 6 7 8 9\n1 2 3 4 5\n1 2 3\n1 2 3\n";
-
 &compare_output($answer,&get_logfile(1));
 
 1;
index 174767d772c740263ca9a5dd31128002ed5325bc..cfb27b22b55b37cefb4f22f3a1c9903ba1feb6bb 100644 (file)
@@ -88,4 +88,25 @@ $answer = "it\n";
 $answer = "it\nworked\n";
 &compare_output($answer,&get_logfile(1));
 
+
+# TEST very recursive invocation of eval
+
+$makefile3 = &get_tmpfile;
+
+open(MAKEFILE,"> $makefile3");
+
+print MAKEFILE <<'EOF';
+..9 := 0 1 2 3 4 5 6 7 8 9
+rev=$(eval res:=)$(foreach word,$1,$(eval res:=${word} ${res}))${res}
+a:=$(call rev,${..9})
+all: ; @echo '[$(a)]'
+
+EOF
+
+close(MAKEFILE);
+
+&run_make_with_options($makefile3, "", &get_logfile);
+$answer = "[         9 8 7 6 5 4 3 2 1 0 ]\n";
+&compare_output($answer,&get_logfile(1));
+
 1;