diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c index 0fb9db0f..1f16a733 100644 --- a/data/skeletons/yacc.c +++ b/data/skeletons/yacc.c @@ -1184,15 +1184,12 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, */ if (yytoken != YYEMPTY) { - int yyn = yypact[+*yyssp]; - YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - yysize = yysize0;]b4_lac_if([[ + int yyn = yypact[+*yyssp];]b4_lac_if([[ YYDPRINTF ((stderr, "Constructing syntax error message\n"));]])[ yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) {]b4_lac_if([[ int yyx; - for (yyx = 0; yyx < YYNTOKENS; ++yyx) if (yyx != YYTERROR && yyx != YYUNDEFTOK) { @@ -1212,7 +1209,6 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; - for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR && !yytable_value_is_error (yytable[yyx + yyn])) @@ -1220,18 +1216,9 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; - yysize = yysize0; break; } yyarg[yycount++] = yytname[yyx]; - { - YYPTRDIFF_T yysize1 - = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) - yysize = yysize1; - else - return 2; - } } }]b4_lac_if([[ # if ]b4_api_PREFIX[DEBUG @@ -1256,14 +1243,19 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, # undef YYCASE_ } + /* Compute error message size. Don't count the "%s"s, but reserve + room for the terminator. */ + yysize = (yystrlen (yyformat) - 2 * yycount) + 1; { - /* Don't count the "%s"s in the final size, but reserve room for - the terminator. */ - YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1; - if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) - yysize = yysize1; - else - return 2; + int yyi; + for (yyi = 0; yyi < yycount; ++yyi) + { + YYPTRDIFF_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yyarg[yyi]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } } if (*yymsg_alloc < yysize) diff --git a/tests/regression.at b/tests/regression.at index a1a85e1f..bbb5634a 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -1219,7 +1219,7 @@ AT_DATA_GRAMMAR([input.y], %% -start: syntax_error1 check syntax_error2 ; +start: syntax_error1 check syntax_error2 check syntax_error3; // Induce a syntax error message whose total length causes yymsg in // yyparse to be reallocated to size YYSTACK_ALLOC_MAXIMUM, which @@ -1251,13 +1251,26 @@ check: } ; -// Now overflow. +// We used to overflow memory here because the first four "expected" +// tokens plus rest of the error message is greater that 255 bytes. +// However there are *five* expected tokens here, so anyway we will +// *not* display these tokens. So the message fits, no overflow. syntax_error2: "123456789112345678921234567893123456789412345678951234567896123A" | "123456789112345678921234567893123456789412345678951234567896123B" | "123456789112345678921234567893123456789412345678951234567896123C" | "123456789112345678921234567893123456789412345678951234567896123D" | "123456789112345678921234567893123456789412345678951234567896123E" +| error 'd' 'e' 'f' +; + + +// Now overflow. +syntax_error3: + "123456789112345678921234567893123456789412345678951234567896123A" +| "123456789112345678921234567893123456789412345678951234567896123B" +| "123456789112345678921234567893123456789412345678951234567896123C" +| "123456789112345678921234567893123456789412345678951234567896123D" ; %% @@ -1265,7 +1278,7 @@ syntax_error2: ]AT_YYERROR_DEFINE[ /* Induce two syntax error messages (which requires full error recovery by shifting 3 tokens). */ -]AT_YYLEX_DEFINE(["abc"])[ +]AT_YYLEX_DEFINE(["abcdef"])[ int main (void) { @@ -1288,6 +1301,7 @@ AT_COMPILE([[input]]) AT_PARSER_CHECK([[input]], [[2]], [], [[syntax error, unexpected 'a', expecting 123456789112345678921234567893123456789412345678951234567896123A or 123456789112345678921234567893123456789412345678951234567896123B or 123456789112345678921234567893123456789412345678951234567896123C +syntax error, unexpected 'd' syntax error memory exhausted ]])