diff options
| author | Michael Matz <matz@suse.de> | 2017-07-09 04:30:36 +0200 |
|---|---|---|
| committer | Michael Matz <matz@suse.de> | 2017-07-09 04:38:56 +0200 |
| commit | d8fdd380f39aa413886c61c2e3624ba3b4582dc0 (patch) | |
| tree | 8f17b9c9e34ae77aafd5ce37fee68f50a6523dcb /tccpp.c | |
| parent | 16d3dbf2d087c92810d8d8354822a5345978e32c (diff) | |
| download | tinycc-d8fdd380f39aa413886c61c2e3624ba3b4582dc0.tar.gz tinycc-d8fdd380f39aa413886c61c2e3624ba3b4582dc0.tar.bz2 | |
tccpp: Fix corner case
See added testcase 19.c from a bug report. The problem is reading outside
the arguments buffers, even though we aren't allowed to. The single
can_read_stream variable is not enough, sometimes we need to be able
to pop into outer contexts but not into arbitrarily outside contexts.
The trick is to terminate argument tokens with a EOF (and not just with
0 that makes us pop contexts), and deal with that in the few places
we have to,
This enables some cleanups of the can_read_stream variable use.
Diffstat (limited to 'tccpp.c')
| -rw-r--r-- | tccpp.c | 14 |
1 files changed, 8 insertions, 6 deletions
@@ -2887,6 +2887,7 @@ static void next_nomacro_spc(void) } else { next_nomacro1(); } + //printf("token = %s\n", get_tok_str(tok, &tokc)); } ST_FUNC void next_nomacro(void) @@ -2932,7 +2933,7 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) cstr_ccat(&cstr, '\"'); st = s->d; spc = 0; - while (*st) { + while (*st >= 0) { TOK_GET(&t, &st, &cval); if (t != TOK_PLCHLDR && t != TOK_NOSUBST @@ -2972,7 +2973,7 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) /* special case for var arg macros : ## eats the ',' if empty VA_ARGS variable. */ if (t1 == TOK_PPJOIN && t0 == ',' && gnu_ext && s->type.t) { - if (*st == 0) { + if (*st <= 0) { /* suppress ',' '##' */ str.len -= 2; } else { @@ -2984,12 +2985,11 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) for(;;) { int t1; TOK_GET(&t1, &st, &cval); - if (!t1) + if (t1 <= 0) break; tok_str_add2(&str, t1, &cval); } } - } else { add_var: /* NOTE: the stream cannot be read when macro @@ -3031,7 +3031,7 @@ static int next_argstream(Sym **nested_list, int can_read_stream, TokenString *w while (is_space(t) || TOK_LINEFEED == t || TOK_PLCHLDR == t) tok_str_add(ws_str, t), t = *++p; } - if (t == 0 && can_read_stream) { + if (t == 0) { end_macro(); /* also, end of scope for nested defined symbol */ sa = *nested_list; @@ -3197,6 +3197,7 @@ static int macro_subst_tok( if (parlevel) expect(")"); str.len -= spc; + tok_str_add(&str, -1); tok_str_add(&str, 0); sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0); sa1->d = str.str; @@ -3366,7 +3367,7 @@ static void macro_subst( while (1) { TOK_GET(&t, &ptr, &cval); - if (t == 0) + if (t <= 0) break; if (t >= TOK_IDENT && 0 == nosubst) { @@ -3703,6 +3704,7 @@ static int pp_need_space(int a, int b) : '+' == a ? TOK_INC == b || '+' == b : '-' == a ? TOK_DEC == b || '-' == b : a >= TOK_IDENT ? b >= TOK_IDENT + : a == TOK_PPNUM ? b >= TOK_IDENT : 0; } |
