1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
From be95a4fe2951374676efc9454ffee8638faaf68d Mon Sep 17 00:00:00 2001
From: Akim Demaille <akim.demaille@gmail.com>
Date: Tue, 28 Jul 2020 18:51:30 +0200
Subject: 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.
---
THANKS | 1 +
src/flex-scanner.h | 10 +++++++++-
src/scan-gram.l | 3 ++-
tests/input.at | 48 ++++++++++++++++++++++++++++++++++++++----------
4 files changed, 50 insertions(+), 12 deletions(-)
diff --git a/THANKS b/THANKS
index ac073ea6..5c64da3c 100644
--- a/THANKS
+++ b/THANKS
@@ -185,6 +185,7 @@ Simon Sobisch simonsobisch@web.de
Stefano Lattarini stefano.lattarini@gmail.com
Stephen Cameron stephenmcameron@gmail.com
Steve Murphy murf@parsetree.com
+Suhwan Song prada960808@gmail.com
Sum Wu sum@geekhouse.org
Théophile Ranquet theophile.ranquet@gmail.com
Thiru Ramakrishnan thiru.ramakrishnan@gmail.com
diff --git a/src/flex-scanner.h b/src/flex-scanner.h
index 56ca7ce3..028847fd 100644
--- a/src/flex-scanner.h
+++ b/src/flex-scanner.h
@@ -112,7 +112,15 @@ static struct obstack obstack_for_string;
# define STRING_1GROW(Char) \
obstack_1grow (&obstack_for_string, Char)
-# define STRING_FREE() \
+# ifdef NDEBUG
+# define STRING_FREE() \
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
diff --git a/src/scan-gram.l b/src/scan-gram.l
index f8d85f23..ad2904ce 100644
--- a/src/scan-gram.l
+++ b/src/scan-gram.l
@@ -403,6 +403,7 @@ eqopt ({sp}=)?
{
\0 {
complain (loc, complaint, _("invalid null character"));
+ STRING_FINISH ();
STRING_FREE ();
return GRAM_error;
}
@@ -599,7 +600,6 @@ eqopt ({sp}=)?
STRING_FINISH ();
BEGIN INITIAL;
loc->start = token_start;
- val->CHAR = last_string[0];
if (last_string[0] == '\0')
{
@@ -615,6 +615,7 @@ eqopt ({sp}=)?
}
else
{
+ val->CHAR = last_string[0];
STRING_FREE ();
return CHAR;
}
diff --git a/tests/input.at b/tests/input.at
index 4da63795..effcd1cc 100644
--- a/tests/input.at
+++ b/tests/input.at
@@ -1,4 +1,4 @@
-# Checking the Bison scanner. -*- Autotest -*-
+# Checking the Bison reader. -*- Autotest -*-
# Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
@@ -78,10 +78,13 @@ AT_CLEANUP
## Invalid inputs. ##
## ---------------- ##
+# The truly bad guys no human would write, but easily uncovered by
+# fuzzers.
AT_SETUP([Invalid inputs])
AT_DATA([input.y],
[[\000\001\002\377?
+"\000"
%%
?
default: 'a' }
@@ -92,16 +95,41 @@ default: 'a' }
]])
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:3.1: error: invalid character: '?'
-input.y:4.14: error: invalid character: '}'
-input.y:5.1: error: invalid character: '%'
-input.y:5.2: error: invalid character: '&'
-input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
-input.y:7.1: error: invalid character: '%'
-input.y:7.2: error: invalid character: '-'
-input.y:8.1-9.0: error: missing '%}' at end of file
+ 1 | \x00\xff?
+ | ^~
+input.y:2.2: error: invalid null character
+ 2 | "\x00"
+ | ^
+input.y:4.1: error: invalid character: '?'
+ 4 | ?
+ | ^
+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
--
cgit v1.2.1
|