]> granicus.if.org Git - re2c/commitdiff
Fixed segfault on options that expect an argument but are passed none.
authorUlya Trofimovich <skvadrik@gmail.com>
Wed, 29 Jul 2015 13:46:19 +0000 (14:46 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Wed, 29 Jul 2015 13:46:19 +0000 (14:46 +0100)
Example of commands that triggered segfault:
    $ re2c -o
    $ re2c --type-header
    $ re2c --input

re2c/bootstrap/src/conf/parse_opts.cc
re2c/src/conf/msg.cc
re2c/src/conf/msg.h
re2c/src/conf/opt.h
re2c/src/conf/parse_opts.re
re2c/src/main.cc

index 26ed9fb84dfa68b63076b15f81ad8fdb2aa5519c..d5852e14de62b721b5c13acfe4a112a9e364f961 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.14.3 on Wed Jul 29 12:29:18 2015 */
+/* Generated by re2c 0.14.3 on Wed Jul 29 14:24:46 2015 */
 #include <stdio.h>
 
 #include "src/conf/msg.h"
@@ -7,14 +7,14 @@
 namespace re2c
 {
 
-parse_opts_t parse_opts (int argc, char ** argv, Opt & opts)
+static inline bool next (char * & arg, char ** & argv)
 {
-       if (argc == 1)
-       {
-               usage ();
-               return EXIT_FAIL;
-       }
+       arg = *++argv;
+       return arg != NULL;
+}
 
+parse_opts_t parse_opts (char ** argv, Opt & opts)
+{
 #define YYCTYPE char
        YYCTYPE * YYCURSOR;
        YYCTYPE * YYMARKER;
@@ -23,8 +23,7 @@ parse_opts_t parse_opts (int argc, char ** argv, Opt & opts)
 
 
 opt:
-       YYCURSOR = *++argv;
-       if (YYCURSOR == NULL)
+       if (!next (YYCURSOR, argv))
        {
                goto end;
        }
@@ -115,7 +114,7 @@ yy13:
                // all remaining arguments are non-options
                // so they must be input files
                // re2c expects exactly one input file
-               for (const char * f = *++argv; f; f = *++argv)
+               for (char * f; next (f, argv);)
                {
                        if (!opts.source (f))
                        {
@@ -442,7 +441,7 @@ yy135:
 yy137:
        ++YYCURSOR;
        if ((yych = *YYCURSOR) <= 0x00) goto yy155;
-       { *argv = YYCURSOR;   goto opt_output; }
+       { *argv = YYCURSOR;                                                             goto opt_output; }
 yy139:
        ++YYCURSOR;
        { opts.reusable ();         goto opt_short; }
@@ -452,7 +451,7 @@ yy141:
 yy143:
        ++YYCURSOR;
        if ((yych = *YYCURSOR) <= 0x00) goto yy153;
-       { *argv = YYCURSOR;   goto opt_header; }
+       { *argv = YYCURSOR;                                                                  goto opt_header; }
 yy145:
        ++YYCURSOR;
        { if (!opts.unicode ())    { error_encoding (); return EXIT_FAIL; } goto opt_short; }
@@ -467,10 +466,10 @@ yy151:
        { if (!opts.utf_16 ())     { error_encoding (); return EXIT_FAIL; } goto opt_short; }
 yy153:
        ++YYCURSOR;
-       { YYCURSOR = *++argv; goto opt_header; }
+       { if (!next (YYCURSOR, argv)) { error_arg ("-t, --type-header"); return EXIT_FAIL; } goto opt_header; }
 yy155:
        ++YYCURSOR;
-       { YYCURSOR = *++argv; goto opt_output; }
+       { if (!next (YYCURSOR, argv)) { error_arg ("-o, --output"); return EXIT_FAIL; } goto opt_output; }
 }
 
 
@@ -693,7 +692,7 @@ yy219:
        yych = *++YYCURSOR;
        if (yych >= 0x01) goto yy177;
        ++YYCURSOR;
-       { YYCURSOR = *++argv; goto opt_header; }
+       { if (!next (YYCURSOR, argv)) { error_arg ("-t, --type-header"); return EXIT_FAIL; } goto opt_header; }
 yy231:
        yych = *++YYCURSOR;
        if (yych == 'n') goto yy272;
@@ -832,7 +831,7 @@ yy292:
        yych = *++YYCURSOR;
        if (yych >= 0x01) goto yy177;
        ++YYCURSOR;
-       { YYCURSOR = *++argv; goto opt_output; }
+       { if (!next (YYCURSOR, argv)) { error_arg ("-o, --output"); return EXIT_FAIL; } goto opt_output; }
 yy299:
        yych = *++YYCURSOR;
        if (yych == '-') goto yy311;
@@ -1303,7 +1302,11 @@ yy484:
 
 
 opt_encoding_policy:
-       YYCURSOR = *++argv;
+       if (!next (YYCURSOR, argv))
+       {
+               error_arg ("--encoding-policy");
+               return EXIT_FAIL;
+       }
 
 {
        YYCTYPE yych;
@@ -1381,7 +1384,11 @@ yy513:
 
 
 opt_input:
-       YYCURSOR = *++argv;
+       if (!next (YYCURSOR, argv))
+       {
+               error_arg ("--input");
+               return EXIT_FAIL;
+       }
 
 {
        YYCTYPE yych;
@@ -1438,7 +1445,11 @@ yy533:
 
 
 opt_empty_class:
-       YYCURSOR = *++argv;
+       if (!next (YYCURSOR, argv))
+       {
+               error_arg ("--empty-class");
+               return EXIT_FAIL;
+       }
 
 {
        YYCTYPE yych;
index a69ac45944c79f8234abea5491b38a65dfbbd21f..ca89cce655ab05d5f261002e602f41079d523311 100644 (file)
@@ -24,6 +24,11 @@ void error_encoding ()
        error ("only one of switches -e, -w, -x, -u and -8 must be set");
 }
 
+void error_arg (const char * option)
+{
+       error ("expected argument to option %s", option);
+}
+
 void warning (const char * type, uint32_t line, bool error, const char * fmt, ...)
 {
        static const char * msg = error ? "error" : "warning";
index 1034131fa5bee972752c84b6d88fdecb9ecdf1e2..f3397d7cab6f25638f372ddeb504f147793c64b2 100644 (file)
@@ -8,6 +8,7 @@ namespace re2c {
 
 void error (const char * fmt, ...) RE2C_GXX_ATTRIBUTE ((format (printf, 1, 2)));
 void error_encoding ();
+void error_arg (const char * option);
 void warning (const char * type, uint32_t line, bool error, const char * fmt, ...) RE2C_GXX_ATTRIBUTE ((format (printf, 4, 5)));
 void usage ();
 void vernum ();
index 95409a6eb92e7251bcb3fe2e710fdd36013f85a3..2c5952919952ef2f2a410220e44b5c0005b11e04 100644 (file)
@@ -57,7 +57,7 @@ enum parse_opts_t
        EXIT_FAIL
 };
 
-parse_opts_t parse_opts (int argc, char ** argv, Opt & opts);
+parse_opts_t parse_opts (char ** argv, Opt & opts);
 
 } // namespace re2c
 
index b3bddb611cdab408b81a996e800175c7b8f3b4ca..b0ab34f0c2d93bbe8ba7ab428cb4156ad8ab08e5 100644 (file)
@@ -6,14 +6,14 @@
 namespace re2c
 {
 
-parse_opts_t parse_opts (int argc, char ** argv, Opt & opts)
+static inline bool next (char * & arg, char ** & argv)
 {
-       if (argc == 1)
-       {
-               usage ();
-               return EXIT_FAIL;
-       }
+       arg = *++argv;
+       return arg != NULL;
+}
 
+parse_opts_t parse_opts (char ** argv, Opt & opts)
+{
 #define YYCTYPE char
        YYCTYPE * YYCURSOR;
        YYCTYPE * YYMARKER;
@@ -27,8 +27,7 @@ parse_opts_t parse_opts (int argc, char ** argv, Opt & opts)
 */
 
 opt:
-       YYCURSOR = *++argv;
-       if (YYCURSOR == NULL)
+       if (!next (YYCURSOR, argv))
        {
                goto end;
        }
@@ -44,7 +43,7 @@ opt:
                // all remaining arguments are non-options
                // so they must be input files
                // re2c expects exactly one input file
-               for (const char * f = *++argv; f; f = *++argv)
+               for (char * f; next (f, argv);)
                {
                        if (!opts.source (f))
                        {
@@ -106,10 +105,10 @@ opt_short:
        "w" { if (!opts.wide_chars ()) { error_encoding (); return EXIT_FAIL; } goto opt_short; }
        "x" { if (!opts.utf_16 ())     { error_encoding (); return EXIT_FAIL; } goto opt_short; }
        "8" { if (!opts.utf_8 ())      { error_encoding (); return EXIT_FAIL; } goto opt_short; }
-       "o" end { YYCURSOR = *++argv; goto opt_output; }
-       "o"     { *argv = YYCURSOR;   goto opt_output; }
-       "t" end { YYCURSOR = *++argv; goto opt_header; }
-       "t"     { *argv = YYCURSOR;   goto opt_header; }
+       "o" end { if (!next (YYCURSOR, argv)) { error_arg ("-o, --output"); return EXIT_FAIL; } goto opt_output; }
+       "o"     { *argv = YYCURSOR;                                                             goto opt_output; }
+       "t" end { if (!next (YYCURSOR, argv)) { error_arg ("-t, --type-header"); return EXIT_FAIL; } goto opt_header; }
+       "t"     { *argv = YYCURSOR;                                                                  goto opt_header; }
        "1" { goto opt_short; } // deprecated
 */
 
@@ -142,8 +141,8 @@ opt_long:
        "wide-chars"         end { if (!opts.wide_chars ()) { error_encoding (); return EXIT_FAIL; } goto opt; }
        "utf-16"             end { if (!opts.utf_16 ())     { error_encoding (); return EXIT_FAIL; } goto opt; }
        "utf-8"              end { if (!opts.utf_8 ())      { error_encoding (); return EXIT_FAIL; } goto opt; }
-       "output"             end { YYCURSOR = *++argv; goto opt_output; }
-       "type-header"        end { YYCURSOR = *++argv; goto opt_header; }
+       "output"             end { if (!next (YYCURSOR, argv)) { error_arg ("-o, --output"); return EXIT_FAIL; } goto opt_output; }
+       "type-header"        end { if (!next (YYCURSOR, argv)) { error_arg ("-t, --type-header"); return EXIT_FAIL; } goto opt_header; }
        "encoding-policy"    end { goto opt_encoding_policy; }
        "input"              end { goto opt_input; }
        "empty-class"        end { goto opt_empty_class; }
@@ -171,7 +170,11 @@ opt_header:
 */
 
 opt_encoding_policy:
-       YYCURSOR = *++argv;
+       if (!next (YYCURSOR, argv))
+       {
+               error_arg ("--encoding-policy");
+               return EXIT_FAIL;
+       }
 /*!re2c
        *
        {
@@ -184,7 +187,11 @@ opt_encoding_policy:
 */
 
 opt_input:
-       YYCURSOR = *++argv;
+       if (!next (YYCURSOR, argv))
+       {
+               error_arg ("--input");
+               return EXIT_FAIL;
+       }
 /*!re2c
        *
        {
@@ -196,7 +203,11 @@ opt_input:
 */
 
 opt_empty_class:
-       YYCURSOR = *++argv;
+       if (!next (YYCURSOR, argv))
+       {
+               error_arg ("--empty-class");
+               return EXIT_FAIL;
+       }
 /*!re2c
        *
        {
index e82803d368e1f08308637f650d979ee428ce51ba..78cbe78f0fd5aba899be1e2b721a431640929f56 100644 (file)
@@ -18,10 +18,10 @@ free_list<RegExp*> RegExp::vFreeList;
 
 using namespace re2c;
 
-int main(int argc, char *argv[])
+int main(int, char *argv[])
 {
        Opt opts;
-       switch (parse_opts (argc, argv, opts))
+       switch (parse_opts (argv, opts))
        {
                case OK:        break;
                case EXIT_OK:   return 0;