diff --git a/THANKS b/THANKS index a016b287..0b3f6faf 100644 --- a/THANKS +++ b/THANKS @@ -131,6 +131,7 @@ Michael Catanzaro mcatanzaro@gnome.org Michael Felt mamfelt@gmail.com Michael Hayes m.hayes@elec.canterbury.ac.nz Michael Raskin 7c6f434c@mail.ru +MichaƂ Majchrowicz mmajchrowicz@afine.com Michel d'Hooge michel.dhooge@gmail.com Michiel De Wilde mdewilde.agilent@gmail.com Mickael Labau labau_m@epita.fr diff --git a/doc/bison.texi b/doc/bison.texi index a72fdd6d..53d14e22 100644 --- a/doc/bison.texi +++ b/doc/bison.texi @@ -6026,6 +6026,7 @@ Introduced in Bison 3.8. @deffn {Directive} %header @var{header-file} Same as above, but save in the file @file{@var{header-file}}. +The @var{header-file} name should not contain slashes. @end deffn @deffn {Directive} %language "@var{language}" @@ -6079,6 +6080,7 @@ file, treating it as an independent source file in its own right. @deffn {Directive} %output "@var{file}" Generate the parser implementation in @file{@var{file}}. +The @var{file} name should not contain slashes. @end deffn @deffn {Directive} %pure-parser diff --git a/src/parse-gram.c b/src/parse-gram.c index 9ebc1c41..14ddf5e8 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -1,9 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.8.2.30-82269. */ +/* A Bison parser, made by GNU Bison 3.8.2.66-3169-modified. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2022, 2025-2026 Free - Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2022, 2025-2026 Free Software + Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -49,7 +49,7 @@ #define YYBISON 30802 /* Bison version string. */ -#define YYBISON_VERSION "3.8.2.30-82269" +#define YYBISON_VERSION "3.8.2.66-3169-modified" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -273,8 +273,11 @@ typedef enum yysymbol_kind_t yysymbol_kind_t; string from the scanner (should be CODE). */ static char const *translate_code_braceless (char *code, location loc); + /* Is FILE a valid output file name? */ + static bool valid_output_file_name (char const *file); + /* Handle a %header directive. */ - static void handle_header (char const *value); + static void handle_header (location const *loc, char const *value); /* Handle a %error-verbose directive. */ static void handle_error_verbose (location const *loc, char const *directive); @@ -658,19 +661,19 @@ union yyalloc /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 310, 310, 319, 320, 324, 325, 331, 335, 340, - 341, 342, 343, 344, 345, 350, 355, 356, 357, 358, - 359, 360, 360, 361, 362, 363, 364, 365, 366, 367, - 368, 372, 373, 382, 383, 387, 398, 402, 406, 414, - 424, 425, 435, 436, 442, 455, 455, 460, 460, 465, - 465, 470, 480, 481, 482, 483, 488, 489, 493, 494, - 499, 500, 504, 505, 509, 510, 511, 524, 533, 537, - 541, 549, 550, 554, 567, 568, 573, 574, 575, 593, - 597, 601, 609, 611, 616, 623, 633, 637, 641, 649, - 655, 668, 669, 675, 676, 677, 684, 684, 692, 693, - 694, 699, 702, 704, 706, 708, 710, 712, 714, 716, - 718, 723, 724, 733, 757, 758, 759, 760, 772, 774, - 798, 803, 804, 809, 817, 818 + 0, 314, 314, 323, 324, 328, 329, 335, 339, 344, + 345, 346, 347, 348, 349, 354, 359, 360, 361, 362, + 363, 372, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 384, 385, 394, 395, 399, 410, 414, 418, 426, + 436, 437, 447, 448, 454, 467, 467, 472, 472, 477, + 477, 482, 492, 493, 494, 495, 500, 501, 505, 506, + 511, 512, 516, 517, 521, 522, 523, 536, 545, 549, + 553, 561, 562, 566, 579, 580, 585, 586, 587, 605, + 609, 613, 621, 623, 628, 635, 645, 649, 653, 661, + 667, 680, 681, 687, 688, 689, 696, 696, 704, 705, + 706, 711, 714, 716, 718, 720, 722, 724, 726, 728, + 730, 735, 736, 745, 769, 770, 771, 772, 784, 786, + 810, 815, 816, 821, 829, 830 }; #endif @@ -2099,7 +2102,7 @@ yyreduce: break; case 9: /* prologue_declaration: "%header" string.opt */ - { handle_header ((yyvsp[0].yykind_75)); } + { handle_header (&(yylsp[0]), (yyvsp[0].yykind_75)); } break; case 10: /* prologue_declaration: "%error-verbose" */ @@ -2149,7 +2152,14 @@ yyreduce: break; case 20: /* prologue_declaration: "%output" "string" */ - { spec_outfile = unquote ((yyvsp[0].STRING)); gram_scanner_last_string_free (); } + { + char *file = unquote ((yyvsp[0].STRING)); + if (valid_output_file_name (file)) + spec_outfile = file; + else + complain (&(yylsp[0]), complaint, _("invalid %%output file name ignored")); + gram_scanner_last_string_free (); + } break; case 21: /* $@1: %empty */ @@ -2969,14 +2979,24 @@ add_param (param_type type, char *decl, location loc) } +static bool +valid_output_file_name (char const *file) +{ + return !strchr (file, '/'); +} + + static void -handle_header (char const *value) +handle_header (location const *loc, char const *value) { header_flag = true; if (value) { char *file = unquote (value); - spec_header_file = xstrdup (file); + if (valid_output_file_name (file)) + spec_header_file = xstrdup (file); + else + complain (loc, complaint, _("invalid %%header file name ignored")); gram_scanner_last_string_free (); unquote_free (file); } diff --git a/src/parse-gram.h b/src/parse-gram.h index 5170e08c..9c21d190 100644 --- a/src/parse-gram.h +++ b/src/parse-gram.h @@ -1,9 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.8.2.30-82269. */ +/* A Bison parser, made by GNU Bison 3.8.2.66-3169-modified. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2022 Free Software Foundation, - Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2022, 2025-2026 Free Software + Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/parse-gram.y b/src/parse-gram.y index d38b16cd..a775339e 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -96,8 +96,11 @@ string from the scanner (should be CODE). */ static char const *translate_code_braceless (char *code, location loc); + /* Is FILE a valid output file name? */ + static bool valid_output_file_name (char const *file); + /* Handle a %header directive. */ - static void handle_header (char const *value); + static void handle_header (location const *loc, char const *value); /* Handle a %error-verbose directive. */ static void handle_error_verbose (location const *loc, char const *directive); @@ -338,7 +341,7 @@ prologue_declaration: muscle_percent_define_insert ($2, @$, $3.kind, $3.chars, MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); } -| "%header" string.opt { handle_header ($2); } +| "%header" string.opt { handle_header (&@2, $2); } | "%error-verbose" { handle_error_verbose (&@$, $1); } | "%expect" INT_LITERAL { expected_sr_conflicts = $2; } | "%expect-rr" INT_LITERAL { expected_rr_conflicts = $2; } @@ -357,7 +360,15 @@ prologue_declaration: | "%name-prefix" STRING { handle_name_prefix (&@$, $1, $2); } | "%no-lines" { no_lines_flag = true; } | "%nondeterministic-parser" { nondeterministic_parser = true; } -| "%output" STRING { spec_outfile = unquote ($2); gram_scanner_last_string_free (); } +| "%output" STRING + { + char *file = unquote ($2); + if (valid_output_file_name (file)) + spec_outfile = file; + else + complain (&@2, complaint, _("invalid %%output file name ignored")); + gram_scanner_last_string_free (); + } | "%param" { current_param = $1; } params { current_param = param_none; } | "%pure-parser" { handle_pure_parser (&@$, $1); } | "%require" STRING { handle_require (&@2, $2); } @@ -953,14 +964,24 @@ add_param (param_type type, char *decl, location loc) } +static bool +valid_output_file_name (char const *file) +{ + return !strchr (file, '/'); +} + + static void -handle_header (char const *value) +handle_header (location const *loc, char const *value) { header_flag = true; if (value) { char *file = unquote (value); - spec_header_file = xstrdup (file); + if (valid_output_file_name (file)) + spec_header_file = xstrdup (file); + else + complain (loc, complaint, _("invalid %%header file name ignored")); gram_scanner_last_string_free (); unquote_free (file); }