Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Zend/zend_ini_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,11 @@ static ZEND_COLD void ini_error(const char *msg)
error_buf_len = 128 + (int)strlen(msg) + (int)strlen(currently_parsed_filename); /* should be more than enough */
error_buf = (char *) emalloc(error_buf_len);

sprintf(error_buf, "%s in %s on line %" PRIu32 "\n", msg, currently_parsed_filename, zend_ini_scanner_get_lineno());
if (strcmp(currently_parsed_filename, "Unknown") == 0 && CG(ini_parser_unbuffered_errors)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You probably want to check if (ini_filename) instead. Side-note: The if (currently_parsed_filename) { is useless because zend_ini_scanner_get_filename() never returns NULL.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why does this check CG(ini_parser_unbuffered_errors)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

To distinguish CLI/FPM -d INI overrides from parse_ini_string(). in basic_functions.c it's called with unbuffered_errors = 0, while the other call sites pass 1.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can ini_filename be unset for any other reasons? E.g. when set in php-fpm.conf or php_value in Apache?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The unbuffered_errors check correctly identifies CLI/FPM command-line cases. For fpm conf and Apache php_value, I think those use zend_parse_ini_file() which sets ini_filename from the file handle.

sprintf(error_buf, "%s in INI command line parameter '-d'\n", msg);
} else {
sprintf(error_buf, "%s in %s on line %" PRIu32 "\n", msg, currently_parsed_filename, zend_ini_scanner_get_lineno());
}
} else {
error_buf = estrdup("Invalid configuration directive\n");
}
Expand Down
29 changes: 29 additions & 0 deletions sapi/cli/tests/gh20871.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--TEST--
GH-20871: Bad error line and file for invalid "-d" arguments
--SKIPIF--
<?php include "skipif.inc"; ?>
--FILE--
<?php
$php = getenv('TEST_PHP_EXECUTABLE_ESCAPED');

exec("$php -d 'foo=bar=asd' -r \"echo 'hello' . PHP_EOL;\" 2>&1", $output, $exit_code);
print_r($output);

echo "\n";

exec("$php -d 'foo=bar!asd' -r \"echo 'world' . PHP_EOL;\" 2>&1", $output2, $exit_code2);
print_r($output2);

?>
--EXPECTF--
Array
(
[0] => PHP: syntax error, unexpected '=' in INI command line parameter '-d'
[1] => hello
)

Array
(
[0] => PHP: syntax error, unexpected '!' in INI command line parameter '-d'
[1] => world
)
Loading