diff --git a/asm/preproc.c b/asm/preproc.c index 8e1e6369..11d521fb 100644 --- a/asm/preproc.c +++ b/asm/preproc.c @@ -479,20 +479,11 @@ static Token *delete_Token(Token * t); #define tok_isnt_(x,v) ((x) && ((x)->type!=TOK_OTHER || strcmp((x)->text,(v)))) /* - * nasm_unquote with error if the string contains NUL characters. - * If the string contains NUL characters, issue an error and return - * the C len, i.e. truncate at the NUL. + * Wrapper for nasm_unquote_cstr() */ -static size_t nasm_unquote_cstr(char *qstr, enum preproc_token directive) +static void nasm_unquote_pp(char *qstr, enum preproc_token directive) { - size_t len = nasm_unquote(qstr, NULL); - size_t clen = strlen(qstr); - - if (len != clen) - nasm_error(ERR_NONFATAL, "NUL character in `%s' directive", - pp_directives[directive]); - - return clen; + nasm_unquote_cstr(qstr, pp_directives[directive]); } /* @@ -1819,7 +1810,7 @@ static bool if_condition(Token * tline, enum preproc_token ct) if (tline->type == TOK_PREPROC_ID) p += 2; /* Skip leading %! */ if (*p == '\'' || *p == '\"' || *p == '`') - nasm_unquote_cstr(p, ct); + nasm_unquote_pp(p, ct); if (getenv(p)) j = true; tline = tline->next; @@ -2600,7 +2591,7 @@ static int do_directive(Token *tline, char **output) "trailing garbage after `%%depend' ignored"); p = t->text; if (t->type != TOK_INTERNAL_STRING) - nasm_unquote_cstr(p, i); + nasm_unquote_pp(p, i); nasm_add_string_to_strlist(dephead, p); free_tlist(origline); return DIRECTIVE_FOUND; @@ -2620,7 +2611,7 @@ static int do_directive(Token *tline, char **output) "trailing garbage after `%%include' ignored"); p = t->text; if (t->type != TOK_INTERNAL_STRING) - nasm_unquote_cstr(p, i); + nasm_unquote_pp(p, i); inc = nasm_malloc(sizeof(Include)); inc->next = istk; inc->conds = NULL; @@ -2662,7 +2653,7 @@ static int do_directive(Token *tline, char **output) nasm_error(ERR_WARNING|ERR_PASS1, "trailing garbage after `%%use' ignored"); if (tline->type == TOK_STRING) - nasm_unquote_cstr(tline->text, i); + nasm_unquote_pp(tline->text, i); use_pkg = nasm_stdmac_find_package(tline->text); if (!use_pkg) nasm_error(ERR_NONFATAL, "unknown `%%use' package: %s", tline->text); @@ -3321,7 +3312,7 @@ issue_error: * are stored with the token stream reversed, so we have to * reverse the output of tokenize(). */ - nasm_unquote_cstr(t->text, i); + nasm_unquote_pp(t->text, i); macro_start = reverse_tokens(tokenize(t->text)); /* diff --git a/asm/quote.c b/asm/quote.c index 75a93726..8e64dc4a 100644 --- a/asm/quote.c +++ b/asm/quote.c @@ -41,6 +41,7 @@ #include "nasmlib.h" #include "quote.h" +#include "error.h" char *nasm_quote(const char *str, size_t len) { @@ -255,7 +256,6 @@ size_t nasm_unquote(char *str, char **ep) p++; *q++ = c; } - *q = '\0'; break; case '`': @@ -417,6 +417,8 @@ size_t nasm_unquote(char *str, char **ep) if (ep) *ep = p; + + *q = '\0'; return q-str; } @@ -477,3 +479,37 @@ char *nasm_skip_string(char *str) return str; /* Not a string... */ } } + +/* + * nasm_unquote with error if the string is malformed or contains + * control characters. + * + * Returns a pointer to the first input character after the string; + * qstr will be a valid C string on return. + */ +char *nasm_unquote_cstr(char *qstr, const char *where) +{ + char *ep; + size_t len = nasm_unquote(qstr, &ep); + size_t clen; + + if (!*ep) + nasm_error(ERR_NONFATAL, "invalid quoted string"); + else + ep++; /* Skip closing quote */ + + for (clen = 0; qstr[clen] >= ' ' || qstr[clen] == '\t'; clen++) + ; + + qstr[clen] = '\0'; /* Truncate string if necessary */ + + if (len != clen) { + if (where) { + nasm_error(ERR_NONFATAL, "control character in `%s' directive", where); + } else { + nasm_error(ERR_NONFATAL, "invalid control character in string"); + } + } + + return ep; +} diff --git a/asm/quote.h b/asm/quote.h index 2d8ce87b..cfa7cb99 100644 --- a/asm/quote.h +++ b/asm/quote.h @@ -36,9 +36,16 @@ #include "compiler.h" +/* Is it the leading character in a quoted string? */ +static inline bool isquote(char c) +{ + return c == '\'' || c == '\"' || c == '`'; +} + char *nasm_quote(const char *str, size_t len); size_t nasm_unquote(char *str, char **endptr); char *nasm_skip_string(char *str); +char *nasm_unquote_cstr(char *str, const char *where); #endif /* NASM_QUOTE_H */