mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-18 16:53:02 +00:00
scanner: don't crash on strings containing a NUL byte
We crash if the input contains a string containing a NUL byte. Reported by Suhwan Song. https://lists.gnu.org/r/bug-bison/2020-07/msg00051.html * src/flex-scanner.h (STRING_FREE): Avoid accidental use of last_string. * src/scan-gram.l: Don't call STRING_FREE without calling STRING_FINISH first. * tests/input.at (Invalid inputs): Check that case.
This commit is contained in:
1
THANKS
1
THANKS
@@ -185,6 +185,7 @@ Simon Sobisch simonsobisch@web.de
|
|||||||
Stefano Lattarini stefano.lattarini@gmail.com
|
Stefano Lattarini stefano.lattarini@gmail.com
|
||||||
Stephen Cameron stephenmcameron@gmail.com
|
Stephen Cameron stephenmcameron@gmail.com
|
||||||
Steve Murphy murf@parsetree.com
|
Steve Murphy murf@parsetree.com
|
||||||
|
Suhwan Song prada960808@gmail.com
|
||||||
Sum Wu sum@geekhouse.org
|
Sum Wu sum@geekhouse.org
|
||||||
Théophile Ranquet theophile.ranquet@gmail.com
|
Théophile Ranquet theophile.ranquet@gmail.com
|
||||||
Thiru Ramakrishnan thiru.ramakrishnan@gmail.com
|
Thiru Ramakrishnan thiru.ramakrishnan@gmail.com
|
||||||
|
|||||||
@@ -112,7 +112,15 @@ static struct obstack obstack_for_string;
|
|||||||
# define STRING_1GROW(Char) \
|
# define STRING_1GROW(Char) \
|
||||||
obstack_1grow (&obstack_for_string, Char)
|
obstack_1grow (&obstack_for_string, Char)
|
||||||
|
|
||||||
# define STRING_FREE() \
|
# ifdef NDEBUG
|
||||||
|
# define STRING_FREE() \
|
||||||
obstack_free (&obstack_for_string, last_string)
|
obstack_free (&obstack_for_string, last_string)
|
||||||
|
# else
|
||||||
|
# define STRING_FREE() \
|
||||||
|
do { \
|
||||||
|
obstack_free (&obstack_for_string, last_string); \
|
||||||
|
last_string = NULL; \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -403,6 +403,7 @@ eqopt ({sp}=)?
|
|||||||
{
|
{
|
||||||
\0 {
|
\0 {
|
||||||
complain (loc, complaint, _("invalid null character"));
|
complain (loc, complaint, _("invalid null character"));
|
||||||
|
STRING_FINISH ();
|
||||||
STRING_FREE ();
|
STRING_FREE ();
|
||||||
return GRAM_error;
|
return GRAM_error;
|
||||||
}
|
}
|
||||||
@@ -599,7 +600,6 @@ eqopt ({sp}=)?
|
|||||||
STRING_FINISH ();
|
STRING_FINISH ();
|
||||||
BEGIN INITIAL;
|
BEGIN INITIAL;
|
||||||
loc->start = token_start;
|
loc->start = token_start;
|
||||||
val->CHAR = last_string[0];
|
|
||||||
|
|
||||||
if (last_string[0] == '\0')
|
if (last_string[0] == '\0')
|
||||||
{
|
{
|
||||||
@@ -615,6 +615,7 @@ eqopt ({sp}=)?
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
val->CHAR = last_string[0];
|
||||||
STRING_FREE ();
|
STRING_FREE ();
|
||||||
return CHAR;
|
return CHAR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Checking the Bison scanner. -*- Autotest -*-
|
# Checking the Bison reader. -*- Autotest -*-
|
||||||
|
|
||||||
# Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
|
# Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
@@ -78,10 +78,13 @@ AT_CLEANUP
|
|||||||
## Invalid inputs. ##
|
## Invalid inputs. ##
|
||||||
## ---------------- ##
|
## ---------------- ##
|
||||||
|
|
||||||
|
# The truly bad guys no human would write, but easily uncovered by
|
||||||
|
# fuzzers.
|
||||||
AT_SETUP([Invalid inputs])
|
AT_SETUP([Invalid inputs])
|
||||||
|
|
||||||
AT_DATA([input.y],
|
AT_DATA([input.y],
|
||||||
[[\000\001\002\377?
|
[[\000\001\002\377?
|
||||||
|
"\000"
|
||||||
%%
|
%%
|
||||||
?
|
?
|
||||||
default: 'a' }
|
default: 'a' }
|
||||||
@@ -92,16 +95,41 @@ default: 'a' }
|
|||||||
]])
|
]])
|
||||||
AT_PERL_REQUIRE([[-pi -e 's/\\(\d{3})/chr(oct($1))/ge' input.y]])
|
AT_PERL_REQUIRE([[-pi -e 's/\\(\d{3})/chr(oct($1))/ge' input.y]])
|
||||||
|
|
||||||
AT_BISON_CHECK([input.y], [1], [],
|
AT_BISON_CHECK([-fcaret input.y], [1], [], [stderr])
|
||||||
|
|
||||||
|
# Autotest's diffing, when there are NUL bytes, just reports "binary
|
||||||
|
# files differ". So don't leave NUL bytes.
|
||||||
|
AT_PERL_CHECK([[-p -e 's{([\0\377])}{sprintf "\\x%02x", ord($1)}ge' stderr]], [],
|
||||||
[[input.y:1.1-2: error: invalid characters: '\0\001\002\377?'
|
[[input.y:1.1-2: error: invalid characters: '\0\001\002\377?'
|
||||||
input.y:3.1: error: invalid character: '?'
|
1 | \x00\xff?
|
||||||
input.y:4.14: error: invalid character: '}'
|
| ^~
|
||||||
input.y:5.1: error: invalid character: '%'
|
input.y:2.2: error: invalid null character
|
||||||
input.y:5.2: error: invalid character: '&'
|
2 | "\x00"
|
||||||
input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
|
| ^
|
||||||
input.y:7.1: error: invalid character: '%'
|
input.y:4.1: error: invalid character: '?'
|
||||||
input.y:7.2: error: invalid character: '-'
|
4 | ?
|
||||||
input.y:8.1-9.0: error: missing '%}' at end of file
|
| ^
|
||||||
|
input.y:5.14: error: invalid character: '}'
|
||||||
|
5 | default: 'a' }
|
||||||
|
| ^
|
||||||
|
input.y:6.1: error: invalid character: '%'
|
||||||
|
6 | %&
|
||||||
|
| ^
|
||||||
|
input.y:6.2: error: invalid character: '&'
|
||||||
|
6 | %&
|
||||||
|
| ^
|
||||||
|
input.y:7.1-17: error: invalid directive: '%a-does-not-exist'
|
||||||
|
7 | %a-does-not-exist
|
||||||
|
| ^~~~~~~~~~~~~~~~~
|
||||||
|
input.y:8.1: error: invalid character: '%'
|
||||||
|
8 | %-
|
||||||
|
| ^
|
||||||
|
input.y:8.2: error: invalid character: '-'
|
||||||
|
8 | %-
|
||||||
|
| ^
|
||||||
|
input.y:9.1-10.0: error: missing '%}' at end of file
|
||||||
|
9 | %{
|
||||||
|
| ^~
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|||||||
Reference in New Issue
Block a user