diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index bf0f233118b1..156599f6f9d4 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -2372,6 +2372,7 @@ consult the installation file that came with this distribution, or visit \n\ } } +do_repeat: if (script_file) { /* override path_translated if -f on command line */ if (SG(request_info).path_translated) efree(SG(request_info).path_translated); @@ -2512,7 +2513,6 @@ consult the installation file that came with this distribution, or visit \n\ PG(during_request_startup) = 0; if (php_lint_script(&file_handle) == SUCCESS) { zend_printf("No syntax errors detected in %s\n", ZSTR_VAL(file_handle.filename)); - exit_status = 0; } else { zend_printf("Errors parsing %s\n", ZSTR_VAL(file_handle.filename)); exit_status = -1; @@ -2581,6 +2581,11 @@ consult the installation file that came with this distribution, or visit \n\ } } } + if (behavior == PHP_MODE_LINT && argc - 1 > php_optind) { + php_optind++; + script_file = NULL; + goto do_repeat; + } break; } diff --git a/sapi/cgi/tests/012.phpt b/sapi/cgi/tests/012.phpt new file mode 100644 index 000000000000..7f981b7da8d0 --- /dev/null +++ b/sapi/cgi/tests/012.phpt @@ -0,0 +1,117 @@ +--TEST-- +multiple files syntax check +--SKIPIF-- + +--INI-- +display_errors=stdout +--FILE-- +/dev/null"; + } + exec($cmd, $output, $exit_code); + print_r($output); + // Normalize Windows vs Linux exit codes. On Windows exit code -1 is actually -1 instead of 255. + if ($exit_code < 0) { + $exit_code += 256; + } + var_dump($exit_code); +} + +$php = get_cgi_path(); +reset_env_vars(); + +$filename_good = __DIR__."/012_good.test.php"; +$filename_good_escaped = escapeshellarg($filename_good); +$filename_bad = __DIR__."/012_bad.test.php"; +$filename_bad_escaped = escapeshellarg($filename_bad); + +$code = ' + +'; + +file_put_contents($filename_bad, $code); + +run_and_output("$php -n -l $filename_good_escaped $filename_good_escaped"); +run_and_output("$php -n -l $filename_good_escaped some.unknown $filename_good_escaped"); +run_and_output("$php -n -l $filename_good_escaped $filename_bad_escaped $filename_good_escaped"); +run_and_output("$php -n -l $filename_bad_escaped $filename_bad_escaped"); +run_and_output("$php -n -l $filename_bad_escaped some.unknown $filename_bad_escaped"); +run_and_output("$php -n -l $filename_bad_escaped $filename_bad_escaped some.unknown"); + +echo "Done\n"; +?> +--CLEAN-- + +--EXPECTF-- +Array +( + [0] => No syntax errors detected in %s012_good.test.php + [1] => No syntax errors detected in %s012_good.test.php +) +int(0) +Array +( + [0] => No syntax errors detected in %s012_good.test.php + [1] => No input file specified. +) +int(255) +Array +( + [0] => No syntax errors detected in %s012_good.test.php + [1] =>
+ [2] => Parse error: syntax error, unexpected token "private", expecting "{" in %s012_bad.test.php on line 5
+ [3] => Errors parsing %s012_bad.test.php + [4] => No syntax errors detected in %s012_good.test.php +) +int(255) +Array +( + [0] =>
+ [1] => Parse error: syntax error, unexpected token "private", expecting "{" in %s012_bad.test.php on line 5
+ [2] => Errors parsing %s012_bad.test.php + [3] =>
+ [4] => Parse error: syntax error, unexpected token "private", expecting "{" in %s012_bad.test.php on line 5
+ [5] => Errors parsing %s012_bad.test.php +) +int(255) +Array +( + [0] =>
+ [1] => Parse error: syntax error, unexpected token "private", expecting "{" in %s012_bad.test.php on line 5
+ [2] => Errors parsing %s012_bad.test.php + [3] => No input file specified. +) +int(255) +Array +( + [0] =>
+ [1] => Parse error: syntax error, unexpected token "private", expecting "{" in %s012_bad.test.php on line 5
+ [2] => Errors parsing %s012_bad.test.php + [3] =>
+ [4] => Parse error: syntax error, unexpected token "private", expecting "{" in %s012_bad.test.php on line 5
+ [5] => Errors parsing %s012_bad.test.php + [6] => No input file specified. +) +int(255) +Done diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index c35980030585..546c4ba997dc 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -734,6 +734,10 @@ static int do_cli(int argc, char **argv) /* {{{ */ break; } behavior=PHP_MODE_LINT; + /* We want to set the error exit status if at least one lint failed. + * If all were successful we set the exit status to 0. + * We already set EG(exit_status) here such that only failures set the exit status. */ + EG(exit_status) = 0; break; case 'q': /* do not generate HTTP headers */ @@ -962,7 +966,6 @@ static int do_cli(int argc, char **argv) /* {{{ */ case PHP_MODE_LINT: if (php_lint_script(&file_handle) == SUCCESS) { zend_printf("No syntax errors detected in %s\n", php_self); - EG(exit_status) = 0; } else { zend_printf("Errors parsing %s\n", php_self); EG(exit_status) = 255; @@ -1128,9 +1131,15 @@ static int do_cli(int argc, char **argv) /* {{{ */ } if (request_started) { php_request_shutdown((void *) 0); + request_started = 0; } if (translated_path) { free(translated_path); + translated_path = NULL; + } + if (behavior == PHP_MODE_LINT && argc > php_optind && strcmp(argv[php_optind],"--")) { + script_file = NULL; + goto do_repeat; } /* Don't repeat fork()ed processes. */ if (--num_repeats && pid == getpid()) { diff --git a/sapi/cli/tests/024.phpt b/sapi/cli/tests/024.phpt new file mode 100644 index 000000000000..bfd24679fd3c --- /dev/null +++ b/sapi/cli/tests/024.phpt @@ -0,0 +1,110 @@ +--TEST-- +multiple files syntax check +--SKIPIF-- + +--FILE-- + +'; + +file_put_contents($filename_bad, $code); + +run_and_output("$php -n -l $filename_good_escaped $filename_good_escaped 2>&1"); +run_and_output("$php -n -l $filename_good_escaped some.unknown $filename_good_escaped 2>&1"); +run_and_output("$php -n -l $filename_good_escaped $filename_bad_escaped $filename_good_escaped 2>&1"); +run_and_output("$php -n -l $filename_bad_escaped $filename_bad_escaped 2>&1"); +run_and_output("$php -n -l $filename_bad_escaped some.unknown $filename_bad_escaped 2>&1"); +run_and_output("$php -n -l $filename_bad_escaped $filename_bad_escaped some.unknown 2>&1"); + +echo "Done\n"; +?> +--CLEAN-- + +--EXPECTF-- +Array +( + [0] => No syntax errors detected in %s024_good.test.php + [1] => No syntax errors detected in %s024_good.test.php +) +int(0) +Array +( + [0] => No syntax errors detected in %s024_good.test.php + [1] => Could not open input file: some.unknown + [2] => No syntax errors detected in %s024_good.test.php +) +int(1) +Array +( + [0] => No syntax errors detected in %s024_good.test.php + [1] => + [2] => Parse error: syntax error, unexpected token "private", expecting "{" in %s on line %d + [3] => Errors parsing %s024_bad.test.php + [4] => No syntax errors detected in %s024_good.test.php +) +int(255) +Array +( + [0] => + [1] => Parse error: syntax error, unexpected token "private", expecting "{" in %s on line %d + [2] => Errors parsing %s024_bad.test.php + [3] => + [4] => Parse error: syntax error, unexpected token "private", expecting "{" in %s on line %d + [5] => Errors parsing %s024_bad.test.php +) +int(255) +Array +( + [0] => + [1] => Parse error: syntax error, unexpected token "private", expecting "{" in %s on line %d + [2] => Errors parsing %s024_bad.test.php + [3] => Could not open input file: some.unknown + [4] => + [5] => Parse error: syntax error, unexpected token "private", expecting "{" in %s on line %d + [6] => Errors parsing %s024_bad.test.php +) +int(255) +Array +( + [0] => + [1] => Parse error: syntax error, unexpected token "private", expecting "{" in %s on line %d + [2] => Errors parsing %s024_bad.test.php + [3] => + [4] => Parse error: syntax error, unexpected token "private", expecting "{" in %s on line %d + [5] => Errors parsing %s024_bad.test.php + [6] => Could not open input file: some.unknown +) +int(1) +Done