summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@gmail.com>2010-04-11 13:00:58 +0400
committerCyrill Gorcunov <gorcunov@gmail.com>2010-04-11 13:00:58 +0400
commit370e5a94c96e7d1198601352949548df27c858f1 (patch)
tree43241bf86b5698b7e0b206d7d2b8ce8df67c728d
parent6702d93c10c003cf9472d33a67185db0a5a8c593 (diff)
downloadnasm-370e5a94c96e7d1198601352949548df27c858f1.tar.gz
nasm-370e5a94c96e7d1198601352949548df27c858f1.tar.bz2
nasm-370e5a94c96e7d1198601352949548df27c858f1.zip
nasmlib.c: Make nasm_opt_val robust
nasm_opt_val should be able handle various text stream passed, including tainted ones. Make it so. Also it fixes the case when Elf section has multiple attributes such as "progbits align=16" and friends (introduced by commit bb0745f). The former just ignore any other options/values except first one. Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
-rw-r--r--nasmlib.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/nasmlib.c b/nasmlib.c
index 812f640..2ae8619 100644
--- a/nasmlib.c
+++ b/nasmlib.c
@@ -726,29 +726,48 @@ char *nasm_get_word(char *p, char **tail)
}
/*
- * extract option and value from a string formatted as "opt = val"
- * and return pointer to the next string or NULL on empty string
- * passed or if nothing left for handling
+ * Extract "opt=val" values from the stream and
+ * returns "opt"
+ *
+ * Exceptions:
+ * 1) If "=val" passed the NULL returned though
+ * you may continue handling the tail via "next"
+ * 2) If "=" passed the NULL is returned and "val"
+ * is set to NULL as well
*/
-char *nasm_opt_val(char *p, char **opt, char **val)
+char *nasm_opt_val(char *p, char **val, char **next)
{
- char *q, *next;
+ char *q, *opt, *nxt;
+
+ opt = *val = *next = NULL;
- p = nasm_skip_spaces(p);
- if (!p || (p && !*p))
+ p = nasm_get_word(p, &nxt);
+ if (!p)
return NULL;
q = strchr(p, '=');
if (q) {
- *q++ = '\0';
- next = nasm_skip_spaces(nasm_skip_word(nasm_skip_spaces(q)));
- } else
- next = nasm_skip_spaces(nasm_skip_word(nasm_skip_spaces(p)));
-
- *opt = nasm_trim_spaces(p);
- *val = nasm_trim_spaces(q);
+ if (q == p)
+ p = NULL;
+ *q++='\0';
+ if (*q) {
+ *val = q;
+ } else {
+ q = nasm_get_word(q + 1, &nxt);
+ if (q)
+ *val = q;
+ }
+ } else {
+ q = nasm_skip_spaces(nxt);
+ if (q && *q == '=') {
+ q = nasm_get_word(q + 1, &nxt);
+ if (q)
+ *val = q;
+ }
+ }
- return next;
+ *next = nxt;
+ return p;
}
/*