]> granicus.if.org Git - re2c/commitdiff
Use custom function instead of 'atoi' to read 32-bit integers.
authorUlya Trofimovich <skvadrik@gmail.com>
Sun, 16 Aug 2015 11:08:21 +0000 (12:08 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Sun, 16 Aug 2015 11:08:21 +0000 (12:08 +0100)
Using 'atoi' displeased me for several reasons:
    - 'atoi' doesn't check for overflow
    - by the time 'atoi' was called, re2c has already parsed input
      string and knows that it is well-formed, no need to do it twice
    - atoi returns 'int', custom function allows to refine types and
      avoid casts between signed/unsigned values or [-Wsign-conversion]
      warnings

Added test for new conversion functions.

re2c/Makefile.am
re2c/bootstrap/src/parse/scanner_lex.cc
re2c/src/parse/extop.h
re2c/src/parse/parser.ypp
re2c/src/parse/scanner_lex.re
re2c/src/test/s_to_n32_unsafe/test.cc [new file with mode: 0644]
re2c/src/util/s_to_n32_unsafe.cc [new file with mode: 0644]
re2c/src/util/s_to_n32_unsafe.h [new file with mode: 0644]

index b8e77ef3e6b477a63ea84711bf749c2cb45c999b..97769286e118fe31da54b58cbc330a0e2c6cbd7e 100644 (file)
@@ -63,6 +63,7 @@ SRC_HDR = \
        src/util/free_list.h \
        src/util/local_increment.h \
        src/util/range.h \
+       src/util/s_to_n32_unsafe.h \
        src/util/smart_ptr.h \
        src/util/static_assert.h \
        src/util/substr.h \
@@ -113,6 +114,7 @@ SRC = \
        src/parse/input.cc \
        src/parse/scanner.cc \
        src/parse/unescape.cc \
+       src/util/s_to_n32_unsafe.cc \
        src/util/range.cc
 re2c_SOURCES = \
        $(SRC_HDR) \
@@ -250,6 +252,13 @@ testrange_SOURCES = \
        src/util/range.h \
        src/util/static_assert.h
 
-check_PROGRAMS = $(TST_RANGE)
+TST_S_TO_N32_UNSAFE = testston32unsafe
+testston32unsafe_SOURCES = \
+       src/test/s_to_n32_unsafe/test.cc \
+       src/util/s_to_n32_unsafe.cc
+
+check_PROGRAMS = \
+       $(TST_RANGE) \
+       $(TST_S_TO_N32_UNSAFE)
 
 TESTS = $(TST_SUITE) $(check_PROGRAMS)
index 2358193c36d55770093086458b4a589100670092..612d6597c03a82478a47344f67600e1d6b79bb29 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.14.3 on Fri Aug 14 12:58:19 2015 */
+/* Generated by re2c 0.14.3 on Sun Aug 16 11:25:05 2015 */
 #line 1 "../src/parse/scanner_lex.re"
 #include <stdlib.h>
 #include <string.h>
 #include "src/parse/parser.h"
 #include "src/parse/scanner.h"
 #include "y.tab.h"
+#include "src/util/s_to_n32_unsafe.h"
 
 extern YYSTYPE yylval;
 
-#ifndef MAX
-#define MAX(a,b) (((a)>(b))?(a):(b))
-#endif
-
 #define        YYCTYPE         unsigned char
 #define        YYCURSOR        cur
 #define        YYLIMIT         lim
@@ -31,10 +28,10 @@ namespace re2c
 // source code is in ASCII: pointers have type 'char *'
 // but re2c makes an implicit assumption that YYCTYPE is unsigned
 // when it generates comparisons
-#line 34 "../src/parse/scanner_lex.re"
+#line 31 "../src/parse/scanner_lex.re"
 
 
-#line 56 "../src/parse/scanner_lex.re"
+#line 53 "../src/parse/scanner_lex.re"
 
 
 Scanner::ParseMode Scanner::echo()
@@ -50,7 +47,7 @@ Scanner::ParseMode Scanner::echo()
        tok = cur;
 echo:
 
-#line 54 "src/parse/scanner_lex.cc"
+#line 51 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        unsigned int yyaccept = 0;
@@ -109,7 +106,7 @@ echo:
                }
        }
        ++YYCURSOR;
-#line 199 "../src/parse/scanner_lex.re"
+#line 196 "../src/parse/scanner_lex.re"
        {
                                        if (!(ignore_eoc || DFlag || flag_skeleton))
                                        {
@@ -121,15 +118,15 @@ echo:
                                                return Stop;
                                        }
                                }
-#line 125 "src/parse/scanner_lex.cc"
+#line 122 "src/parse/scanner_lex.cc"
 yy4:
        ++YYCURSOR;
 yy5:
-#line 210 "../src/parse/scanner_lex.re"
+#line 207 "../src/parse/scanner_lex.re"
        {
                                        goto echo;
                                }
-#line 133 "src/parse/scanner_lex.cc"
+#line 130 "src/parse/scanner_lex.cc"
 yy6:
        yyaccept = 0;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
@@ -138,7 +135,7 @@ yy6:
        }
        if (yych == '#') goto yy91;
 yy7:
-#line 186 "../src/parse/scanner_lex.re"
+#line 183 "../src/parse/scanner_lex.re"
        {
                                        if (ignore_eoc)
                                        {
@@ -152,7 +149,7 @@ yy7:
                                        cline++;
                                        goto echo;
                                }
-#line 156 "src/parse/scanner_lex.cc"
+#line 153 "src/parse/scanner_lex.cc"
 yy8:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == '{') goto yy32;
@@ -236,7 +233,7 @@ yy21:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'c') goto yy12;
        ++YYCURSOR;
-#line 87 "../src/parse/scanner_lex.re"
+#line 84 "../src/parse/scanner_lex.re"
        {
                                        if (rFlag)
                                        {
@@ -249,13 +246,13 @@ yy21:
                                        tok = cur;
                                        return Rules;
                                }
-#line 253 "src/parse/scanner_lex.cc"
+#line 250 "src/parse/scanner_lex.cc"
 yy31:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'c') goto yy12;
 yy32:
        ++YYCURSOR;
-#line 72 "../src/parse/scanner_lex.re"
+#line 69 "../src/parse/scanner_lex.re"
        {
                                        if (rFlag)
                                        {
@@ -271,7 +268,7 @@ yy32:
                                        tok = cur;
                                        return Parse;
                                }
-#line 275 "src/parse/scanner_lex.cc"
+#line 272 "src/parse/scanner_lex.cc"
 yy34:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'e') goto yy12;
@@ -286,7 +283,7 @@ yy34:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'c') goto yy12;
        ++YYCURSOR;
-#line 99 "../src/parse/scanner_lex.re"
+#line 96 "../src/parse/scanner_lex.re"
        {
                                        if (!rFlag)
                                        {
@@ -301,7 +298,7 @@ yy34:
                                        tok = cur;
                                        return Reuse;
                                }
-#line 305 "src/parse/scanner_lex.cc"
+#line 302 "src/parse/scanner_lex.cc"
 yy42:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'x') goto yy12;
@@ -316,7 +313,7 @@ yy42:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'c') goto yy12;
        ++YYCURSOR;
-#line 113 "../src/parse/scanner_lex.re"
+#line 110 "../src/parse/scanner_lex.re"
        {
                                        if (!DFlag)
                                        {
@@ -326,7 +323,7 @@ yy42:
                                        ignore_eoc = true;
                                        goto echo;
                                }
-#line 330 "src/parse/scanner_lex.cc"
+#line 327 "src/parse/scanner_lex.cc"
 yy50:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 't') goto yy12;
@@ -351,14 +348,14 @@ yy50:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'c') goto yy12;
        ++YYCURSOR;
-#line 122 "../src/parse/scanner_lex.re"
+#line 119 "../src/parse/scanner_lex.re"
        {
                                        tok = pos = cur;
                                        out.insert_state_goto (topIndent);
                                        ignore_eoc = true;
                                        goto echo;
                                }
-#line 362 "src/parse/scanner_lex.cc"
+#line 359 "src/parse/scanner_lex.cc"
 yy63:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'n') goto yy12;
@@ -379,13 +376,13 @@ yy63:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'c') goto yy12;
        ++YYCURSOR;
-#line 128 "../src/parse/scanner_lex.re"
+#line 125 "../src/parse/scanner_lex.re"
        {
                                        tok = pos = cur;
                                        ignore_eoc = true;
                                        goto echo;
                                }
-#line 389 "src/parse/scanner_lex.cc"
+#line 386 "src/parse/scanner_lex.cc"
 yy74:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'p') goto yy12;
@@ -404,7 +401,7 @@ yy74:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'c') goto yy12;
        ++YYCURSOR;
-#line 133 "../src/parse/scanner_lex.re"
+#line 130 "../src/parse/scanner_lex.re"
        {
                                        tok = pos = cur;
                                        ignore_eoc = true;
@@ -418,14 +415,14 @@ yy74:
                                        }
                                        goto echo;
                                }
-#line 422 "src/parse/scanner_lex.cc"
+#line 419 "src/parse/scanner_lex.cc"
 yy84:
        yyaccept = 2;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych == '\n') goto yy87;
        if (yych == '\r') goto yy86;
 yy85:
-#line 164 "../src/parse/scanner_lex.re"
+#line 161 "../src/parse/scanner_lex.re"
        {
                                        if (ignore_eoc)
                                        {
@@ -444,13 +441,13 @@ yy85:
                                        tok = pos = cur;
                                        goto echo;
                                }
-#line 448 "src/parse/scanner_lex.cc"
+#line 445 "src/parse/scanner_lex.cc"
 yy86:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != '\n') goto yy12;
 yy87:
        ++YYCURSOR;
-#line 146 "../src/parse/scanner_lex.re"
+#line 143 "../src/parse/scanner_lex.re"
        {
                                        cline++;
                                        if (ignore_eoc)
@@ -469,7 +466,7 @@ yy87:
                                        tok = pos = cur;
                                        goto echo;
                                }
-#line 473 "src/parse/scanner_lex.cc"
+#line 470 "src/parse/scanner_lex.cc"
 yy89:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -544,12 +541,12 @@ yy101:
 yy103:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 182 "../src/parse/scanner_lex.re"
+#line 179 "../src/parse/scanner_lex.re"
        {
                                        set_sourceline ();
                                        goto echo;
                                }
-#line 553 "src/parse/scanner_lex.cc"
+#line 550 "src/parse/scanner_lex.cc"
 yy105:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == '\n') goto yy103;
@@ -574,7 +571,7 @@ yy109:
        if (yych == '\r') goto yy105;
        goto yy12;
 }
-#line 213 "../src/parse/scanner_lex.re"
+#line 210 "../src/parse/scanner_lex.re"
 
 }
 
@@ -596,7 +593,7 @@ scan:
 
 start:
 
-#line 600 "src/parse/scanner_lex.cc"
+#line 597 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        unsigned int yyaccept = 0;
@@ -711,22 +708,22 @@ start:
 yy112:
        ++YYCURSOR;
 yy113:
-#line 431 "../src/parse/scanner_lex.re"
+#line 441 "../src/parse/scanner_lex.re"
        {
                                        fatalf("unexpected character: '%c'", *tok);
                                        goto scan;
                                }
-#line 720 "src/parse/scanner_lex.cc"
+#line 717 "src/parse/scanner_lex.cc"
 yy114:
        ++YYCURSOR;
        yych = (YYCTYPE)*YYCURSOR;
        goto yy248;
 yy115:
-#line 415 "../src/parse/scanner_lex.re"
+#line 425 "../src/parse/scanner_lex.re"
        {
                                        goto scan;
                                }
-#line 730 "src/parse/scanner_lex.cc"
+#line 727 "src/parse/scanner_lex.cc"
 yy116:
        yyaccept = 0;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
@@ -737,14 +734,14 @@ yy116:
                if (yych == '#') goto yy228;
        }
 yy117:
-#line 424 "../src/parse/scanner_lex.re"
+#line 434 "../src/parse/scanner_lex.re"
        {
                                        if (cur == eof) return 0;
                                        pos = cur;
                                        cline++;
                                        goto scan;
                                }
-#line 748 "src/parse/scanner_lex.cc"
+#line 745 "src/parse/scanner_lex.cc"
 yy118:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == '\n') goto yy225;
@@ -754,11 +751,11 @@ yy119:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych != '\n') goto yy221;
 yy120:
-#line 289 "../src/parse/scanner_lex.re"
+#line 286 "../src/parse/scanner_lex.re"
        {
                                        fatal("unterminated string constant (missing \")");
                                }
-#line 762 "src/parse/scanner_lex.cc"
+#line 759 "src/parse/scanner_lex.cc"
 yy121:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == '}') goto yy213;
@@ -768,44 +765,44 @@ yy122:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych != '\n') goto yy216;
 yy123:
-#line 292 "../src/parse/scanner_lex.re"
+#line 289 "../src/parse/scanner_lex.re"
        {
                                        fatal("unterminated string constant (missing ')");
                                }
-#line 776 "src/parse/scanner_lex.cc"
+#line 773 "src/parse/scanner_lex.cc"
 yy124:
        ++YYCURSOR;
 yy125:
-#line 318 "../src/parse/scanner_lex.re"
+#line 315 "../src/parse/scanner_lex.re"
        {
                                        return *tok;
                                }
-#line 784 "src/parse/scanner_lex.cc"
+#line 781 "src/parse/scanner_lex.cc"
 yy126:
        ++YYCURSOR;
        if ((yych = (YYCTYPE)*YYCURSOR) == '/') goto yy213;
-#line 322 "../src/parse/scanner_lex.re"
+#line 319 "../src/parse/scanner_lex.re"
        {
                                        yylval.op = *tok;
                                        return STAR;
                                }
-#line 793 "src/parse/scanner_lex.cc"
+#line 790 "src/parse/scanner_lex.cc"
 yy128:
        ++YYCURSOR;
-#line 326 "../src/parse/scanner_lex.re"
+#line 323 "../src/parse/scanner_lex.re"
        {
                                        yylval.op = *tok;
                                        return CLOSE;
                                }
-#line 801 "src/parse/scanner_lex.cc"
+#line 798 "src/parse/scanner_lex.cc"
 yy130:
        ++YYCURSOR;
-#line 410 "../src/parse/scanner_lex.re"
+#line 420 "../src/parse/scanner_lex.re"
        {
                                        yylval.regexp = mkDot();
                                        return RANGE;
                                }
-#line 809 "src/parse/scanner_lex.cc"
+#line 806 "src/parse/scanner_lex.cc"
 yy132:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == '*') goto yy209;
@@ -833,11 +830,11 @@ yy136:
        if (yych == '^') goto yy188;
        goto yy187;
 yy137:
-#line 308 "../src/parse/scanner_lex.re"
+#line 305 "../src/parse/scanner_lex.re"
        {
                                        fatal("unterminated range (missing ])");
                                }
-#line 841 "src/parse/scanner_lex.cc"
+#line 838 "src/parse/scanner_lex.cc"
 yy138:
        YYCTXMARKER = YYCURSOR + 1;
        yych = (YYCTYPE)*++YYCURSOR;
@@ -863,12 +860,12 @@ yy139:
                }
        }
 yy140:
-#line 234 "../src/parse/scanner_lex.re"
+#line 231 "../src/parse/scanner_lex.re"
        {
                                        depth = 1;
                                        goto code;
                                }
-#line 872 "src/parse/scanner_lex.cc"
+#line 869 "src/parse/scanner_lex.cc"
 yy141:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == ',') goto yy160;
@@ -940,14 +937,14 @@ yy145:
 yy147:
        ++YYCURSOR;
 yy148:
-#line 354 "../src/parse/scanner_lex.re"
+#line 364 "../src/parse/scanner_lex.re"
        {
                                        fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers");
                                }
-#line 948 "src/parse/scanner_lex.cc"
+#line 945 "src/parse/scanner_lex.cc"
 yy149:
        ++YYCURSOR;
-#line 358 "../src/parse/scanner_lex.re"
+#line 368 "../src/parse/scanner_lex.re"
        {
                                        if (!FFlag) {
                                                fatal("curly braces for names only allowed with -F switch");
@@ -955,13 +952,16 @@ yy149:
                                        yylval.str = new std::string (tok + 1, tok_len () - 2); // -2 to omit braces
                                        return ID;
                                }
-#line 959 "src/parse/scanner_lex.cc"
+#line 956 "src/parse/scanner_lex.cc"
 yy151:
        ++YYCURSOR;
-#line 336 "../src/parse/scanner_lex.re"
+#line 333 "../src/parse/scanner_lex.re"
        {
-                                       yylval.extop.minsize = atoi((char *)tok+1);
-                                       yylval.extop.maxsize = atoi((char *)tok+1);
+                                       if (!s_to_u32_unsafe (tok + 1, cur - 1, yylval.extop.min))
+                                       {
+                                               fatal ("repetition count overflow");
+                                       }
+                                       yylval.extop.max = yylval.extop.min;
                                        return CLOSESIZE;
                                }
 #line 968 "src/parse/scanner_lex.cc"
@@ -972,13 +972,16 @@ yy153:
        if (yych <= '9') goto yy156;
        if (yych != '}') goto yy148;
        ++YYCURSOR;
-#line 348 "../src/parse/scanner_lex.re"
+#line 355 "../src/parse/scanner_lex.re"
        {
-                                       yylval.extop.minsize = atoi((char *)tok+1);
-                                       yylval.extop.maxsize = -1;
+                                       if (!s_to_u32_unsafe (tok + 1, cur - 2, yylval.extop.min))
+                                       {
+                                               fatal ("repetition lower bound overflow");
+                                       }
+                                       yylval.extop.max = UINT32_MAX;
                                        return CLOSESIZE;
                                }
-#line 982 "src/parse/scanner_lex.cc"
+#line 985 "src/parse/scanner_lex.cc"
 yy156:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -989,11 +992,18 @@ yy156:
        ++YYCURSOR;
 #line 342 "../src/parse/scanner_lex.re"
        {
-                                       yylval.extop.minsize = atoi((char *)tok+1);
-                                       yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1));
+                                       const char * p = strchr (tok, ',');
+                                       if (!s_to_u32_unsafe (tok + 1, p, yylval.extop.min))
+                                       {
+                                               fatal ("repetition lower bound overflow");
+                                       }
+                                       if (!s_to_u32_unsafe (p + 1, cur - 1, yylval.extop.max))
+                                       {
+                                               fatal ("repetition upper bound overflow");
+                                       }
                                        return CLOSESIZE;
                                }
-#line 997 "src/parse/scanner_lex.cc"
+#line 1007 "src/parse/scanner_lex.cc"
 yy160:
        yyaccept = 6;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
@@ -1001,17 +1011,17 @@ yy160:
        if (yych <= '9') goto yy156;
        if (yych != '}') goto yy148;
        ++YYCURSOR;
-#line 331 "../src/parse/scanner_lex.re"
+#line 328 "../src/parse/scanner_lex.re"
        {
                                        yylval.op = '*';
                                        return CLOSE;
                                }
-#line 1010 "src/parse/scanner_lex.cc"
+#line 1020 "src/parse/scanner_lex.cc"
 yy163:
        ++YYCURSOR;
 yy164:
        YYCURSOR = YYCTXMARKER;
-#line 391 "../src/parse/scanner_lex.re"
+#line 401 "../src/parse/scanner_lex.re"
        {
                                        if (!FFlag) {
                                                yylval.str = new std::string (tok, tok_len ());
@@ -1030,7 +1040,7 @@ yy164:
                                                return STRING;
                                        }
                                }
-#line 1034 "src/parse/scanner_lex.cc"
+#line 1044 "src/parse/scanner_lex.cc"
 yy165:
        yych = (YYCTYPE)*++YYCURSOR;
        goto yy184;
@@ -1038,12 +1048,12 @@ yy166:
        ++YYCURSOR;
 yy167:
        YYCURSOR = YYCTXMARKER;
-#line 386 "../src/parse/scanner_lex.re"
+#line 396 "../src/parse/scanner_lex.re"
        {
                                        yylval.str = new std::string (tok, tok_len ());
                                        return ID;
                                }
-#line 1047 "src/parse/scanner_lex.cc"
+#line 1057 "src/parse/scanner_lex.cc"
 yy168:
        YYCTXMARKER = YYCURSOR + 1;
        ++YYCURSOR;
@@ -1122,14 +1132,14 @@ yy174:
                }
        }
 yy176:
-#line 366 "../src/parse/scanner_lex.re"
+#line 376 "../src/parse/scanner_lex.re"
        {
                                        tok += 5; /* skip "re2c:" */
                                        lexer_state = LEX_CONFIG;
                                        yylval.str = new std::string (tok, tok_len ());
                                        return CONFIG;
                                }
-#line 1133 "src/parse/scanner_lex.cc"
+#line 1143 "src/parse/scanner_lex.cc"
 yy177:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= 'Z') {
@@ -1188,7 +1198,7 @@ yy179:
 yy181:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 373 "../src/parse/scanner_lex.re"
+#line 383 "../src/parse/scanner_lex.re"
        {
                                        yylval.str = new std::string (tok, tok_len ());
                                        if (FFlag)
@@ -1201,7 +1211,7 @@ yy181:
                                                return ID;
                                        }
                                }
-#line 1205 "src/parse/scanner_lex.cc"
+#line 1215 "src/parse/scanner_lex.cc"
 yy183:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -1247,13 +1257,13 @@ yy190:
        goto yy186;
 yy191:
        ++YYCURSOR;
-#line 302 "../src/parse/scanner_lex.re"
+#line 299 "../src/parse/scanner_lex.re"
        {
                                        SubStr s (tok, tok_len ());
                                        yylval.regexp = ranToRE (s);
                                        return RANGE;
                                }
-#line 1257 "src/parse/scanner_lex.cc"
+#line 1267 "src/parse/scanner_lex.cc"
 yy193:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -1262,20 +1272,20 @@ yy193:
        goto yy188;
 yy194:
        ++YYCURSOR;
-#line 296 "../src/parse/scanner_lex.re"
+#line 293 "../src/parse/scanner_lex.re"
        {
                                        SubStr s (tok, tok_len ());
                                        yylval.regexp = invToRE (s);
                                        return RANGE;
                                }
-#line 1272 "src/parse/scanner_lex.cc"
+#line 1282 "src/parse/scanner_lex.cc"
 yy196:
        ++YYCURSOR;
-#line 315 "../src/parse/scanner_lex.re"
+#line 312 "../src/parse/scanner_lex.re"
        {
                                        return SETUP;
                                }
-#line 1279 "src/parse/scanner_lex.cc"
+#line 1289 "src/parse/scanner_lex.cc"
 yy198:
        YYCTXMARKER = YYCURSOR + 1;
        yych = (YYCTYPE)*++YYCURSOR;
@@ -1305,11 +1315,11 @@ yy200:
 yy201:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 312 "../src/parse/scanner_lex.re"
+#line 309 "../src/parse/scanner_lex.re"
        {
                                        return NOCOND;
                                }
-#line 1313 "src/parse/scanner_lex.cc"
+#line 1323 "src/parse/scanner_lex.cc"
 yy203:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == '>') goto yy201;
@@ -1321,44 +1331,44 @@ yy204:
 yy205:
        ++YYCURSOR;
        if ((yych = (YYCTYPE)*YYCURSOR) == '>') goto yy207;
-#line 243 "../src/parse/scanner_lex.re"
+#line 240 "../src/parse/scanner_lex.re"
        {
                                        tok += 2; /* skip ":=" */
                                        depth = 0;
                                        goto code;
                                }
-#line 1331 "src/parse/scanner_lex.cc"
+#line 1341 "src/parse/scanner_lex.cc"
 yy207:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 239 "../src/parse/scanner_lex.re"
+#line 236 "../src/parse/scanner_lex.re"
        {
                                        return *tok;
                                }
-#line 1339 "src/parse/scanner_lex.cc"
+#line 1349 "src/parse/scanner_lex.cc"
 yy209:
        ++YYCURSOR;
-#line 252 "../src/parse/scanner_lex.re"
+#line 249 "../src/parse/scanner_lex.re"
        {
                                        depth = 1;
                                        goto comment;
                                }
-#line 1347 "src/parse/scanner_lex.cc"
+#line 1357 "src/parse/scanner_lex.cc"
 yy211:
        ++YYCURSOR;
-#line 249 "../src/parse/scanner_lex.re"
+#line 246 "../src/parse/scanner_lex.re"
        {
                                goto nextLine;
                        }
-#line 1354 "src/parse/scanner_lex.cc"
+#line 1364 "src/parse/scanner_lex.cc"
 yy213:
        ++YYCURSOR;
-#line 258 "../src/parse/scanner_lex.re"
+#line 255 "../src/parse/scanner_lex.re"
        {
                                        tok = cur;
                                        return 0;
                                }
-#line 1362 "src/parse/scanner_lex.cc"
+#line 1372 "src/parse/scanner_lex.cc"
 yy215:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -1376,7 +1386,7 @@ yy216:
        goto yy215;
 yy218:
        ++YYCURSOR;
-#line 276 "../src/parse/scanner_lex.re"
+#line 273 "../src/parse/scanner_lex.re"
        {
                                        SubStr s (tok + 1, tok_len () - 2); // -2 to omit quotes
                                        if (bCaseInverted)
@@ -1389,7 +1399,7 @@ yy218:
                                        }
                                        return STRING;
                                }
-#line 1393 "src/parse/scanner_lex.cc"
+#line 1403 "src/parse/scanner_lex.cc"
 yy220:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -1407,7 +1417,7 @@ yy221:
        goto yy220;
 yy223:
        ++YYCURSOR;
-#line 263 "../src/parse/scanner_lex.re"
+#line 260 "../src/parse/scanner_lex.re"
        {
                                        SubStr s (tok + 1, tok_len () - 2); // -2 to omit quotes
                                        if (bCaseInsensitive || bCaseInverted)
@@ -1420,7 +1430,7 @@ yy223:
                                        }
                                        return STRING;
                                }
-#line 1424 "src/parse/scanner_lex.cc"
+#line 1434 "src/parse/scanner_lex.cc"
 yy225:
        yyaccept = 0;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
@@ -1513,12 +1523,12 @@ yy238:
 yy240:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 419 "../src/parse/scanner_lex.re"
+#line 429 "../src/parse/scanner_lex.re"
        {
                                        set_sourceline ();
                                        goto scan;
                                }
-#line 1522 "src/parse/scanner_lex.cc"
+#line 1532 "src/parse/scanner_lex.cc"
 yy242:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == '\n') goto yy240;
@@ -1553,12 +1563,12 @@ yy248:
        if (yych == ' ') goto yy247;
        goto yy115;
 }
-#line 435 "../src/parse/scanner_lex.re"
+#line 445 "../src/parse/scanner_lex.re"
 
 
 flex_name:
 
-#line 1562 "src/parse/scanner_lex.cc"
+#line 1572 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
@@ -1567,22 +1577,22 @@ flex_name:
        if (yych == '\r') goto yy255;
        ++YYCURSOR;
 yy252:
-#line 446 "../src/parse/scanner_lex.re"
+#line 456 "../src/parse/scanner_lex.re"
        {
                YYCURSOR = tok;
                goto start;
        }
-#line 1576 "src/parse/scanner_lex.cc"
+#line 1586 "src/parse/scanner_lex.cc"
 yy253:
        ++YYCURSOR;
 yy254:
-#line 440 "../src/parse/scanner_lex.re"
+#line 450 "../src/parse/scanner_lex.re"
        {
                YYCURSOR = tok;
                lexer_state = LEX_NORMAL;
                return FID_END;
        }
-#line 1586 "src/parse/scanner_lex.cc"
+#line 1596 "src/parse/scanner_lex.cc"
 yy255:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != '\n') goto yy252;
@@ -1590,12 +1600,12 @@ yy255:
        yych = (YYCTYPE)*YYCURSOR;
        goto yy254;
 }
-#line 450 "../src/parse/scanner_lex.re"
+#line 460 "../src/parse/scanner_lex.re"
 
 
 code:
 
-#line 1599 "src/parse/scanner_lex.cc"
+#line 1609 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        unsigned int yyaccept = 0;
@@ -1656,7 +1666,7 @@ code:
        }
 yy259:
        ++YYCURSOR;
-#line 513 "../src/parse/scanner_lex.re"
+#line 523 "../src/parse/scanner_lex.re"
        {
                                        if (cur == eof)
                                        {
@@ -1668,15 +1678,15 @@ yy259:
                                        }
                                        goto code;
                                }
-#line 1672 "src/parse/scanner_lex.cc"
+#line 1682 "src/parse/scanner_lex.cc"
 yy261:
        ++YYCURSOR;
 yy262:
-#line 527 "../src/parse/scanner_lex.re"
+#line 537 "../src/parse/scanner_lex.re"
        {
                                        goto code;
                                }
-#line 1680 "src/parse/scanner_lex.cc"
+#line 1690 "src/parse/scanner_lex.cc"
 yy263:
        YYCTXMARKER = YYCURSOR + 1;
        yyaccept = 0;
@@ -1696,7 +1706,7 @@ yy263:
                }
        }
 yy264:
-#line 494 "../src/parse/scanner_lex.re"
+#line 504 "../src/parse/scanner_lex.re"
        {
                                        if (depth == 0)
                                        {
@@ -1716,7 +1726,7 @@ yy264:
                                        cline++;
                                        goto code;
                                }
-#line 1720 "src/parse/scanner_lex.cc"
+#line 1730 "src/parse/scanner_lex.cc"
 yy265:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
@@ -1729,7 +1739,7 @@ yy266:
        goto yy272;
 yy267:
        ++YYCURSOR;
-#line 466 "../src/parse/scanner_lex.re"
+#line 476 "../src/parse/scanner_lex.re"
        {
                                        if (depth == 0)
                                        {
@@ -1741,10 +1751,10 @@ yy267:
                                        }
                                        goto code;
                                }
-#line 1745 "src/parse/scanner_lex.cc"
+#line 1755 "src/parse/scanner_lex.cc"
 yy269:
        ++YYCURSOR;
-#line 454 "../src/parse/scanner_lex.re"
+#line 464 "../src/parse/scanner_lex.re"
        {
                                        if (depth == 0)
                                        {
@@ -1757,7 +1767,7 @@ yy269:
                                        }
                                        goto code;
                                }
-#line 1761 "src/parse/scanner_lex.cc"
+#line 1771 "src/parse/scanner_lex.cc"
 yy271:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -1788,11 +1798,11 @@ yy274:
        goto yy271;
 yy275:
        ++YYCURSOR;
-#line 524 "../src/parse/scanner_lex.re"
+#line 534 "../src/parse/scanner_lex.re"
        {
                                        goto code;
                                }
-#line 1796 "src/parse/scanner_lex.cc"
+#line 1806 "src/parse/scanner_lex.cc"
 yy277:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -1819,7 +1829,7 @@ yy280:
        }
 yy281:
        YYCURSOR = YYCTXMARKER;
-#line 481 "../src/parse/scanner_lex.re"
+#line 491 "../src/parse/scanner_lex.re"
        {
                                        if (depth == 0)
                                        {
@@ -1833,7 +1843,7 @@ yy281:
                                        cline++;
                                        goto code;
                                }
-#line 1837 "src/parse/scanner_lex.cc"
+#line 1847 "src/parse/scanner_lex.cc"
 yy282:
        yych = (YYCTYPE)*++YYCURSOR;
        goto yy281;
@@ -1900,12 +1910,12 @@ yy293:
 yy295:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 477 "../src/parse/scanner_lex.re"
+#line 487 "../src/parse/scanner_lex.re"
        {
                                        set_sourceline ();
                                        goto code;
                                }
-#line 1909 "src/parse/scanner_lex.cc"
+#line 1919 "src/parse/scanner_lex.cc"
 yy297:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == '\n') goto yy295;
@@ -1944,12 +1954,12 @@ yy302:
                goto yy273;
        }
 }
-#line 530 "../src/parse/scanner_lex.re"
+#line 540 "../src/parse/scanner_lex.re"
 
 
 comment:
 
-#line 1953 "src/parse/scanner_lex.cc"
+#line 1963 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -1996,7 +2006,7 @@ comment:
        }
        ++YYCURSOR;
 yy307:
-#line 562 "../src/parse/scanner_lex.re"
+#line 572 "../src/parse/scanner_lex.re"
        {
                                        if (cur == eof)
                                        {
@@ -2004,7 +2014,7 @@ yy307:
                                        }
                                        goto comment;
                                }
-#line 2008 "src/parse/scanner_lex.cc"
+#line 2018 "src/parse/scanner_lex.cc"
 yy308:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yybm[0+yych] & 32) {
@@ -2012,7 +2022,7 @@ yy308:
        }
        if (yych == '#') goto yy319;
 yy309:
-#line 553 "../src/parse/scanner_lex.re"
+#line 563 "../src/parse/scanner_lex.re"
        {
                                        if (cur == eof)
                                        {
@@ -2022,7 +2032,7 @@ yy309:
                                        cline++;
                                        goto comment;
                                }
-#line 2026 "src/parse/scanner_lex.cc"
+#line 2036 "src/parse/scanner_lex.cc"
 yy310:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == '/') goto yy314;
@@ -2031,16 +2041,16 @@ yy311:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != '*') goto yy307;
        ++YYCURSOR;
-#line 544 "../src/parse/scanner_lex.re"
+#line 554 "../src/parse/scanner_lex.re"
        {
                                        ++depth;
                                        fatal("ambiguous /* found");
                                        goto comment;
                                }
-#line 2041 "src/parse/scanner_lex.cc"
+#line 2051 "src/parse/scanner_lex.cc"
 yy314:
        ++YYCURSOR;
-#line 534 "../src/parse/scanner_lex.re"
+#line 544 "../src/parse/scanner_lex.re"
        {
                                        if (--depth == 0)
                                        {
@@ -2051,7 +2061,7 @@ yy314:
                                                goto comment;
                                        }
                                }
-#line 2055 "src/parse/scanner_lex.cc"
+#line 2065 "src/parse/scanner_lex.cc"
 yy316:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -2129,12 +2139,12 @@ yy329:
 yy331:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 549 "../src/parse/scanner_lex.re"
+#line 559 "../src/parse/scanner_lex.re"
        {
                                        set_sourceline ();
                                        goto comment;
                                }
-#line 2138 "src/parse/scanner_lex.cc"
+#line 2148 "src/parse/scanner_lex.cc"
 yy333:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == '\n') goto yy331;
@@ -2159,28 +2169,28 @@ yy337:
        if (yych == '\r') goto yy333;
        goto yy318;
 }
-#line 569 "../src/parse/scanner_lex.re"
+#line 579 "../src/parse/scanner_lex.re"
 
 
 nextLine:
 
-#line 2168 "src/parse/scanner_lex.cc"
+#line 2178 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych == '\n') goto yy342;
        ++YYCURSOR;
-#line 580 "../src/parse/scanner_lex.re"
+#line 590 "../src/parse/scanner_lex.re"
        {  if(cur == eof) {
                   return 0;
                }
                goto nextLine;
             }
-#line 2181 "src/parse/scanner_lex.cc"
+#line 2191 "src/parse/scanner_lex.cc"
 yy342:
        ++YYCURSOR;
-#line 573 "../src/parse/scanner_lex.re"
+#line 583 "../src/parse/scanner_lex.re"
        { if(cur == eof) {
                   return 0;
                }
@@ -2188,14 +2198,14 @@ yy342:
                cline++;
                goto scan;
             }
-#line 2192 "src/parse/scanner_lex.cc"
+#line 2202 "src/parse/scanner_lex.cc"
 }
-#line 585 "../src/parse/scanner_lex.re"
+#line 595 "../src/parse/scanner_lex.re"
 
 
 config:
 
-#line 2199 "src/parse/scanner_lex.cc"
+#line 2209 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -2241,32 +2251,32 @@ config:
                if (yych == '=') goto yy350;
        }
        ++YYCURSOR;
-#line 596 "../src/parse/scanner_lex.re"
+#line 606 "../src/parse/scanner_lex.re"
        {
                                        fatal("missing '='");
                                }
-#line 2249 "src/parse/scanner_lex.cc"
+#line 2259 "src/parse/scanner_lex.cc"
 yy348:
        ++YYCURSOR;
        yych = (YYCTYPE)*YYCURSOR;
        goto yy355;
 yy349:
-#line 589 "../src/parse/scanner_lex.re"
+#line 599 "../src/parse/scanner_lex.re"
        {
                                        goto config;
                                }
-#line 2259 "src/parse/scanner_lex.cc"
+#line 2269 "src/parse/scanner_lex.cc"
 yy350:
        ++YYCURSOR;
        yych = (YYCTYPE)*YYCURSOR;
        goto yy353;
 yy351:
-#line 592 "../src/parse/scanner_lex.re"
+#line 602 "../src/parse/scanner_lex.re"
        {
                                        lexer_state = LEX_CONFIG_VALUE;
                                        return '=';
                                }
-#line 2270 "src/parse/scanner_lex.cc"
+#line 2280 "src/parse/scanner_lex.cc"
 yy352:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -2285,12 +2295,12 @@ yy355:
        if (yych == ' ') goto yy354;
        goto yy349;
 }
-#line 599 "../src/parse/scanner_lex.re"
+#line 609 "../src/parse/scanner_lex.re"
 
 
 value:
 
-#line 2294 "src/parse/scanner_lex.cc"
+#line 2304 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -2357,26 +2367,29 @@ value:
                }
        }
 yy358:
-#line 608 "../src/parse/scanner_lex.re"
+#line 621 "../src/parse/scanner_lex.re"
        {
                                        yylval.str = new std::string (tok, tok_len ());
                                        lexer_state = LEX_NORMAL;
                                        return VALUE;
                                }
-#line 2367 "src/parse/scanner_lex.cc"
+#line 2377 "src/parse/scanner_lex.cc"
 yy359:
        ++YYCURSOR;
        if (yybm[0+(yych = (YYCTYPE)*YYCURSOR)] & 8) {
                goto yy364;
        }
 yy360:
-#line 603 "../src/parse/scanner_lex.re"
+#line 613 "../src/parse/scanner_lex.re"
        {
-                                       yylval.number = atoi(std::string (tok, tok_len ()).c_str());
+                                       if (!s_to_i32_unsafe (tok, cur, yylval.number))
+                                       {
+                                               fatal ("configuration value overflow");
+                                       }
                                        lexer_state = LEX_NORMAL;
                                        return NUMBER;
                                }
-#line 2380 "src/parse/scanner_lex.cc"
+#line 2393 "src/parse/scanner_lex.cc"
 yy361:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '0') goto yy365;
@@ -2519,7 +2532,7 @@ yy379:
        if (yych == '\n') goto yy372;
        goto yy376;
 }
-#line 613 "../src/parse/scanner_lex.re"
+#line 626 "../src/parse/scanner_lex.re"
 
 }
 
@@ -2542,7 +2555,7 @@ void Scanner::set_sourceline ()
 sourceline:
        tok = cur;
 
-#line 2546 "src/parse/scanner_lex.cc"
+#line 2559 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -2591,14 +2604,14 @@ sourceline:
 yy382:
        ++YYCURSOR;
 yy383:
-#line 655 "../src/parse/scanner_lex.re"
+#line 671 "../src/parse/scanner_lex.re"
        {
                                        goto sourceline;
                                }
-#line 2599 "src/parse/scanner_lex.cc"
+#line 2612 "src/parse/scanner_lex.cc"
 yy384:
        ++YYCURSOR;
-#line 643 "../src/parse/scanner_lex.re"
+#line 659 "../src/parse/scanner_lex.re"
        {
                                        if (cur == eof)
                                        {
@@ -2611,7 +2624,7 @@ yy384:
                                        tok = cur;
                                        return; 
                                }
-#line 2615 "src/parse/scanner_lex.cc"
+#line 2628 "src/parse/scanner_lex.cc"
 yy386:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych == '\n') goto yy383;
@@ -2621,12 +2634,15 @@ yy387:
        yych = (YYCTYPE)*YYCURSOR;
        goto yy390;
 yy388:
-#line 635 "../src/parse/scanner_lex.re"
+#line 648 "../src/parse/scanner_lex.re"
        {
-                                       cline = atoi(std::string (tok, tok_len ()).c_str());
+                                       if (!s_to_u32_unsafe (tok, cur, cline))
+                                       {
+                                               fatal ("line number overflow");
+                                       }
                                        goto sourceline; 
                                }
-#line 2630 "src/parse/scanner_lex.cc"
+#line 2646 "src/parse/scanner_lex.cc"
 yy389:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -2658,14 +2674,14 @@ yy394:
        goto yy391;
 yy395:
        ++YYCURSOR;
-#line 639 "../src/parse/scanner_lex.re"
+#line 655 "../src/parse/scanner_lex.re"
        {
                                        escape (in.file_name, std::string (tok + 1, tok_len () - 2)); // -2 to omit quotes
                                        goto sourceline; 
                                }
-#line 2667 "src/parse/scanner_lex.cc"
+#line 2683 "src/parse/scanner_lex.cc"
 }
-#line 658 "../src/parse/scanner_lex.re"
+#line 674 "../src/parse/scanner_lex.re"
 
 }
 
index f2ac5cd0cafaa7a7e87e24e4927acaf24ffbfe31..d093be9244964576a02acd9f4e5c8e0d8b0b529c 100644 (file)
@@ -8,8 +8,8 @@ namespace re2c
 
 struct ExtOp
 {
-       int32_t minsize;
-       int32_t maxsize;
+       uint32_t min;
+       uint32_t max;
 };
 
 } // end namespace re2c
index 1c9ae042e98c0331953ef56c4fff9e8ef21e6e02..fba9a9f5e3571e623db84d864cbd4173f04e6c3d 100644 (file)
@@ -420,17 +420,17 @@ factor:
        |       primary CLOSESIZE
                {
                        $1->ins_access = RegExp::PRIVATE;
-                       if ($2.maxsize < 0)
+                       if ($2.max == UINT32_MAX)
                        {
-                               $$ = repeat_from ($1, $2.minsize);
+                               $$ = repeat_from ($1, $2.min);
                        }
-                       else if ($2.minsize == $2.maxsize)
+                       else if ($2.min == $2.max)
                        {
-                               $$ = repeat ($1, $2.minsize);
+                               $$ = repeat ($1, $2.min);
                        }
                        else
                        {
-                               $$ = repeat_from_to ($1, $2.minsize, $2.maxsize);
+                               $$ = repeat_from_to ($1, $2.min, $2.max);
                        }
                        $$ = $$ ? $$ : new NullOp;
                }
index 9b8eaa3f3f5005fed98817aa108e14b5089d181c..91bb7bba542524a3c1e2063557f31f1b63987c22 100644 (file)
@@ -9,13 +9,10 @@
 #include "src/parse/parser.h"
 #include "src/parse/scanner.h"
 #include "y.tab.h"
+#include "src/util/s_to_n32_unsafe.h"
 
 extern YYSTYPE yylval;
 
-#ifndef MAX
-#define MAX(a,b) (((a)>(b))?(a):(b))
-#endif
-
 #define        YYCTYPE         unsigned char
 #define        YYCURSOR        cur
 #define        YYLIMIT         lim
@@ -334,20 +331,33 @@ start:
                                }
 
        "{" [0-9]+ "}"  {
-                                       yylval.extop.minsize = atoi((char *)tok+1);
-                                       yylval.extop.maxsize = atoi((char *)tok+1);
+                                       if (!s_to_u32_unsafe (tok + 1, cur - 1, yylval.extop.min))
+                                       {
+                                               fatal ("repetition count overflow");
+                                       }
+                                       yylval.extop.max = yylval.extop.min;
                                        return CLOSESIZE;
                                }
 
        "{" [0-9]+ "," [0-9]+ "}"       {
-                                       yylval.extop.minsize = atoi((char *)tok+1);
-                                       yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1));
+                                       const char * p = strchr (tok, ',');
+                                       if (!s_to_u32_unsafe (tok + 1, p, yylval.extop.min))
+                                       {
+                                               fatal ("repetition lower bound overflow");
+                                       }
+                                       if (!s_to_u32_unsafe (p + 1, cur - 1, yylval.extop.max))
+                                       {
+                                               fatal ("repetition upper bound overflow");
+                                       }
                                        return CLOSESIZE;
                                }
 
        "{" [0-9]+ ",}"         {
-                                       yylval.extop.minsize = atoi((char *)tok+1);
-                                       yylval.extop.maxsize = -1;
+                                       if (!s_to_u32_unsafe (tok + 1, cur - 2, yylval.extop.min))
+                                       {
+                                               fatal ("repetition lower bound overflow");
+                                       }
+                                       yylval.extop.max = UINT32_MAX;
                                        return CLOSESIZE;
                                }
 
@@ -601,7 +611,10 @@ config:
 value:
 /*!re2c
        number          {
-                                       yylval.number = atoi(std::string (tok, tok_len ()).c_str());
+                                       if (!s_to_i32_unsafe (tok, cur, yylval.number))
+                                       {
+                                               fatal ("configuration value overflow");
+                                       }
                                        lexer_state = LEX_NORMAL;
                                        return NUMBER;
                                }
@@ -633,7 +646,10 @@ sourceline:
        tok = cur;
 /*!re2c        
        lineno          {
-                                       cline = atoi(std::string (tok, tok_len ()).c_str());
+                                       if (!s_to_u32_unsafe (tok, cur, cline))
+                                       {
+                                               fatal ("line number overflow");
+                                       }
                                        goto sourceline; 
                                }
        dstring         {
diff --git a/re2c/src/test/s_to_n32_unsafe/test.cc b/re2c/src/test/s_to_n32_unsafe/test.cc
new file mode 100644 (file)
index 0000000..44977be
--- /dev/null
@@ -0,0 +1,98 @@
+#include <stdio.h>
+
+#include "src/util/s_to_n32_unsafe.h"
+
+namespace re2c_test {
+
+static const uint32_t DIGITS = 256;
+
+// writes string backwards and returns pointer to the start
+// no terminating null as we don't need it
+static char * u64_to_s_fastest_ever (uint64_t u, char * s)
+{
+       while (u > 0)
+       {
+               const uint64_t d = u % 10 + '0';
+               *--s = static_cast<char> (d);
+               u /= 10;
+       }
+       return s;
+}
+
+static int32_t test_u (uint64_t i)
+{
+       char s [DIGITS];
+       char * const s_end = s + DIGITS;
+       char * const s_start = u64_to_s_fastest_ever (i, s_end);
+       uint32_t u = i == 0; // not equal to i
+       if (s_to_u32_unsafe (s_start, s_end, u) && u != i)
+       {
+               fprintf (stderr, "unsigned: expected: %lu, got: %u\n", i, u);
+               return 1;
+       }
+       return 0;
+}
+
+static int32_t test_i (int64_t i)
+{
+       char s [DIGITS];
+       char * const s_end = s + DIGITS;
+       const uint64_t i_abs = i < 0
+               ? static_cast<uint64_t> (-i)
+               : static_cast<uint64_t> (i);
+       char * s_start = u64_to_s_fastest_ever (i_abs, s_end);
+       if (i < 0)
+       {
+               *--s_start = '-';
+       }
+       int32_t j = i == 0; // not equal to i
+       if (s_to_i32_unsafe (s_start, s_end, j) && j != i)
+       {
+               fprintf (stderr, "signed: expected: %ld, got: %d\n", i, j);
+               return 1;
+       }
+       return 0;
+}
+
+static int32_t test ()
+{
+       int32_t ok = 0;
+
+       static const uint64_t UDELTA = 0xFFFF;
+       // zero neighbourhood
+       for (uint64_t i = 0; i <= UDELTA; ++i)
+       {
+               ok |= test_u (i);
+       }
+       // UINT32_MAX neighbourhood
+       for (uint64_t i = UINT32_MAX - UDELTA; i <= UINT32_MAX + UDELTA; ++i)
+       {
+               ok |= test_u (i);
+       }
+
+       static const int64_t IDELTA = 0xFFFF;
+       // INT32_MIN neighbourhood
+       for (int64_t i = INT32_MIN - IDELTA; i <= INT32_MIN + IDELTA; ++i)
+       {
+               ok |= test_i (i);
+       }
+       // zero neighbourhood
+       for (int64_t i = -IDELTA; i <= IDELTA; ++i)
+       {
+               ok |= test_i (i);
+       }
+       // INT32_MAX neighbourhood
+       for (int64_t i = INT32_MAX - IDELTA; i <= INT32_MAX + IDELTA; ++i)
+       {
+               ok |= test_i (i);
+       }
+
+       return ok;
+}
+
+} // namespace re2c_test
+
+int main ()
+{
+       return re2c_test::test ();
+}
diff --git a/re2c/src/util/s_to_n32_unsafe.cc b/re2c/src/util/s_to_n32_unsafe.cc
new file mode 100644 (file)
index 0000000..050547c
--- /dev/null
@@ -0,0 +1,53 @@
+#include "src/util/s_to_n32_unsafe.h"
+
+// assumes that string matches regexp [0-9]+
+// returns false on overflow
+bool s_to_u32_unsafe (const char * s, const char * s_end, uint32_t & number)
+{
+       uint64_t u = 0;
+       for (; s != s_end; ++s)
+       {
+               u *= 10;
+               u += static_cast<uint32_t> (*s) - 0x30;
+               if (u >= UINT32_MAX)
+               {
+                       return false;
+               }
+       }
+       number = static_cast<uint32_t> (u);
+       return true;
+}
+
+// assumes that string matches regexp "-"? [0-9]+
+// returns false on underflow/overflow
+bool s_to_i32_unsafe (const char * s, const char * s_end, int32_t & number)
+{
+       int64_t i = 0;
+       if (*s == '-')
+       {
+               ++s;
+               for (; s != s_end; ++s)
+               {
+                       i *= 10;
+                       i -= *s - 0x30;
+                       if (i < INT32_MIN)
+                       {
+                               return false;
+                       }
+               }
+       }
+       else
+       {
+               for (; s != s_end; ++s)
+               {
+                       i *= 10;
+                       i += *s - 0x30;
+                       if (i > INT32_MAX)
+                       {
+                               return false;
+                       }
+               }
+       }
+       number = static_cast<int32_t> (i);
+       return true;
+}
diff --git a/re2c/src/util/s_to_n32_unsafe.h b/re2c/src/util/s_to_n32_unsafe.h
new file mode 100644 (file)
index 0000000..e733c16
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _RE2C_UTIL_S_TO_N32_UNSAFE_
+#define _RE2C_UTIL_S_TO_N32_UNSAFE_
+
+#include "src/util/attribute.h"
+#include "src/util/c99_stdint.h"
+
+bool s_to_u32_unsafe (const char * s, const char * s_end, uint32_t & number) RE2C_GXX_ATTRIBUTE ((warn_unused_result));
+bool s_to_i32_unsafe (const char * s, const char * s_end, int32_t & number) RE2C_GXX_ATTRIBUTE ((warn_unused_result));
+
+#endif // _RE2C_UTIL_S_TO_N32_UNSAFE_