@@ -1749,7 +1749,6 @@ int main(int argc, char *argv[])
17491749 int status = 0 ;
17501750#endif
17511751 char * query_string ;
1752- char * decoded_query_string ;
17531752 int skip_getopt = 0 ;
17541753
17551754#if defined(SIGPIPE ) && defined(SIG_IGN )
@@ -1804,10 +1803,15 @@ int main(int argc, char *argv[])
18041803 * the executable. Ideally we skip argument parsing when we're in cgi or fastcgi mode,
18051804 * but that breaks PHP scripts on Linux with a hashbang: `#!/php-cgi -d option=value`.
18061805 * Therefore, this code only prevents passing arguments if the query string starts with a '-'.
1807- * Similarly, scripts spawned in subprocesses on Windows may have the same issue. */
1806+ * Similarly, scripts spawned in subprocesses on Windows may have the same issue.
1807+ * However, Windows has lots of conversion rules and command line parsing rules that
1808+ * are too difficult and dangerous to reliably emulate. */
18081809 if ((query_string = getenv ("QUERY_STRING" )) != NULL && strchr (query_string , '=' ) == NULL ) {
1810+ #ifdef PHP_WIN32
1811+ skip_getopt = cgi || fastcgi ;
1812+ #else
18091813 unsigned char * p ;
1810- decoded_query_string = strdup (query_string );
1814+ char * decoded_query_string = strdup (query_string );
18111815 php_url_decode (decoded_query_string , strlen (decoded_query_string ));
18121816 for (p = (unsigned char * )decoded_query_string ; * p && * p <= ' ' ; p ++ ) {
18131817 /* skip all leading spaces */
@@ -1816,22 +1820,8 @@ int main(int argc, char *argv[])
18161820 skip_getopt = 1 ;
18171821 }
18181822
1819- /* On Windows we have to take into account the "best fit" mapping behaviour. */
1820- #ifdef PHP_WIN32
1821- if (* p >= 0x80 ) {
1822- wchar_t wide_buf [1 ];
1823- wide_buf [0 ] = * p ;
1824- char char_buf [4 ];
1825- size_t wide_buf_len = sizeof (wide_buf ) / sizeof (wide_buf [0 ]);
1826- size_t char_buf_len = sizeof (char_buf ) / sizeof (char_buf [0 ]);
1827- if (WideCharToMultiByte (CP_ACP , 0 , wide_buf , wide_buf_len , char_buf , char_buf_len , NULL , NULL ) == 0
1828- || char_buf [0 ] == '-' ) {
1829- skip_getopt = 1 ;
1830- }
1831- }
1832- #endif
1833-
18341823 free (decoded_query_string );
1824+ #endif
18351825 }
18361826
18371827 php_ini_builder_init (& ini_builder );
@@ -1898,18 +1888,17 @@ int main(int argc, char *argv[])
18981888
18991889 /* check force_cgi after startup, so we have proper output */
19001890 if (cgi && CGIG (force_redirect )) {
1901- /* Apache will generate REDIRECT_STATUS,
1902- * Netscape and redirect.so will generate HTTP_REDIRECT_STATUS.
1903- * redirect.so and installation instructions available from
1904- * http://www.koehntopp.de/php.
1905- 1906- */
1907- if (!getenv ("REDIRECT_STATUS" ) &&
1908- !getenv ("HTTP_REDIRECT_STATUS" ) &&
1909- /* this is to allow a different env var to be configured
1910- * in case some server does something different than above */
1911- (!CGIG (redirect_status_env ) || !getenv (CGIG (redirect_status_env )))
1912- ) {
1891+ /* This is to allow a different environment variable to be configured
1892+ * in case the we cannot auto-detect which environment variable to use.
1893+ * Checking this first to allow user overrides in case the environment
1894+ * variable can be set by an untrusted party. */
1895+ const char * redirect_status_env = CGIG (redirect_status_env );
1896+ if (!redirect_status_env ) {
1897+ /* Apache will generate REDIRECT_STATUS. */
1898+ redirect_status_env = "REDIRECT_STATUS" ;
1899+ }
1900+
1901+ if (!getenv (redirect_status_env )) {
19131902 zend_try {
19141903 SG (sapi_headers ).http_response_code = 400 ;
19151904 PUTS ("<b>Security Alert!</b> The PHP CGI cannot be accessed directly.\n\n\
0 commit comments