Hi,

consider the following one-line Makefile:

all:;@echo $(if $(foo),,it) works

    It should print "it works" unless you set "foo" somewhere, but make
3.78-1 crashes with a segmentation fault, both on Solaris 2.6 and on Linux
2.2.14.

    I tracked the bug down to line 1158 in function.c (func_if). The
attached patch solves it.

    The other changes in that patch are cosmetical ones, and the variable
name changes in handle_function helped me to understand what's going on
there. If you don't like them, leave them out. :)

Hope that helps,

    - Stephan.
diff -rup make-3.78.1.orig/ChangeLog make-3.78.1/ChangeLog
--- make-3.78.1.orig/ChangeLog  Thu Sep 23 19:45:42 1999
+++ make-3.78.1/ChangeLog       Thu Feb 17 11:41:05 2000
@@ -1,3 +1,11 @@
+2000-02-17  Stephan Niemz  <[EMAIL PROTECTED]>
+
+       * function.c (func_if): Fixed pointer substraction which caused a
+       segmentation fault.
+       (func_basename_dir): Corrected indentation.
+       (handle_function): Some cleanup to make things clearer, at least
+       for me.
+
 1999-09-23  Paul D. Smith  <[EMAIL PROTECTED]>
 
        * Version 3.78.1 released.
diff -rup make-3.78.1.orig/function.c make-3.78.1/function.c
--- make-3.78.1.orig/function.c Wed Sep  1 21:00:00 1999
+++ make-3.78.1/function.c      Thu Feb 17 11:36:19 2000
@@ -563,7 +563,7 @@ func_basename_dir(o, argv, funcname)
            {
              if (IS_PATHSEP(*p))
                break;
-                   --p;
+             --p;
            }
 
          if (p >= p2 && (is_dir))
@@ -1125,7 +1125,7 @@ func_if (o, argv, funcname)
         while (*endp && **endp != '\0')
           ++endp;
 
-      expansion = expand_argument (*argv, *endp-1);
+      expansion = expand_argument (*argv, endp[-1]-1); /* equivalent: *(endp-1)-1 */
 
       o = variable_buffer_output (o, expansion, strlen (expansion));
       free (expansion);
@@ -1704,9 +1704,9 @@ handle_function (op, stringp)
   char openparen = (*stringp)[0];
   char closeparen = openparen == '(' ? ')' : '}';
   char *beg = *stringp + 1;
-  char *endref;
-  int count = 0;
+  int count;
   char *argbeg;
+  char *argend;
   register char *p;
   char **argv, **argvp;
   int nargs;
@@ -1719,18 +1719,17 @@ handle_function (op, stringp)
   /* We have found a call to a builtin function.  Find the end of the
      arguments, and do the function.  */
 
-  endref = beg + entry_p->len;
+  p = beg + entry_p->len;
 
   /* Space after function name isn't part of the args.  */
-  p = next_token (endref);
-  argbeg = p;
+  argbeg = p = next_token (p);
 
   /* Find the end of the function invocation, counting nested use of
      whichever kind of parens we use.  Since we're looking, count commas
      to get a rough estimate of how many arguments we might have.  The
      count might be high, but it'll never be low.  */
 
-  for (nargs=1; *p != '\0'; ++p)
+  for (count=0, nargs=1; *p != '\0'; ++p)
     if (*p == ',')
       ++nargs;
     else if (*p == openparen)
@@ -1738,6 +1737,7 @@ handle_function (op, stringp)
     else if (*p == closeparen && --count < 0)
       break;
 
+  argend = p;
   if (count >= 0)
     fatal (reading_file,
           _("unterminated call to function `%s': missing `%c'"),
@@ -1753,7 +1753,7 @@ handle_function (op, stringp)
   nargs = 1;
   while (entry_p->required_args < 0 || nargs < entry_p->required_args)
     {
-      char *next = find_next_argument (openparen, closeparen, *argvp, p);
+      char *next = find_next_argument (openparen, closeparen, *argvp, argend);
 
       if (!next)
        break;
@@ -1762,7 +1762,7 @@ handle_function (op, stringp)
       ++nargs;
     }
 
-  *(++argvp) = p+1;
+  *(++argvp) = argend+1;
   *(++argvp) = 0;
 
   /* If we should expand, do it.  */
@@ -1783,7 +1783,7 @@ handle_function (op, stringp)
     for (argvp=argv; *argvp != 0; ++argvp)
       free (*argvp);
 
-  *stringp = p;
+  *stringp = argend;
 
   return 1;
 }

PGP signature

Reply via email to