Skip to content
1 change: 1 addition & 0 deletions src/lexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ lexer.prototype.setInput = function(input) {
length: 0,
indentation: 0,
indentation_uses_spaces: false,
finished: false,
/**
* this used for parser to detemine the if current node segment is first encaps node.
* if ture, the indentation will remove from the begining. and if false, the prev node
Expand Down
48 changes: 32 additions & 16 deletions src/lexer/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ module.exports = {
// go go go
this.heredoc_label.label = yylabel;
this.heredoc_label.length = yylabel.length;
this.heredoc_label.finished = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

yyoffset = this.offset - revert;
this.offset = revert;
this.consume(yyoffset);
Expand Down Expand Up @@ -135,7 +136,7 @@ module.exports = {
// consumeLeadingSpaces is false happen DOC prematch END HEREDOC stage.

// Ensure current state is really after a new line break, not after a such as ${variables}
const prev_ch = this._input.substring(offset - 2, offset - 1);
const prev_ch = this._input[offset - 2];
if (prev_ch !== "\n" && prev_ch !== "\r") {
return false;
}
Expand All @@ -145,21 +146,34 @@ module.exports = {
let indentation_uses_tabs = false;
// reset heredoc_label structure
let indentation = 0;
let leading_ch = this._input.substring(offset - 1, offset);
let leading_ch = this._input[offset - 1];
let valid_endings = ["\n", "\r", ";"];

while (leading_ch === "\t" || leading_ch === " ") {
if (leading_ch === " ") {
indentation_uses_spaces = true;
} else if (leading_ch === "\t") {
indentation_uses_tabs = true;
if (this.version >= 703) {
valid_endings = valid_endings.concat(["\t", " ", ",", ")", "]"]);

while (leading_ch === "\t" || leading_ch === " ") {
if (leading_ch === " ") {
indentation_uses_spaces = true;
} else if (leading_ch === "\t") {
indentation_uses_tabs = true;
}

leading_ch = this._input[offset + indentation];
indentation++;
}

leading_ch = this._input[offset + indentation];
indentation++;
}
// Move offset to skip leading whitespace
offset = offset + indentation;

// Move offset to skip leading whitespace
offset = offset + indentation;
// return out if there was only whitespace on this line
if (
this._input[offset - 1] === "\n" ||
this._input[offset - 1] === "\r"
) {
return false;
}
}

if (
this._input.substring(
Expand All @@ -168,7 +182,7 @@ module.exports = {
) === this.heredoc_label.label
) {
const ch = this._input[offset - 1 + this.heredoc_label.length];
if (ch === "\n" || ch === "\r" || ch === ";") {
if (valid_endings.includes(ch)) {
if (consumeLeadingSpaces) {
this.consume(indentation);
// https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes
Expand Down Expand Up @@ -211,9 +225,11 @@ module.exports = {
return;
}

// skip one line
while (this._input[offset++] !== "\n" && offset < this._input.length) {
// skip
if (this._input[offset - 1] !== "\n") {
// skip one line
while (this._input[offset++] !== "\n" && offset < this._input.length) {
// skip
}
}

offset++;
Expand Down
21 changes: 14 additions & 7 deletions src/parser/scalar.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,11 @@ module.exports = {
inCoutingState = false;
}

if (inCheckState && leadingWhitespaceCharCount < indentation) {
if (
text[offset] !== "\n" &&
inCheckState &&
leadingWhitespaceCharCount < indentation
) {
this.raiseError(
`Invalid body indentation level (expecting an indentation at least ${indentation})`
);
Expand Down Expand Up @@ -335,12 +339,14 @@ module.exports = {
result = result(
"string",
false,
this.remove_heredoc_leading_whitespace_chars(
this.resolve_special_chars(text, isDoubleQuote),
this.lexer.heredoc_label.indentation,
this.lexer.heredoc_label.indentation_uses_spaces,
this.lexer.heredoc_label.first_encaps_node
),
this.version >= 703 && !this.lexer.heredoc_label.finished
? this.remove_heredoc_leading_whitespace_chars(
this.resolve_special_chars(text, isDoubleQuote),
this.lexer.heredoc_label.indentation,
this.lexer.heredoc_label.indentation_uses_spaces,
this.lexer.heredoc_label.first_encaps_node
)
: text,
false,
text
);
Expand Down Expand Up @@ -467,6 +473,7 @@ module.exports = {

if (expect === this.tok.T_END_HEREDOC) {
node.label = this.lexer.heredoc_label.label;
this.lexer.heredoc_label.finished = true;
}
return node;
},
Expand Down
Loading