]> granicus.if.org Git - php/commitdiff
Support <?php followed by EOF
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 15 Jul 2019 15:26:26 +0000 (17:26 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 16 Jul 2019 09:53:48 +0000 (11:53 +0200)
This is an annoying edge-case for canonicalization.

UPGRADING
Zend/tests/php_tag_only.inc [new file with mode: 0644]
Zend/tests/php_tag_only.phpt [new file with mode: 0644]
Zend/zend_language_scanner.l
ext/tokenizer/tests/php_tag_only.phpt [new file with mode: 0644]

index 66b12819725a7ae3858584d6b2ac1de2306076f5..25e62eed735d4be055ca7c4a0a1f8e502ba0ae7c 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -34,6 +34,10 @@ PHP 7.4 UPGRADE NOTES
   . Passing the result of a (non-reference) list() assignment by reference is
     consistently disallowed now. Previously this worked if the right hand side
     was a simple (CV) variable and did not occur as part of the list().
+  . `<?php` at the end of the file (without trailing newline) will now be
+    interpreted as an opening PHP tag. Previously it was interpreted either as
+    `<? php` and resulted in a syntax error (with short_open_tag=1) or was
+    interpreted as a literal `<?php` string (with short_open_tag=0).
 
 - BCMath:
   . BCMath functions will now warn if a non well-formed number is passed, such
diff --git a/Zend/tests/php_tag_only.inc b/Zend/tests/php_tag_only.inc
new file mode 100644 (file)
index 0000000..a814366
--- /dev/null
@@ -0,0 +1 @@
+<?php
\ No newline at end of file
diff --git a/Zend/tests/php_tag_only.phpt b/Zend/tests/php_tag_only.phpt
new file mode 100644 (file)
index 0000000..0d01180
--- /dev/null
@@ -0,0 +1,5 @@
+--TEST--
+File with just a <?php tag should be valid
+--FILE_EXTERNAL--
+php_tag_only.inc
+--EXPECT--
index c9539ce8817a2f4114a574364571044957f46f42..5824b6b7631ab4cc4a3aa361ddab04c09d776376 100644 (file)
@@ -2031,6 +2031,20 @@ string:
        RETURN_OR_SKIP_TOKEN(T_OPEN_TAG);
 }
 
+<INITIAL>"<?php" {
+       /* Allow <?php followed by end of file. */
+       if (YYCURSOR == YYLIMIT) {
+               BEGIN(ST_IN_SCRIPTING);
+               RETURN_OR_SKIP_TOKEN(T_OPEN_TAG);
+       }
+       /* Degenerate case: <?phpX is interpreted as <? phpX with short tags. */
+       if (CG(short_tags)) {
+               yyless(2);
+               BEGIN(ST_IN_SCRIPTING);
+               RETURN_OR_SKIP_TOKEN(T_OPEN_TAG);
+       }
+       goto inline_char_handler;
+}
 
 <INITIAL>"<?" {
        if (CG(short_tags)) {
diff --git a/ext/tokenizer/tests/php_tag_only.phpt b/ext/tokenizer/tests/php_tag_only.phpt
new file mode 100644 (file)
index 0000000..a6df7de
--- /dev/null
@@ -0,0 +1,19 @@
+--TEST--
+Tokenization of only the <?php tag
+--FILE--
+<?php
+
+foreach (token_get_all("<?php") as $token) {
+    echo token_name($token[0]), "\n";
+}
+echo "\n";
+foreach (token_get_all("Foobar<?php") as $token) {
+    echo token_name($token[0]), "\n";
+}
+
+?>
+--EXPECT--
+T_OPEN_TAG
+
+T_INLINE_HTML
+T_OPEN_TAG