Skip to content

Commit

Permalink
Emit an error when repetition lower bound exceeds upper bound.
Browse files Browse the repository at this point in the history
Historically this was allowed and re2c swapped the bounds. However, it
most likely indicates an error in user code and there is only a single
occurrence in the tests (and the test in an artificial one), so although
the change is backwards incompatible there is low chance of breaking
real-world code.

This fixes second test case in the bug #394 "Stack overflow due to
recursion in src/dfa/dead_rules.cc" (the actual fix is to limit DFA size
but the test also has counted repetition with swapped bounds).
  • Loading branch information
skvadrik committed Jan 21, 2022
1 parent a3473fd commit 039c189
Show file tree
Hide file tree
Showing 9 changed files with 2,453 additions and 2,519 deletions.
4,798 changes: 2,400 additions & 2,398 deletions bootstrap/src/parse/lex.cc

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bootstrap/src/parse/lex.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Generated by re2c 2.2 on Fri Dec 24 21:36:58 2021 */
/* Generated by re2c 2.2 on Fri Jan 21 22:49:06 2022 */

#ifndef _RE2C_PARSE_LEX_
#define _RE2C_PARSE_LEX_
Expand Down
1 change: 1 addition & 0 deletions src/debug/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ template<typename ctx_t>

#include <assert.h>
#include "src/util/c99_stdint.h"
#include <stddef.h>
#include <map>
#include <set>
#include <vector>
Expand Down
2 changes: 2 additions & 0 deletions src/parse/ast.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <limits>

#include "src/debug/debug.h"
#include "src/parse/ast.h"
#include "src/util/free_list.h"

Expand Down Expand Up @@ -83,6 +84,7 @@ const AST *ast_cat(const AST *a1, const AST *a2)

const AST *ast_iter(const AST *a, uint32_t n, uint32_t m)
{
DASSERT(n <= m);
AST *ast = new AST(a->loc, AST::ITER);
ast->iter.ast = a;
ast->iter.min = n;
Expand Down
8 changes: 5 additions & 3 deletions src/parse/lex.re
Original file line number Diff line number Diff line change
Expand Up @@ -461,13 +461,15 @@ scan:
}
"{" [0-9]+ @p "," [0-9]+ "}" {
if (!s_to_u32_unsafe (tok + 1, p, yylval.bounds.min)) {
if (!s_to_u32_unsafe(tok + 1, p, yylval.bounds.min)) {
msg.error(tok_loc(), "repetition lower bound overflow");
exit(1);
}
if (!s_to_u32_unsafe (p + 1, cur - 1, yylval.bounds.max)) {
} else if (!s_to_u32_unsafe(p + 1, cur - 1, yylval.bounds.max)) {
msg.error(tok_loc(), "repetition upper bound overflow");
exit(1);
} else if (yylval.bounds.min > yylval.bounds.max) {
msg.error(tok_loc(), "repetition lower bound exceeds upper bound");
exit(1);
}
return TOKEN_CLOSESIZE;
}
Expand Down
1 change: 1 addition & 0 deletions test/messages/repetition_swapped_bounds.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
messages/repetition_swapped_bounds.re:5:7: error: repetition lower bound exceeds upper bound
6 changes: 6 additions & 0 deletions test/messages/repetition_swapped_bounds.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// re2c $INPUT

// error: lower bound exceeds upper bound
/*!re2c
[a]{3,2} {}
*/
146 changes: 37 additions & 109 deletions test/repeater2.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,33 +208,29 @@
#line 209 "repeater2.c"
{
YYCTYPE yych;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
if ((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy31;
default: goto yy30;
}
yy30:
yy31:
++YYCURSOR;
#line 39 "repeater2.re"
{}
#line 223 "repeater2.c"
}
#line 40 "repeater2.re"



#line 229 "repeater2.c"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
yych = *YYCURSOR;
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy32;
default: goto yy30;
}
yy32:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy34;
default: goto yy33;
}
yy33:
#line 39 "repeater2.re"
{}
#line 234 "repeater2.c"
yy34:
yych = *++YYCURSOR;
switch (yych) {
Expand All @@ -244,118 +240,58 @@
yy35:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy37;
default: goto yy36;
case 'a': goto yy36;
default: goto yy33;
}
yy36:
#line 43 "repeater2.re"
{}
#line 254 "repeater2.c"
yy37:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy38;
default: goto yy36;
}
yy38:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy39;
default: goto yy36;
}
yy39:
++YYCURSOR;
goto yy36;
}
#line 44 "repeater2.re"



#line 275 "repeater2.c"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy42;
default: goto yy41;
}
yy41:
yy42:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy43;
default: goto yy41;
}
yy43:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy44;
default: goto yy41;
}
yy44:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy45;
default: goto yy41;
}
yy45:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy46;
default: goto yy41;
}
yy46:
++YYCURSOR;
#line 47 "repeater2.re"
{}
#line 313 "repeater2.c"
goto yy33;
}
#line 48 "repeater2.re"
#line 40 "repeater2.re"



#line 319 "repeater2.c"
#line 255 "repeater2.c"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy49;
default: goto yy48;
case 'a': goto yy39;
default: goto yy38;
}
yy48:
yy49:
yy38:
yy39:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy50;
default: goto yy48;
case 'a': goto yy40;
default: goto yy38;
}
yy50:
yy40:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy51;
default: goto yy48;
case 'a': goto yy41;
default: goto yy38;
}
yy51:
yy41:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy52;
default: goto yy48;
case 'a': goto yy42;
default: goto yy38;
}
yy52:
yy42:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy53;
default: goto yy48;
case 'a': goto yy43;
default: goto yy38;
}
yy53:
yy43:
++YYCURSOR;
#line 51 "repeater2.re"
#line 43 "repeater2.re"
{}
#line 357 "repeater2.c"
#line 293 "repeater2.c"
}
#line 52 "repeater2.re"
#line 44 "repeater2.re"

repeater2.re:6:0: warning: control flow is undefined for strings that match '[\x0-\x60\x62-\xFF]', use default rule '*' [-Wundefined-control-flow]
repeater2.re:10:0: warning: control flow is undefined for strings that match
Expand All @@ -372,19 +308,11 @@ repeater2.re:22:0: warning: control flow is undefined for strings that match
, use default rule '*' [-Wundefined-control-flow]
repeater2.re:31:10: warning: rule matches empty string [-Wmatch-empty-string]
repeater2.re:34:0: warning: control flow is undefined for strings that match '[\x0-\x60\x62-\xFF]', use default rule '*' [-Wundefined-control-flow]
repeater2.re:38:0: warning: control flow is undefined for strings that match '[\x0-\x60\x62-\xFF]', use default rule '*' [-Wundefined-control-flow]
repeater2.re:42:0: warning: control flow is undefined for strings that match
'[\x0-\x60\x62-\xFF]'
'\x61 [\x0-\x60\x62-\xFF]'
, use default rule '*' [-Wundefined-control-flow]
repeater2.re:46:0: warning: control flow is undefined for strings that match
repeater2.re:38:0: warning: control flow is undefined for strings that match
'[\x0-\x60\x62-\xFF]'
'\x61 [\x0-\x60\x62-\xFF]'
'\x61 \x61 [\x0-\x60\x62-\xFF]'
'\x61 \x61 \x61 [\x0-\x60\x62-\xFF]'
'\x61 \x61 \x61 \x61 [\x0-\x60\x62-\xFF]'
, use default rule '*' [-Wundefined-control-flow]
repeater2.re:50:0: warning: control flow is undefined for strings that match
repeater2.re:42:0: warning: control flow is undefined for strings that match
'[\x0-\x60\x62-\xFF]'
'\x61 [\x0-\x60\x62-\xFF]'
'\x61 \x61 [\x0-\x60\x62-\xFF]'
Expand Down
8 changes: 0 additions & 8 deletions test/repeater2.re
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@
"a"{0,1} {}
*/

/*!re2c
"a"{1,0} {}
*/

/*!re2c
"a"{1,1} {}
*/
Expand All @@ -43,10 +39,6 @@
"a"{2,5} {}
*/

/*!re2c
"a"{5,2} {}
*/

/*!re2c
"a"{5,5} {}
*/

0 comments on commit 039c189

Please sign in to comment.