diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2014-09-09 01:01:41 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-12-17 15:24:37 +0200 |
commit | 3d7ee4dacf54e8000fd126d49881dd322f5926b9 (patch) | |
tree | 8788c6bdba66a8b47a21a36a3c10138a99eea3a7 /src | |
parent | bfc4869c9fda509e26a038d5c7485d800544bdf1 (diff) | |
download | grecs-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.c | 29 | ||||
-rw-r--r-- | src/wordsplit.h | 2 |
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; |