summaryrefslogtreecommitdiff
path: root/quote.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-06-04 11:26:59 -0700
committerH. Peter Anvin <hpa@zytor.com>2008-06-04 11:26:59 -0700
commit88c9e1f88cd1e67ad4fb2834f3cad6160d5a3fbb (patch)
tree01b0135d5f68e2e9cb80ccdf774d9f687c33fda2 /quote.c
parent0eebf799db452dc1980931bd2f15efde5ecdf28c (diff)
downloadnasm-88c9e1f88cd1e67ad4fb2834f3cad6160d5a3fbb.tar.gz
nasm-88c9e1f88cd1e67ad4fb2834f3cad6160d5a3fbb.tar.bz2
nasm-88c9e1f88cd1e67ad4fb2834f3cad6160d5a3fbb.zip
Fix memory management issues with expanded %include
Ownership of the filename string was a bit fuzzy, with the result that we were freeing it even though it was retained for use by __FILE__. Clean up a number of other memory management issues with the new quoting code, and change the stdscan implementation to one pass over the string.
Diffstat (limited to 'quote.c')
-rw-r--r--quote.c64
1 files changed, 40 insertions, 24 deletions
diff --git a/quote.c b/quote.c
index 6bfded3..5a04d36 100644
--- a/quote.c
+++ b/quote.c
@@ -183,12 +183,13 @@ static char *emit_utf8(char *q, int32_t v)
*
* In-place replacement is possible since the unquoted length is always
* shorter than or equal to the quoted length.
+ *
+ * *ep points to the final quote, or to the null if improperly quoted.
*/
-size_t nasm_unquote(char *str)
+size_t nasm_unquote(char *str, char **ep)
{
- size_t ln;
- char bq, eq;
- char *p, *q, *ep;
+ char bq;
+ char *p, *q;
char *escp = NULL;
char c;
enum unq_state {
@@ -201,33 +202,42 @@ size_t nasm_unquote(char *str)
int ndig = 0;
int32_t nval = 0;
- bq = str[0];
+ p = q = str;
+
+ bq = *p++;
if (!bq)
return 0;
- ln = strlen(str);
- eq = str[ln-1];
- if ((bq == '\'' || bq == '\"') && bq == eq) {
+ switch (bq) {
+ case '\'':
+ case '\"':
/* '...' or "..." string */
- memmove(str, str+1, ln-2);
- str[ln-2] = '\0';
- return ln-2;
- }
- if (bq == '`' || eq == '`') {
+ while ((c = *p) && c != bq) {
+ p++;
+ *q++ = c;
+ }
+ *q = '\0';
+ break;
+
+ case '`':
/* `...` string */
- q = str;
- p = str+1;
- ep = str+ln-1;
state = st_start;
- while (p < ep) {
- c = *p++;
+ while ((c = *p)) {
+ p++;
switch (state) {
case st_start:
- if (c == '\\')
+ switch (c) {
+ case '\\':
state = st_backslash;
- else
+ break;
+ case '`':
+ p--;
+ goto out;
+ default:
*q++ = c;
+ break;
+ }
break;
case st_backslash:
@@ -357,12 +367,18 @@ size_t nasm_unquote(char *str)
*q++ = escp[-1];
break;
}
- *q = '\0';
- return q-str;
+ out:
+ break;
+
+ default:
+ /* Not a quoted string, just return the input... */
+ p = q = strchr(str, '\0');
+ break;
}
- /* Otherwise, just return the input... */
- return ln;
+ if (ep)
+ *ep = p;
+ return q-str;
}
/*