lexer: Avoid reentering the lexer upon error in special cases.
[pspp] / tests / language / lexer / lexer.at
1 dnl PSPP - a program for statistical analysis.
2 dnl Copyright (C) 2017 Free Software Foundation, Inc.
3 dnl
4 dnl This program is free software: you can redistribute it and/or modify
5 dnl it under the terms of the GNU General Public License as published by
6 dnl the Free Software Foundation, either version 3 of the License, or
7 dnl (at your option) any later version.
8 dnl
9 dnl This program is distributed in the hope that it will be useful,
10 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
11 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 dnl GNU General Public License for more details.
13 dnl
14 dnl You should have received a copy of the GNU General Public License
15 dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 dnl
17 AT_BANNER([lexer])
18
19 AT_SETUP([lexer ignores initial @%:@! line])
20 AT_DATA([lexer.sps], [dnl
21 #! /usr/local/bin/pspp
22 DATA LIST LIST NOTABLE /a.
23 BEGIN DATA.
24 1
25 2
26 END DATA.
27 LIST.
28 ])
29 AT_CHECK([pspp -o pspp.csv lexer.sps])
30 AT_CHECK([cat pspp.csv], [0], [dnl
31 Table: Data List
32 a
33 1.00
34 2.00
35 ])
36 AT_CLEANUP
37
38 AT_SETUP([lexer properly reports scan errors])
39 AT_DATA([lexer.sps], [dnl
40 x'123'
41 x'1x'
42 u''
43 u'012345678'
44 u'd800'
45 u'110000'
46 'foo
47 'very long unterminated string that be ellipsized in its error message
48 1e .x
49 ^
50
51 ])
52 AT_CHECK([pspp -O format=csv lexer.sps], [1], [dnl
53 "lexer.sps:1.1-1.6: error: String of hex digits has 3 characters, which is not a multiple of 2.
54     1 | x'123'
55       | ^~~~~~"
56
57 "lexer.sps:2.1-2.5: error: `x' is not a valid hex digit.
58     2 | x'1x'
59       | ^~~~~"
60
61 "lexer.sps:3.1-3.3: error: Unicode string contains 0 bytes, which is not in the valid range of 1 to 8 bytes.
62     3 | u''
63       | ^~~"
64
65 "lexer.sps:4.1-4.12: error: Unicode string contains 9 bytes, which is not in the valid range of 1 to 8 bytes.
66     4 | u'012345678'
67       | ^~~~~~~~~~~~"
68
69 "lexer.sps:5.1-5.7: error: U+D800 is not a valid Unicode code point.
70     5 | u'd800'
71       | ^~~~~~~"
72
73 "lexer.sps:6.1-6.9: error: U+110000 is not a valid Unicode code point.
74     6 | u'110000'
75       | ^~~~~~~~~"
76
77 "lexer.sps:7.1-7.4: error: Unterminated string constant.
78     7 | 'foo
79       | ^~~~"
80
81 "lexer.sps:8.1-8.70: error: Unterminated string constant.
82     8 | 'very long unterminated string that be ellipsized in its error message
83       | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
84
85 "lexer.sps:9.1-9.2: error: Missing exponent following `1e'.
86     9 | 1e .x
87       | ^~"
88
89 "lexer.sps:9.4: error: Syntax error expecting command name.
90     9 | 1e .x
91       |    ^"
92
93 "lexer.sps:10.1: error: Bad character `^' in input.
94    10 | ^
95       | ^"
96
97 "lexer.sps:11.1-11.2: error: Bad character U+FFFD in input.
98    11 | �
99       | ^~"
100 ])
101 AT_CLEANUP
102
103 # Bug #47602.
104 AT_SETUP([lexer crash due to null byte])
105 # Intentionally leave out the new-line and add a null byte:
106 printf "datA dist list notable file='input.txt'/a b c.
107 lis|.\0" > lexer.sps
108
109 AT_CHECK([pspp -O format=csv lexer.sps], [1], [dnl
110 "lexer.sps:1.1-1.9: error: Unknown command `datA dist'.
111     1 | datA dist list notable file='input.txt'/a b c.
112       | ^~~~~~~~~"
113
114 "lexer.sps:2.1-2.3: error: LIST: LIST is allowed only after the active dataset has been defined.
115     2 | lis|."
116
117 "lexer.sps:2.6: error: LIST: Bad character U+0000 in input.
118     2 | lis|."
119 ])
120 AT_CLEANUP
121
122
123
124
125 # Bug #54684
126 AT_SETUP([lexer crash due to overflow])
127 printf "DATA LIST/5555555555555555." > lexer.sps
128
129 AT_CHECK([pspp -O format=csv lexer.sps], [1], [dnl
130 "lexer.sps:1.11-1.26: error: DATA LIST: Syntax error expecting integer between 1 and 2147483647.
131     1 | DATA LIST/5555555555555555.
132       |           ^~~~~~~~~~~~~~~~"
133 ])
134
135 AT_CLEANUP
136
137 AT_SETUP([lexer crash due to reentrancy in error processing])
138 dnl ^ is an invalid character in input that triggers an error message.
139 dnl 100 of them, as shown below, exceeds the 100-error limit.  The
140 dnl minus sign causes the lexer to look ahead for a number, and then
141 dnl the ^ encountered afterward causes an error too, and then the
142 dnl message emission handler might reenter the lexer looking for a
143 dnl location, which can then cause the lexer to try to get a token
144 dnl again.  It's a whole mess and the new way of avoiding reentrancy
145 dnl by keeping a collection of messages to emit until we've almost
146 dnl returned to the top level is much less prone to error.
147 AT_DATA([lexer.sps], [dnl
148 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^
149 ])
150 AT_CHECK([pspp lexer.sps], [1], [ignore])
151 AT_CLEANUP