diff options
author | Bob Weinand <bobwei9@hotmail.com> | 2016-10-01 18:54:44 +0100 |
---|---|---|
committer | Bob Weinand <bobwei9@hotmail.com> | 2016-10-01 19:05:19 +0100 |
commit | 9d537951c5e4af5e453dd4d60e74dad039856b80 (patch) | |
tree | 4fe7f1c6e283886c2e9099234d32bf00dd7b766b | |
parent | 633b93817ea9636366f56898894aa18c4d6e485b (diff) | |
download | php-git-9d537951c5e4af5e453dd4d60e74dad039856b80.tar.gz |
Add proper escape sequences and reading stdin from file in phpdbg run command
-rw-r--r-- | NEWS | 3 | ||||
-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 |
6 files changed, 567 insertions, 110 deletions
@@ -9,6 +9,9 @@ PHP NEWS - GD: . Fixed bug #73213 (Integer overflow in imageline() with antialiasing). (cmb) +- phpdbg: + . Properly allow for stdin input from a file. (Bob) + - Standard: . Fixed bug #73203 (passing additional_parameters causes mail to fail). (cmb) diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 9b7993ddf0..234d0f912e 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -262,6 +262,11 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ PHPDBG_G(oplog_list) = NULL; } + if (PHPDBG_G(stdin_file)) { + fclose(PHPDBG_G(stdin_file)); + PHPDBG_G(stdin_file) = NULL; + } + return SUCCESS; } /* }}} */ @@ -1281,6 +1286,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; @@ -1774,6 +1800,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(); @@ -2005,6 +2038,11 @@ phpdbg_out: } php_output_deactivate(); + { + 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 c77bc1c530..1879e62252 100644 --- a/sapi/phpdbg/phpdbg.h +++ b/sapi/phpdbg/phpdbg.h @@ -300,6 +300,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 fb935c3ca5..7315ff2afe 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -688,35 +688,84 @@ PHPDBG_COMMAND(run) /* {{{ */ } } - /* clean up from last execution */ - if (ex && ex->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;) { @@ -729,6 +778,21 @@ PHPDBG_COMMAND(run) /* {{{ */ php_build_argv(NULL, &PG(http_globals)[TRACK_VARS_SERVER]); } + /* clean up from last execution */ + if (ex && ex->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; |