From d8fdd380f39aa413886c61c2e3624ba3b4582dc0 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Sun, 9 Jul 2017 04:30:36 +0200 Subject: 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. --- tccpp.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'tccpp.c') diff --git a/tccpp.c b/tccpp.c index d70ddd6..7eb4501 100644 --- a/tccpp.c +++ b/tccpp.c @@ -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; } -- cgit v1.3.1