summaryrefslogtreecommitdiff
blob: 3f202b4db96b3e2d882fe7064a3d367ee7523202 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
fix from upstream cvs

----------------------------
revision 1.58
date: 2011-08-29 12:20:19 -0400;  author: psmith;  state: Exp;  lines: +7 -13;  commitid: MdH0jSxpuIy7mqxv;
Save strings we're expanding in case an embedded eval causes them
to be freed (if they're the value of a variable that's reset for example).
See Savannah patch #7534

Index: expand.c
===================================================================
RCS file: /sources/make/make/expand.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -p -r1.57 -r1.58
--- expand.c	7 May 2011 20:03:49 -0000	1.57
+++ expand.c	29 Aug 2011 16:20:19 -0000	1.58
@@ -197,7 +197,7 @@ variable_expand_string (char *line, cons
 {
   struct variable *v;
   const char *p, *p1;
-  char *abuf = NULL;
+  char *save;
   char *o;
   unsigned int line_offset;
 
@@ -212,16 +212,11 @@ variable_expand_string (char *line, cons
       return (variable_buffer);
     }
 
-  /* If we want a subset of the string, allocate a temporary buffer for it.
-     Most of the functions we use here don't work with length limits.  */
-  if (length > 0 && string[length] != '\0')
-    {
-      abuf = xmalloc(length+1);
-      memcpy(abuf, string, length);
-      abuf[length] = '\0';
-      string = abuf;
-    }
-  p = string;
+  /* We need a copy of STRING: due to eval, it's possible that it will get
+     freed as we process it (it might be the value of a variable that's reset
+     for example).  Also having a nil-terminated string is handy.  */
+  save = length < 0 ? xstrdup (string) : xstrndup (string, length);
+  p = save;
 
   while (1)
     {
@@ -411,8 +406,7 @@ variable_expand_string (char *line, cons
       ++p;
     }
 
-  if (abuf)
-    free (abuf);
+  free (save);
 
   variable_buffer_output (o, "", 1);
   return (variable_buffer + line_offset);