diff options
| -rw-r--r-- | sapi/phpdbg/phpdbg.c | 38 | ||||
| -rw-r--r-- | sapi/phpdbg/phpdbg.h | 3 | ||||
| -rw-r--r-- | sapi/phpdbg/phpdbg_lexer.c | 521 | ||||
| -rw-r--r-- | sapi/phpdbg/phpdbg_lexer.l | 6 | ||||
| -rw-r--r-- | sapi/phpdbg/phpdbg_prompt.c | 106 | 
5 files changed, 564 insertions, 110 deletions
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 1e0b214a23..0e891f3869 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -294,6 +294,11 @@ static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */  static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */  { +	if (PHPDBG_G(stdin_file)) { +		fclose(PHPDBG_G(stdin_file)); +		PHPDBG_G(stdin_file) = NULL; +	} +  	return SUCCESS;  } /* }}} */ @@ -1307,6 +1312,27 @@ void *phpdbg_realloc_wrapper(void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_  	return _zend_mm_realloc(zend_mm_get_heap(), ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);  } /* }}} */ +php_stream *phpdbg_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC) /* {{{ */ +{ +	if (!strncasecmp(path, "php://", 6)) { +		path += 6; +	} + +	if (!strncasecmp(path, "stdin", 6) && PHPDBG_G(stdin_file)) { +		php_stream *stream =stream = php_stream_fopen_from_file(PHPDBG_G(stdin_file), "r"); +#ifdef PHP_WIN32 +		zval *blocking_pipes = php_stream_context_get_option(context, "pipe", "blocking"); +		if (blocking_pipes) { +			convert_to_long(blocking_pipes); +			php_stream_set_option(stream, PHP_STREAM_OPTION_PIPE_BLOCKING, Z_LVAL_P(blocking_pipes), NULL); +		} +#endif +		return stream; +	} + +	return PHPDBG_G(orig_url_wrap_php)(wrapper, path, mode, options, opened_path, context STREAMS_CC); +} /* }}} */ +  int main(int argc, char **argv) /* {{{ */  {  	sapi_module_struct *phpdbg = &phpdbg_sapi_module; @@ -1787,6 +1813,13 @@ phpdbg_main:  		/* set default prompt */  		phpdbg_set_prompt(PHPDBG_DEFAULT_PROMPT); +/* refactor to preserve run commands on force run command */ +		{ +			php_stream_wrapper *wrapper = zend_hash_str_find_ptr(php_stream_get_url_stream_wrappers_hash(), ZEND_STRL("php")); +			PHPDBG_G(orig_url_wrap_php) = wrapper->wops->stream_opener; +			wrapper->wops->stream_opener = phpdbg_stream_url_wrap_php; +		} +  		/* Make stdin, stdout and stderr accessible from PHP scripts */  		phpdbg_register_file_handles(); @@ -2015,6 +2048,11 @@ phpdbg_out:  			}  		} +		{ +			php_stream_wrapper *wrapper = zend_hash_str_find_ptr(php_stream_get_url_stream_wrappers_hash(), ZEND_STRL("php")); +			wrapper->wops->stream_opener = PHPDBG_G(orig_url_wrap_php); +		} +  		zend_try {  			php_module_shutdown();  		} zend_end_try(); diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h index 1ff0e7a3ac..3a1ff0e723 100644 --- a/sapi/phpdbg/phpdbg.h +++ b/sapi/phpdbg/phpdbg.h @@ -306,6 +306,9 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)  	char *buffer;                                /* buffer */  	zend_bool last_was_newline;                  /* check if we don't need to output a newline upon next phpdbg_error or phpdbg_notice */ +	FILE *stdin_file;                            /* FILE pointer to stdin source file */ +	php_stream *(*orig_url_wrap_php)(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC); +  	char input_buffer[PHPDBG_MAX_CMD];           /* stdin input buffer */  	int input_buflen;                            /* length of stdin input buffer */  	phpdbg_signal_safe_mem sigsafe_mem;          /* memory to use in async safe environment (only once!) */ diff --git a/sapi/phpdbg/phpdbg_lexer.c b/sapi/phpdbg/phpdbg_lexer.c index 10af103fb0..281f882b62 100644 --- a/sapi/phpdbg/phpdbg_lexer.c +++ b/sapi/phpdbg/phpdbg_lexer.c @@ -534,7 +534,7 @@ yy39:  #line 161 "sapi/phpdbg/phpdbg_lexer.l"  		{  	phpdbg_init_param(yylval, STR_PARAM); -	yylval->str = estrndup(yytext, yyleng - unescape_string(yytext)); +	yylval->str = estrndup(yytext + (*yytext == '\'' || *yytext == '\"'), yyleng - unescape_string(yytext));  	yylval->len = yyleng;  	return T_ID;  } @@ -1655,56 +1655,61 @@ yy165:  yyc_RAW:  	{  		static const unsigned char yybm[] = { -			  0, 224, 224, 224, 224, 224, 224, 224,  -			224, 240,   0, 224, 224, 240, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			240, 224,  64, 192, 224, 224, 224, 128,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224,  32, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  -			224, 224, 224, 224, 224, 224, 224, 224,  +			  0, 232, 232, 232, 232, 232, 232, 232,  +			232, 236,   0, 232, 232, 236, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			236, 232,  32, 224, 232, 232, 232,  64,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232,  16, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,  +			232, 232, 232, 232, 232, 232, 232, 232,   		};  		YYDEBUG(168, *YYCURSOR);  		YYFILL(1);  		yych = *YYCURSOR; -		if (yybm[0+yych] & 16) { +		if (yybm[0+yych] & 4) {  			goto yy170;  		} -		if (yych <= '!') { -			if (yych <= 0x00) goto yy175; -			if (yych <= 0x08) goto yy177; -			if (yych <= '\n') goto yy175; -			goto yy177; +		if (yych <= '"') { +			if (yych <= 0x08) { +				if (yych <= 0x00) goto yy175; +				goto yy177; +			} else { +				if (yych <= '\n') goto yy175; +				if (yych <= '!') goto yy177; +				goto yy181; +			}  		} else { -			if (yych <= '#') { -				if (yych <= '"') goto yy179; -				goto yy173; +			if (yych <= '\'') { +				if (yych <= '#') goto yy173; +				if (yych <= '&') goto yy177; +				goto yy183;  			} else { -				if (yych == '\'') goto yy181; +				if (yych == '\\') goto yy179;  				goto yy177;  			}  		} @@ -1715,18 +1720,24 @@ yy170:  		YYFILL(1);  		yych = *YYCURSOR;  		YYDEBUG(171, *YYCURSOR); -		if (yybm[0+yych] & 16) { +		if (yybm[0+yych] & 4) {  			goto yy170;  		} -		if (yych <= '!') { -			if (yych <= 0x00) goto yy172; -			if (yych <= 0x08) goto yy177; -			if (yych >= '\v') goto yy177; +		if (yych <= '"') { +			if (yych <= 0x08) { +				if (yych >= 0x01) goto yy177; +			} else { +				if (yych <= '\n') goto yy172; +				if (yych <= '!') goto yy177; +				goto yy181; +			}  		} else { -			if (yych <= '#') { -				if (yych <= '"') goto yy179; +			if (yych <= '\'') { +				if (yych <= '#') goto yy172; +				if (yych <= '&') goto yy177; +				goto yy183;  			} else { -				if (yych == '\'') goto yy181; +				if (yych == '\\') goto yy179;  				goto yy177;  			}  		} @@ -1736,11 +1747,11 @@ yy172:  #line 168 "sapi/phpdbg/phpdbg_lexer.l"  		{  	phpdbg_init_param(yylval, STR_PARAM); -	yylval->str = estrndup(yytext, yyleng - unescape_string(yytext)); +	yylval->str = estrdup(yytext);  	yylval->len = yyleng;  	return T_INPUT;  } -#line 1744 "sapi/phpdbg/phpdbg_lexer.c" +#line 1755 "sapi/phpdbg/phpdbg_lexer.c"  yy173:  		YYDEBUG(173, *YYCURSOR);  		++YYCURSOR; @@ -1751,7 +1762,7 @@ yy173:  	YYSETCONDITION(INITIAL);  	return T_SEPARATOR;  } -#line 1755 "sapi/phpdbg/phpdbg_lexer.c" +#line 1766 "sapi/phpdbg/phpdbg_lexer.c"  yy175:  		YYDEBUG(175, *YYCURSOR);  		++YYCURSOR; @@ -1761,7 +1772,7 @@ yy175:  		{  	return 0;  } -#line 1765 "sapi/phpdbg/phpdbg_lexer.c" +#line 1776 "sapi/phpdbg/phpdbg_lexer.c"  yy177:  		YYDEBUG(177, *YYCURSOR);  		yyaccept = 0; @@ -1769,74 +1780,412 @@ yy177:  		YYFILL(1);  		yych = *YYCURSOR;  		YYDEBUG(178, *YYCURSOR); -		if (yybm[0+yych] & 32) { +		if (yybm[0+yych] & 8) {  			goto yy177;  		}  		if (yych <= '\n') goto yy172; -		if (yych <= '"') goto yy179; +		if (yych <= '"') goto yy181;  		if (yych <= '#') goto yy172; -		goto yy181; +		if (yych <= '\'') goto yy183;  yy179:  		YYDEBUG(179, *YYCURSOR);  		++YYCURSOR;  		YYFILL(1);  		yych = *YYCURSOR; -		if (yybm[0+yych] & 128) { -			goto yy185; -		} -		if (yych >= '#') goto yy187; -yy180:  		YYDEBUG(180, *YYCURSOR); -		YYCURSOR = YYMARKER; -		goto yy172; +		if (yybm[0+yych] & 8) { +			goto yy177; +		} +		if (yych <= '\n') goto yy172; +		if (yych <= '"') goto yy190; +		if (yych <= '#') goto yy172; +		if (yych <= '\'') goto yy191; +		goto yy179;  yy181:  		YYDEBUG(181, *YYCURSOR);  		++YYCURSOR;  		YYFILL(1);  		yych = *YYCURSOR;  		if (yybm[0+yych] & 64) { -			goto yy182; +			goto yy187;  		} -		if (yych <= '\'') goto yy180; -		goto yy184; +		if (yych >= '#') goto yy189;  yy182:  		YYDEBUG(182, *YYCURSOR); +		YYCURSOR = YYMARKER; +		goto yy172; +yy183: +		YYDEBUG(183, *YYCURSOR);  		++YYCURSOR;  		YYFILL(1);  		yych = *YYCURSOR; -		YYDEBUG(183, *YYCURSOR); -		if (yybm[0+yych] & 64) { -			goto yy182; +		if (yybm[0+yych] & 32) { +			goto yy184;  		} -		if (yych <= '\n') goto yy180; -		if (yych <= '\'') goto yy177; +		if (yych <= '\'') goto yy182; +		goto yy186;  yy184:  		YYDEBUG(184, *YYCURSOR);  		++YYCURSOR;  		YYFILL(1);  		yych = *YYCURSOR; -		if (yych == '\'') goto yy182; -		if (yych == '\\') goto yy182; -		goto yy180; -yy185:  		YYDEBUG(185, *YYCURSOR); +		if (yybm[0+yych] & 32) { +			goto yy184; +		} +		if (yych <= '\n') goto yy182; +		if (yych <= '\'') goto yy177; +yy186: +		YYDEBUG(186, *YYCURSOR);  		++YYCURSOR;  		YYFILL(1);  		yych = *YYCURSOR; -		YYDEBUG(186, *YYCURSOR); -		if (yybm[0+yych] & 128) { -			goto yy185; -		} -		if (yych <= '\n') goto yy180; -		if (yych <= '"') goto yy177; +		if (yych == '\'') goto yy184; +		if (yych == '\\') goto yy184; +		goto yy182;  yy187:  		YYDEBUG(187, *YYCURSOR);  		++YYCURSOR;  		YYFILL(1);  		yych = *YYCURSOR; -		if (yych == '"') goto yy185; -		if (yych == '\\') goto yy185; -		goto yy180; +		YYDEBUG(188, *YYCURSOR); +		if (yybm[0+yych] & 64) { +			goto yy187; +		} +		if (yych <= '\n') goto yy182; +		if (yych <= '"') goto yy177; +yy189: +		YYDEBUG(189, *YYCURSOR); +		++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yych == '"') goto yy187; +		if (yych == '\\') goto yy187; +		goto yy182; +yy190: +		YYDEBUG(190, *YYCURSOR); +		yyaccept = 0; +		YYMARKER = ++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yych <= '"') { +			if (yych <= '\t') { +				if (yych <= 0x00) goto yy172; +				goto yy205; +			} else { +				if (yych <= '\n') goto yy172; +				if (yych <= '!') goto yy205; +				goto yy181; +			} +		} else { +			if (yych <= '\'') { +				if (yych <= '#') goto yy187; +				if (yych <= '&') goto yy205; +				goto yy207; +			} else { +				if (yych == '\\') goto yy208; +				goto yy205; +			} +		} +yy191: +		YYDEBUG(191, *YYCURSOR); +		yyaccept = 0; +		YYMARKER = ++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yych <= '"') { +			if (yych <= '\t') { +				if (yych <= 0x00) goto yy172; +			} else { +				if (yych <= '\n') goto yy172; +				if (yych >= '"') goto yy194; +			} +		} else { +			if (yych <= '\'') { +				if (yych <= '#') goto yy184; +				if (yych >= '\'') goto yy183; +			} else { +				if (yych == '\\') goto yy195; +			} +		} +yy192: +		YYDEBUG(192, *YYCURSOR); +		yyaccept = 0; +		YYMARKER = ++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		YYDEBUG(193, *YYCURSOR); +		if (yych <= '"') { +			if (yych <= '\t') { +				if (yych <= 0x00) goto yy172; +				goto yy192; +			} else { +				if (yych <= '\n') goto yy172; +				if (yych <= '!') goto yy192; +			} +		} else { +			if (yych <= '\'') { +				if (yych <= '#') goto yy184; +				if (yych <= '&') goto yy192; +				goto yy191; +			} else { +				if (yych == '\\') goto yy195; +				goto yy192; +			} +		} +yy194: +		YYDEBUG(194, *YYCURSOR); +		++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yybm[0+yych] & 128) { +			goto yy200; +		} +		if (yych <= '\n') goto yy182; +		if (yych <= '"') goto yy184; +		if (yych <= '\'') goto yy205; +		goto yy210; +yy195: +		YYDEBUG(195, *YYCURSOR); +		++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yybm[0+yych] & 8) { +			goto yy177; +		} +		if (yych <= '\n') goto yy172; +		if (yych <= '"') goto yy190; +		if (yych <= '#') goto yy172; +		if (yych <= '\'') goto yy192; +		YYDEBUG(196, *YYCURSOR); +		yyaccept = 0; +		YYMARKER = ++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yych <= '"') { +			if (yych <= '\t') { +				if (yych <= 0x00) goto yy172; +				goto yy192; +			} else { +				if (yych <= '\n') goto yy172; +				if (yych <= '!') goto yy192; +			} +		} else { +			if (yych <= '\'') { +				if (yych <= '#') goto yy184; +				if (yych <= '&') goto yy192; +				goto yy191; +			} else { +				if (yych == '\\') goto yy195; +				goto yy192; +			} +		} +yy197: +		YYDEBUG(197, *YYCURSOR); +		yyaccept = 0; +		YYMARKER = ++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yych <= '"') { +			if (yych <= '\t') { +				if (yych <= 0x00) goto yy172; +			} else { +				if (yych <= '\n') goto yy172; +				if (yych >= '"') goto yy194; +			} +		} else { +			if (yych <= '\'') { +				if (yych <= '#') goto yy200; +				if (yych >= '\'') goto yy202; +			} else { +				if (yych == '\\') goto yy203; +			} +		} +yy198: +		YYDEBUG(198, *YYCURSOR); +		yyaccept = 0; +		YYMARKER = ++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		YYDEBUG(199, *YYCURSOR); +		if (yych <= '"') { +			if (yych <= '\t') { +				if (yych <= 0x00) goto yy172; +				goto yy198; +			} else { +				if (yych <= '\n') goto yy172; +				if (yych <= '!') goto yy198; +				goto yy197; +			} +		} else { +			if (yych <= '\'') { +				if (yych <= '#') goto yy200; +				if (yych <= '&') goto yy198; +				goto yy202; +			} else { +				if (yych == '\\') goto yy203; +				goto yy198; +			} +		} +yy200: +		YYDEBUG(200, *YYCURSOR); +		++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		YYDEBUG(201, *YYCURSOR); +		if (yybm[0+yych] & 128) { +			goto yy200; +		} +		if (yych <= '\n') goto yy182; +		if (yych <= '"') goto yy192; +		if (yych <= '\'') goto yy205; +		goto yy210; +yy202: +		YYDEBUG(202, *YYCURSOR); +		yyaccept = 0; +		YYMARKER = ++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yych <= '"') { +			if (yych <= '\t') { +				if (yych <= 0x00) goto yy172; +				goto yy198; +			} else { +				if (yych <= '\n') goto yy172; +				if (yych <= '!') goto yy198; +				goto yy197; +			} +		} else { +			if (yych <= '\'') { +				if (yych <= '#') goto yy200; +				if (yych <= '&') goto yy198; +				goto yy207; +			} else { +				if (yych != '\\') goto yy198; +			} +		} +yy203: +		YYDEBUG(203, *YYCURSOR); +		++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yybm[0+yych] & 8) { +			goto yy177; +		} +		if (yych <= '\n') goto yy172; +		if (yych <= '"') goto yy205; +		if (yych <= '#') goto yy172; +		if (yych <= '\'') goto yy192; +		YYDEBUG(204, *YYCURSOR); +		yyaccept = 0; +		YYMARKER = ++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yych <= '"') { +			if (yych <= '\t') { +				if (yych <= 0x00) goto yy172; +				goto yy198; +			} else { +				if (yych <= '\n') goto yy172; +				if (yych <= '!') goto yy198; +				goto yy197; +			} +		} else { +			if (yych <= '\'') { +				if (yych <= '#') goto yy200; +				if (yych <= '&') goto yy198; +				goto yy202; +			} else { +				if (yych == '\\') goto yy203; +				goto yy198; +			} +		} +yy205: +		YYDEBUG(205, *YYCURSOR); +		yyaccept = 0; +		YYMARKER = ++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		YYDEBUG(206, *YYCURSOR); +		if (yych <= '"') { +			if (yych <= '\t') { +				if (yych <= 0x00) goto yy172; +				goto yy205; +			} else { +				if (yych <= '\n') goto yy172; +				if (yych <= '!') goto yy205; +				goto yy190; +			} +		} else { +			if (yych <= '\'') { +				if (yych <= '#') goto yy187; +				if (yych <= '&') goto yy205; +			} else { +				if (yych == '\\') goto yy208; +				goto yy205; +			} +		} +yy207: +		YYDEBUG(207, *YYCURSOR); +		++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yybm[0+yych] & 128) { +			goto yy200; +		} +		if (yych <= '\n') goto yy182; +		if (yych <= '"') goto yy192; +		if (yych <= '\'') goto yy187; +		goto yy210; +yy208: +		YYDEBUG(208, *YYCURSOR); +		++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yybm[0+yych] & 8) { +			goto yy177; +		} +		if (yych <= '\n') goto yy172; +		if (yych <= '"') goto yy205; +		if (yych <= '#') goto yy172; +		if (yych <= '\'') goto yy191; +		YYDEBUG(209, *YYCURSOR); +		yyaccept = 0; +		YYMARKER = ++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yych <= '"') { +			if (yych <= '\t') { +				if (yych <= 0x00) goto yy172; +				goto yy205; +			} else { +				if (yych <= '\n') goto yy172; +				if (yych <= '!') goto yy205; +				goto yy190; +			} +		} else { +			if (yych <= '\'') { +				if (yych <= '#') goto yy187; +				if (yych <= '&') goto yy205; +				goto yy202; +			} else { +				if (yych == '\\') goto yy208; +				goto yy205; +			} +		} +yy210: +		YYDEBUG(210, *YYCURSOR); +		++YYCURSOR; +		YYFILL(1); +		yych = *YYCURSOR; +		if (yych <= '&') { +			if (yych == '"') goto yy187; +			goto yy182; +		} else { +			if (yych <= '\'') goto yy184; +			if (yych == '\\') goto yy200; +			goto yy182; +		}  	}  }  #line 213 "sapi/phpdbg/phpdbg_lexer.l" diff --git a/sapi/phpdbg/phpdbg_lexer.l b/sapi/phpdbg/phpdbg_lexer.l index 21c4569480..b9c247a494 100644 --- a/sapi/phpdbg/phpdbg_lexer.l +++ b/sapi/phpdbg/phpdbg_lexer.l @@ -82,7 +82,7 @@ ID          [^ \r\n\t:#\000]+  GENERIC_ID  ([^ \r\n\t:#\000"']|":\\")+|["]([^\n\000"\\]|"\\\\"|"\\"["])+["]|[']([^\n\000'\\]|"\\\\"|"\\"['])+[']  ADDR        [0][x][a-fA-F0-9]+  OPCODE      (ZEND_|zend_)([A-Za-z])+ -INPUT       ([^\n\000#"']|["]([^\n\000"\\]|"\\\\"|"\\"["])+["]|[']([^\n\000'\\]|"\\\\"|"\\"['])+['])+ +INPUT       ([^\n\000#"']|"\\"["']|["]([^\n\000"\\]|"\\\\"|"\\"["])+["]|[']([^\n\000'\\]|"\\\\"|"\\"['])+['])+  <!*> := yyleng = (size_t) YYCURSOR - (size_t) yytext; @@ -160,14 +160,14 @@ INPUT       ([^\n\000#"']|["]([^\n\000"\\]|"\\\\"|"\\"["])+["]|[']([^\n\000'\\]|  <NORMAL>{GENERIC_ID} {  	phpdbg_init_param(yylval, STR_PARAM); -	yylval->str = estrndup(yytext, yyleng - unescape_string(yytext)); +	yylval->str = estrndup(yytext + (*yytext == '\'' || *yytext == '\"'), yyleng - unescape_string(yytext));  	yylval->len = yyleng;  	return T_ID;  }  <RAW>{INPUT} {  	phpdbg_init_param(yylval, STR_PARAM); -	yylval->str = estrndup(yytext, yyleng - unescape_string(yytext)); +	yylval->str = estrdup(yytext);  	yylval->len = yyleng;  	return T_INPUT;  } diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index c0ce007715..4ade755877 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -687,35 +687,84 @@ PHPDBG_COMMAND(run) /* {{{ */  			}  		} -		/* clean up from last execution */ -		if (ex && (ZEND_CALL_INFO(ex) & ZEND_CALL_HAS_SYMBOL_TABLE)) { -			zend_hash_clean(ex->symbol_table); -		} else { -			zend_rebuild_symbol_table(); -		} -		PHPDBG_G(handled_exception) = NULL; - -		/* clean seek state */ -		PHPDBG_G(flags) &= ~PHPDBG_SEEK_MASK; -		zend_hash_clean(&PHPDBG_G(seek)); - -		/* reset hit counters */ -		phpdbg_reset_breakpoints(); -  		if (param && param->type != EMPTY_PARAM && param->len != 0) {  			char **argv = emalloc(5 * sizeof(char *)); +			char *end = param->str + param->len, *p = param->str;  			int argc = 0;  			int i; -			/* TODO allow proper escaping with \,  "" and '' here */ -			char *argv_str = strtok(param->str, " "); -			while (argv_str) { +			while (*end == '\r' || *end == '\n') *(end--) = 0; + +			while (*p == ' ') p++; +			while (*p) { +				char sep = ' '; +				char *buf = emalloc(end - p + 1), *q = buf; + +				if (*p == '<') { +					/* use as STDIN */ +					do p++; while (*p == ' '); + +					if (*p == '\'' || *p == '"') { +						sep = *(p++); +					} +					while (*p && *p != sep) { +						if (*p == '\\' && (p[1] == sep || p[1] == '\\')) { +							p++; +						} +						*(q++) = *(p++); +					} +					*(q++) = 0; +					if (*p) { +						do p++; while (*p == ' '); +					} + +					if (*p) { +						phpdbg_error("cmd", "", "Invalid run command, cannot put further arguments after stdin"); +						goto free_cmd; +					} + +					PHPDBG_G(stdin_file) = fopen(buf, "r"); +					if (PHPDBG_G(stdin_file) == NULL) { +						phpdbg_error("stdin", "path=\"%s\"", "Could not open '%s' for reading from stdin", buf); +						goto free_cmd; +					} +					efree(buf); +					break; +				} +  				if (argc >= 4 && argc == (argc & -argc)) {  					argv = erealloc(argv, (argc * 2 + 1) * sizeof(char *));  				} -				argv[++argc] = argv_str; -				argv_str = strtok(0, " "); -				argv[argc] = estrdup(argv[argc]); + +				if (*p == '\'' || *p == '"') { +					sep = *(p++); +				} +				if (*p == '\\' && (p[1] == '<' || p[1] == '\'' || p[1] == '"')) { +					p++; +				} +				while (*p && *p != sep) { +					if (*p == '\\' && (p[1] == sep || p[1] == '\\')) { +						p++; +					} +					*(q++) = *(p++); +				} +				if (!*p && sep != ' ') { +					phpdbg_error("cmd", "", "Invalid run command, unterminated escape sequence"); +free_cmd: +					efree(buf); +					for (i = 0; i < argc; i++) { +						efree(argv[i]); +					} +					efree(argv); +					return SUCCESS; +				} + +				*(q++) = 0; +				argv[++argc] = erealloc(buf, q - buf); + +				if (*p) { +					do p++; while (*p == ' '); +				}  			}  			argv[0] = SG(request_info).argv[0];  			for (i = SG(request_info).argc; --i;) { @@ -728,6 +777,21 @@ PHPDBG_COMMAND(run) /* {{{ */  			php_build_argv(NULL, &PG(http_globals)[TRACK_VARS_SERVER]);  		} +		/* clean up from last execution */ +		if (ex && (ZEND_CALL_INFO(ex) & ZEND_CALL_HAS_SYMBOL_TABLE)) { +			zend_hash_clean(ex->symbol_table); +		} else { +			zend_rebuild_symbol_table(); +		} +		PHPDBG_G(handled_exception) = NULL; + +		/* clean seek state */ +		PHPDBG_G(flags) &= ~PHPDBG_SEEK_MASK; +		zend_hash_clean(&PHPDBG_G(seek)); + +		/* reset hit counters */ +		phpdbg_reset_breakpoints(); +  		zend_try {  			PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE;  			PHPDBG_G(flags) |= PHPDBG_IS_RUNNING;  | 
