summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2016-10-01 18:54:44 +0100
committerBob Weinand <bobwei9@hotmail.com>2016-10-01 19:05:19 +0100
commit9d537951c5e4af5e453dd4d60e74dad039856b80 (patch)
tree4fe7f1c6e283886c2e9099234d32bf00dd7b766b
parent633b93817ea9636366f56898894aa18c4d6e485b (diff)
downloadphp-git-9d537951c5e4af5e453dd4d60e74dad039856b80.tar.gz
Add proper escape sequences and reading stdin from file in phpdbg run command
-rw-r--r--NEWS3
-rw-r--r--sapi/phpdbg/phpdbg.c38
-rw-r--r--sapi/phpdbg/phpdbg.h3
-rw-r--r--sapi/phpdbg/phpdbg_lexer.c521
-rw-r--r--sapi/phpdbg/phpdbg_lexer.l6
-rw-r--r--sapi/phpdbg/phpdbg_prompt.c106
6 files changed, 567 insertions, 110 deletions
diff --git a/NEWS b/NEWS
index 823baa9304..0b4cae7cf6 100644
--- a/NEWS
+++ b/NEWS
@@ -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;