quote: move nasm_unquote_cstr() to quote.c; disallow control characters

Move nasm_unquote_cstr() to quote.c so we can use it in other places.
Provide nasm_unquote_pp() as a minimal wrapper for the preprocessor
itself.

Disallow non-ASCII characters except tab in the output.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin (Intel) 2018-06-25 20:59:42 -07:00
parent d558598ebe
commit b90d5c7761
3 changed files with 52 additions and 18 deletions

View File

@ -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));
/*

View File

@ -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;
}

View File

@ -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 */