summaryrefslogtreecommitdiff
path: root/expand.c
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2011-08-29 16:20:19 +0000
committerPaul Smith <psmith@gnu.org>2011-08-29 16:20:19 +0000
commite4d5d434247b720a3f78e1f7279168b5e6bf628e (patch)
treee3743fa9a60722d0b22116d8a170d376fa0b251e /expand.c
parentb06b8c64a29a5ba3a8daecd829fa2f98d42cb285 (diff)
downloadgunmake-e4d5d434247b720a3f78e1f7279168b5e6bf628e.tar.gz
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
Diffstat (limited to 'expand.c')
-rw-r--r--expand.c20
1 files changed, 7 insertions, 13 deletions
diff --git a/expand.c b/expand.c
index d1404b9..f5b6b99 100644
--- a/expand.c
+++ b/expand.c
@@ -197,7 +197,7 @@ variable_expand_string (char *line, const char *string, long length)
{
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, const char *string, long length)
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, const char *string, long length)
++p;
}
- if (abuf)
- free (abuf);
+ free (save);
variable_buffer_output (o, "", 1);
return (variable_buffer + line_offset);