aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2014-09-09 01:01:41 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2015-12-17 15:24:37 +0200
commit3d7ee4dacf54e8000fd126d49881dd322f5926b9 (patch)
tree8788c6bdba66a8b47a21a36a3c10138a99eea3a7 /src
parentbfc4869c9fda509e26a038d5c7485d800544bdf1 (diff)
downloadgrecs-3d7ee4dacf54e8000fd126d49881dd322f5926b9.tar.gz
grecs-3d7ee4dacf54e8000fd126d49881dd322f5926b9.tar.bz2
wordsplit: ws_getvar allocates memory.
* src/wordsplit.c (ISVARBEG,ISVARCHR): New macros. (expvar): ws_getvar allocates memory. * src/wordsplit.h (wordsplit)<ws_getvar>: Remove const from the return value: the function should allocate memory.
Diffstat (limited to 'src')
-rw-r--r--src/wordsplit.c29
-rw-r--r--src/wordsplit.h2
2 files changed, 20 insertions, 11 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c
index b694b64..b5a757f 100644
--- a/src/wordsplit.c
+++ b/src/wordsplit.c
@@ -45,12 +45,15 @@
#define ISALPHA(c) (ISUPPER(c) || ISLOWER(c))
#define ISDIGIT(c) ('0' <= ((unsigned) (c)) && ((unsigned) (c)) <= '9')
#define ISXDIGIT(c) (strchr("abcdefABCDEF", c)!=NULL)
#define ISALNUM(c) (ISALPHA(c) || ISDIGIT(c))
#define ISPRINT(c) (' ' <= ((unsigned) (c)) && ((unsigned) (c)) <= 127)
+#define ISVARBEG(c) (ISALPHA(c) || c == '_')
+#define ISVARCHR(c) (ISALNUM(c) || c == '_')
+
#define ALLOC_INIT 128
#define ALLOC_INCR 128
static void
_wsplt_alloc_die (struct wordsplit *wsp)
{
@@ -700,21 +703,22 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len)
static int
expvar (struct wordsplit *wsp, const char *str, size_t len,
struct wordsplit_node **ptail, const char **pend, int flg)
{
size_t i = 0;
- const char *value;
+ const char *defstr = NULL;
+ char *value;
const char *vptr;
struct wordsplit_node *newnode;
const char *start = str - 1;
- if (ISALPHA (str[0]) || str[0] == '_')
+ if (ISVARBEG (str[0]))
{
for (i = 1; i < len; i++)
- if (!(ISALNUM (str[i]) || str[i] == '_'))
+ if (!ISVARCHR (str[i]))
break;
*pend = str + i - 1;
}
else if (str[0] == '{')
{
str++;
@@ -786,45 +790,50 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
{
if (wsp->ws_flags & WRDSF_WARNUNDEF)
wsp->ws_error (_("warning: undefined variable `%.*s'"), (int) i, str);
if (wsp->ws_flags & WRDSF_KEEPUNDEF)
value = NULL;
else
- value = "";
+ {
+ value = strdup ("");
+ if (!value)
+ return _wsplt_nomem (wsp);
+ }
}
/* FIXME: handle defstr */
if (value)
{
if (flg & _WSNF_QUOTE)
{
if (wsnode_new (wsp, &newnode))
return 1;
wsnode_insert (wsp, newnode, *ptail, 0);
*ptail = newnode;
newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
- newnode->v.word = strdup (value);
- if (!newnode->v.word)
- return _wsplt_nomem (wsp);
+ newnode->v.word = value;
}
else if (*value == 0)
{
+ free (value);
/* Empty string is a special case */
if (wsnode_new (wsp, &newnode))
return 1;
wsnode_insert (wsp, newnode, *ptail, 0);
*ptail = newnode;
newnode->flags = _WSNF_NULL;
}
else
{
struct wordsplit ws;
- int i;
+ int i, rc;
ws.ws_delim = wsp->ws_delim;
- if (wordsplit (value, &ws,
- WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM | WRDSF_WS))
+ rc = wordsplit (value, &ws,
+ WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM | WRDSF_WS);
+ free (value);
+ if (rc)
{
wordsplit_free (&ws);
return 1;
}
for (i = 0; i < ws.ws_wordc; i++)
{
diff --git a/src/wordsplit.h b/src/wordsplit.h
index 35e125a..4e2b117 100644
--- a/src/wordsplit.h
+++ b/src/wordsplit.h
@@ -33,13 +33,13 @@ struct wordsplit
void (*ws_error) (const char *, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
void (*ws_debug) (const char *, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
const char **ws_env;
- const char *(*ws_getvar) (const char *, size_t, void *);
+ char *(*ws_getvar) (const char *, size_t, void *);
void *ws_closure;
const char *ws_input;
size_t ws_len;
size_t ws_endp;
int ws_errno;

Return to:

Send suggestions and report system problems to the System administrator.