summaryrefslogtreecommitdiff
path: root/Zend/zend_language_scanner.l
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_language_scanner.l')
-rw-r--r--Zend/zend_language_scanner.l145
1 files changed, 41 insertions, 104 deletions
diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l
index cf898f3bb2..7ac4efe353 100644
--- a/Zend/zend_language_scanner.l
+++ b/Zend/zend_language_scanner.l
@@ -919,7 +919,7 @@ DOUBLE_QUOTES_CHARS ("{"*([^$"\\{]|("\\"{ANY_CHAR}))|{DOUBLE_QUOTES_LITERAL_DOLL
BACKQUOTE_CHARS ("{"*([^$`\\{]|("\\"{ANY_CHAR}))|{BACKQUOTE_LITERAL_DOLLAR})
HEREDOC_CHARS ("{"*([^$\n\r\\{]|("\\"[^\n\r]))|{HEREDOC_LITERAL_DOLLAR}|({HEREDOC_NEWLINE}+({HEREDOC_NON_LABEL}|{HEREDOC_LABEL_NO_NEWLINE})))
-NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_\x7f-\xff;\n\r][^\n\r]*)|({LABEL}[;][^\n\r]+)))
+NOWDOC_CHARS ([^\n\r]|{NEWLINE}+([^a-zA-Z_\x7f-\xff\n\r]|({LABEL}([^a-zA-Z0-9_\x7f-\xff;\n\r]|(";"[^\n\r])))))
/* compute yyleng before each rule */
<!*> := yyleng = YYCURSOR - SCNG(yy_text);
@@ -1896,7 +1896,7 @@ inline_char_handler:
}
-<ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}({LABEL}|["]{LABEL}["]){NEWLINE} {
+<ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}({LABEL}|([']{LABEL}['])|(["]{LABEL}["])){NEWLINE} {
char *s;
int bprefix = (yytext[0] != '<') ? 1 : 0;
@@ -1908,12 +1908,35 @@ inline_char_handler:
CG(heredoc_len)--;
}
- if (*s == '"') {
+ if (*s == '\'') {
s++;
CG(heredoc_len) -= 2;
+
+ BEGIN(ST_NOWDOC);
+ } else {
+ if (*s == '"') {
+ s++;
+ CG(heredoc_len) -= 2;
+ }
+
+ BEGIN(ST_HEREDOC);
}
+
CG(heredoc) = estrndup(s, CG(heredoc_len));
- BEGIN(ST_START_HEREDOC);
+
+ /* Check for ending label on the next line */
+ if (CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, CG(heredoc_len))) {
+ char *end = YYCURSOR + CG(heredoc_len);
+
+ if (*end == ';') {
+ end++;
+ }
+
+ if (*end == '\n' || *end == '\r') {
+ BEGIN(ST_END_HEREDOC);
+ }
+ }
+
return T_START_HEREDOC;
}
@@ -1924,34 +1947,6 @@ inline_char_handler:
}
-<ST_START_HEREDOC>{ANY_CHAR} {
- yyless(0);
- BEGIN(ST_HEREDOC);
- goto restart;
-}
-
-<ST_START_HEREDOC>{LABEL}";"?[\n\r] {
- int label_len = yyleng - 1;
-
- if (yytext[label_len-1]==';') {
- label_len--;
- }
-
- yyless(label_len);
-
- if (label_len==CG(heredoc_len) && !memcmp(yytext, CG(heredoc), label_len)) {
- zendlval->value.str.val = CG(heredoc);
- zendlval->value.str.len = label_len;
- CG(heredoc)=NULL;
- CG(heredoc_len)=0;
- BEGIN(ST_IN_SCRIPTING);
- return T_END_HEREDOC;
- } else {
- BEGIN(ST_HEREDOC);
- yymore();
- }
-}
-
/* Match everything up to and including a possible ending label, so if the label
* doesn't match, it's kept with the rest of the string
*
@@ -1979,12 +1974,9 @@ inline_char_handler:
len--; /* Windows newline */
}
- /* Go back before last label char, to match in ST_END_HEREDOC state */
- yyless(yyleng - 2);
-
- /* Subtract the remaining label length. yyleng must include newline
- * before label, for zend_highlight/strip, tokenizer, etc. */
- yyleng -= CG(heredoc_len) - 1;
+ /* Go back before label, to match in ST_END_HEREDOC state. yytext will include
+ * newline before label, for zend_highlight/strip, tokenizer, etc. */
+ yyless(yyleng - CG(heredoc_len) - 1); /* 1 for newline after label */
CG(increment_lineno) = 1; /* For newline before label */
BEGIN(ST_END_HEREDOC);
@@ -1999,8 +1991,11 @@ inline_char_handler:
}
<ST_END_HEREDOC>{ANY_CHAR} {
- SCNG(yy_text) = (unsigned char *)(Z_STRVAL_P(zendlval) = CG(heredoc));
- SCNG(yy_leng) = Z_STRLEN_P(zendlval) = CG(heredoc_len);
+ YYCURSOR += CG(heredoc_len) - 1;
+ yyleng = CG(heredoc_len);
+
+ Z_STRVAL_P(zendlval) = CG(heredoc);
+ Z_STRLEN_P(zendlval) = CG(heredoc_len);
CG(heredoc) = NULL;
CG(heredoc_len) = 0;
BEGIN(ST_IN_SCRIPTING);
@@ -2065,52 +2060,7 @@ inline_char_handler:
}
-/* BEGIN nowdoc */
-
-<ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}[']{LABEL}[']{NEWLINE} {
- int bprefix = (yytext[0] != '<') ? 1 : 0;
- char *s;
- CG(zend_lineno)++;
- /* 3 is <<<, 2 is quotes, 1 is newline */
- CG(heredoc_len) = yyleng-bprefix-3-2-1-(yytext[yyleng-2]=='\r'?1:0);
- s = yytext+bprefix+3;
- while ((*s == ' ') || (*s == '\t')) {
- s++;
- CG(heredoc_len)--;
- }
- s++; /* first quote */
- CG(heredoc) = estrndup(s, CG(heredoc_len));
- BEGIN(ST_START_NOWDOC);
- return T_START_NOWDOC;
-}
-
-<ST_START_NOWDOC>{ANY_CHAR} {
- yyless(0);
- BEGIN(ST_NOWDOC);
- goto restart;
-}
-
-<ST_START_NOWDOC>{LABEL}";"?[\r\n] {
- int label_len = yyleng - 1;
-
- if (yytext[label_len-1]==';') {
- label_len--;
- }
-
- if (label_len==CG(heredoc_len) && !memcmp(yytext, CG(heredoc), label_len)) {
- yyless(label_len-1);
- yyleng = 0;
- BEGIN(ST_END_NOWDOC);
- ZVAL_EMPTY_STRING(zendlval);
- return T_ENCAPSED_AND_WHITESPACE;
- } else {
- BEGIN(ST_NOWDOC);
- yyless(label_len);
- yymore();
- }
-}
-
-<ST_NOWDOC>{NOWDOC_CHARS}*{NEWLINE}+{LABEL}";"?[\n\r] {
+<ST_NOWDOC>({NOWDOC_CHARS}+{NEWLINE}+|{NEWLINE}+){LABEL}";"?[\n\r] {
char *end = yytext + yyleng - 1;
if (end[-1] == ';') {
@@ -2131,19 +2081,16 @@ inline_char_handler:
len--; /* Windows newline */
}
- /* Go back before last label char, to match in ST_END_NOWDOC state */
- yyless(yyleng - 2);
-
- /* Subtract the remaining label length. yyleng must include newline
- * before label, for zend_highlight/strip, tokenizer, etc. */
- yyleng -= CG(heredoc_len) - 1;
+ /* Go back before label, to match in ST_END_HEREDOC state. yytext will include
+ * newline before label, for zend_highlight/strip, tokenizer, etc. */
+ yyless(yyleng - CG(heredoc_len) - 1); /* 1 for newline after label */
CG(increment_lineno) = 1; /* For newline before label */
- BEGIN(ST_END_NOWDOC);
+ BEGIN(ST_END_HEREDOC);
- HANDLE_NEWLINES(yytext, len);
zend_copy_value(zendlval, yytext, len);
zendlval->type = IS_STRING;
+ HANDLE_NEWLINES(yytext, len);
return T_ENCAPSED_AND_WHITESPACE;
} else {
/* Go back to end of label, so the next match works correctly in case of
@@ -2153,16 +2100,6 @@ inline_char_handler:
}
}
-<ST_END_NOWDOC>{ANY_CHAR} {
- SCNG(yy_text) = (unsigned char*)(Z_STRVAL_P(zendlval) = CG(heredoc));
- SCNG(yy_leng) = Z_STRLEN_P(zendlval) = CG(heredoc_len);
- CG(heredoc) = NULL;
- CG(heredoc_len) = 0;
- BEGIN(ST_IN_SCRIPTING);
- return T_END_NOWDOC;
-}
-
-/* END nowdoc */
<ST_DOUBLE_QUOTES>["] {
BEGIN(ST_IN_SCRIPTING);