5
5
*/
6
6
"use strict" ;
7
7
8
+ const newline = [ "\n" , "\r" ] ;
9
+ const valid_after_heredoc = [ "\n" , "\r" , ";" ] ;
10
+ const valid_after_heredoc_73 = valid_after_heredoc . concat ( [
11
+ "\t" ,
12
+ " " ,
13
+ "," ,
14
+ "]" ,
15
+ ")" ,
16
+ "/" ,
17
+ "=" ,
18
+ "!"
19
+ ] ) ;
20
+
8
21
module . exports = {
9
22
T_CONSTANT_ENCAPSED_STRING : function ( ) {
10
23
let ch ;
@@ -60,13 +73,11 @@ module.exports = {
60
73
// required ending quote
61
74
if ( tChar ) this . offset ++ ;
62
75
// require newline
63
- if (
64
- this . _input [ this . offset - 1 ] === "\r" ||
65
- this . _input [ this . offset - 1 ] === "\n"
66
- ) {
76
+ if ( newline . includes ( this . _input [ this . offset - 1 ] ) ) {
67
77
// go go go
68
78
this . heredoc_label . label = yylabel ;
69
79
this . heredoc_label . length = yylabel . length ;
80
+ this . heredoc_label . finished = false ;
70
81
yyoffset = this . offset - revert ;
71
82
this . offset = revert ;
72
83
this . consume ( yyoffset ) ;
@@ -135,8 +146,8 @@ module.exports = {
135
146
// consumeLeadingSpaces is false happen DOC prematch END HEREDOC stage.
136
147
137
148
// Ensure current state is really after a new line break, not after a such as ${variables}
138
- const prev_ch = this . _input . substring ( offset - 2 , offset - 1 ) ;
139
- if ( prev_ch !== "\n" && prev_ch !== "\r" ) {
149
+ const prev_ch = this . _input [ offset - 2 ] ;
150
+ if ( ! newline . includes ( prev_ch ) ) {
140
151
return false ;
141
152
}
142
153
@@ -145,21 +156,28 @@ module.exports = {
145
156
let indentation_uses_tabs = false ;
146
157
// reset heredoc_label structure
147
158
let indentation = 0 ;
148
- let leading_ch = this . _input . substring ( offset - 1 , offset ) ;
159
+ let leading_ch = this . _input [ offset - 1 ] ;
160
+
161
+ if ( this . version >= 703 ) {
162
+ while ( leading_ch === "\t" || leading_ch === " " ) {
163
+ if ( leading_ch === " " ) {
164
+ indentation_uses_spaces = true ;
165
+ } else if ( leading_ch === "\t" ) {
166
+ indentation_uses_tabs = true ;
167
+ }
149
168
150
- while ( leading_ch === "\t" || leading_ch === " " ) {
151
- if ( leading_ch === " " ) {
152
- indentation_uses_spaces = true ;
153
- } else if ( leading_ch === "\t" ) {
154
- indentation_uses_tabs = true ;
169
+ leading_ch = this . _input [ offset + indentation ] ;
170
+ indentation ++ ;
155
171
}
156
172
157
- leading_ch = this . _input [ offset + indentation ] ;
158
- indentation ++ ;
159
- }
173
+ // Move offset to skip leading whitespace
174
+ offset = offset + indentation ;
160
175
161
- // Move offset to skip leading whitespace
162
- offset = offset + indentation ;
176
+ // return out if there was only whitespace on this line
177
+ if ( newline . includes ( this . _input [ offset - 1 ] ) ) {
178
+ return false ;
179
+ }
180
+ }
163
181
164
182
if (
165
183
this . _input . substring (
@@ -168,7 +186,12 @@ module.exports = {
168
186
) === this . heredoc_label . label
169
187
) {
170
188
const ch = this . _input [ offset - 1 + this . heredoc_label . length ] ;
171
- if ( ch === "\n" || ch === "\r" || ch === ";" ) {
189
+ if (
190
+ ( this . version >= 703
191
+ ? valid_after_heredoc_73
192
+ : valid_after_heredoc
193
+ ) . includes ( ch )
194
+ ) {
172
195
if ( consumeLeadingSpaces ) {
173
196
this . consume ( indentation ) ;
174
197
// https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes
@@ -211,9 +234,14 @@ module.exports = {
211
234
return ;
212
235
}
213
236
214
- // skip one line
215
- while ( this . _input [ offset ++ ] !== "\n" && offset < this . _input . length ) {
216
- // skip
237
+ if ( ! newline . includes ( this . _input [ offset - 1 ] ) ) {
238
+ // skip one line
239
+ while (
240
+ ! newline . includes ( this . _input [ offset ++ ] ) &&
241
+ offset < this . _input . length
242
+ ) {
243
+ // skip
244
+ }
217
245
}
218
246
219
247
offset ++ ;
@@ -231,7 +259,7 @@ module.exports = {
231
259
/** SCANNING CONTENTS **/
232
260
let ch = this . _input [ this . offset - 1 ] ;
233
261
while ( this . offset < this . size ) {
234
- if ( ch === "\n" || ch === "\r" ) {
262
+ if ( newline . includes ( ch ) ) {
235
263
ch = this . input ( ) ;
236
264
if ( this . isDOC_MATCH ( this . offset , true ) ) {
237
265
this . unput ( 1 ) . popState ( ) ;
@@ -258,12 +286,12 @@ module.exports = {
258
286
while ( this . offset < this . size ) {
259
287
if ( ch === "\\" ) {
260
288
ch = this . input ( ) ; // ignore next
261
- if ( ch !== "\n" && ch !== "\r" ) {
289
+ if ( ! newline . includes ( ch ) ) {
262
290
ch = this . input ( ) ;
263
291
}
264
292
}
265
293
266
- if ( ch === "\n" || ch === "\r" ) {
294
+ if ( newline . includes ( ch ) ) {
267
295
ch = this . input ( ) ;
268
296
if ( this . isDOC_MATCH ( this . offset , true ) ) {
269
297
this . unput ( 1 ) . popState ( ) ;
0 commit comments