|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2019-05-25 16:52 UTC] octalbugsphp at alvarezp dot org
Description:
------------
PHP eats the first byte of a program that comes from process substitution
After discussion in ##php at Freenode this was found (see the third line, lseek)
$ strace php -f <(echo -- '<?php print("hello\n"); ?>') 2>&1 | grep -A 5 'openat.*/dev/fd/63'
openat(AT_FDCWD, "/dev/fd/63", O_RDONLY) = 3
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
read(3, "-- <?php print(\"hello\\n\"); ?>\n", 4096) = 30
lseek(3, 0, SEEK_SET) = -1 ESPIPE (Illegal seek)
lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
readlink("/dev/fd/63", "pipe:[6195898]", 4096) = 14
Test script:
---------------
[ 0][Sat May 25 11:05:07 -0500 -- alvarezp@alvarezp-samsung:~]
$ php -f <(echo '<?php print("hello\n"); ?>')
?php print("hello\n"); ?>
[ 0][Sat May 25 11:05:11 -0500 -- alvarezp@alvarezp-samsung:~]
$ php -f <(echo ' <?php print("hello\n"); ?>')
hello
[ 0][Sat May 25 11:05:19 -0500 -- alvarezp@alvarezp-samsung:~]
$ php -f <(echo -- '<?php print("hello\n"); ?>')
- hello
Expected result:
----------------
The script should run as expected. The first byte should prevail as part of the script.
Actual result:
--------------
The first byte is eaten and not interpreted at all.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 10:00:01 2025 UTC |
Hi, I was able to reproduce the problem with a small test C snippet that mimics what php-src is doing: ------------------------------------- #include <stdio.h> #include <stdlib.h> int main(int argc, char* argv[]) { FILE *fp; fp = fopen(argv[1], "rb"); char a = fgetc(fp); rewind(fp); char ch; while(1) { ch = fgetc(fp); if(feof(fp)) { break; } printf("%c", ch); } return 0; } ------------------------------------- `rewind()` fills `errno` with the value `29` which means `Illegal seek`. The lines char a = fgetc(fp); rewind(fp); mimic what php-src is doing here on line 606 and 620: https://github.com/php/php-src/blob/e6f86fb17cd3a2dfe94ca1a0113a23194cb1915a/sapi/cli/php_cli.c#L606-L620 It calls fgetc() to find out if shebang exists on the file pointer but rewind() doesn't work correctly.... Call the above snippet as specified in the bug report: gcc test.c ./a.out <(echo '<?php print("hello"); ?>') ----------------------------- Output: ?php print("hello"); ?>It should break all instances where the script file is a fifo. Blame shows commit 71ea95354b [1]: MFH: Corrected fix for bug #46844 to only trigger on the 1st line of CLI opened files. Which in turn references bug #46844: First line of included files not output if they begin with # [1] https://github.com/php/php-src/commit/71ea95354b4133f12dcf8207bc7b36e1562bdd65 [2] https://bugs.php.net/bug.php?id=46844