]> granicus.if.org Git - php/commitdiff
Add proper escape sequences and reading stdin from file in phpdbg run command
authorBob Weinand <bobwei9@hotmail.com>
Sat, 1 Oct 2016 17:54:44 +0000 (18:54 +0100)
committerBob Weinand <bobwei9@hotmail.com>
Sat, 1 Oct 2016 18:05:19 +0000 (19:05 +0100)
NEWS
sapi/phpdbg/phpdbg.c
sapi/phpdbg/phpdbg.h
sapi/phpdbg/phpdbg_lexer.c
sapi/phpdbg/phpdbg_lexer.l
sapi/phpdbg/phpdbg_prompt.c

diff --git a/NEWS b/NEWS
index 823baa9304037a8eae96fd985c147a0346f9f3bc..0b4cae7cf69b404449ee2cb30840ed1b9985fde9 100644 (file)
--- 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)
 
index 9b7993ddf04e7182303f9865f643d9f5de49585c..234d0f912e4d32821ba5f7a86c40f73f4a76078d 100644 (file)
@@ -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();
index c77bc1c5301937cf68585c23f352eef7718c4a33..1879e622520774dbbec74bb6bd2c4d00964ccf41 100644 (file)
@@ -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!) */
index 10af103fb02f34d4892670163a5d7d67bba8f7cc..281f882b62d9a945d2932e2ef93a98fb2727d446 100644 (file)
@@ -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"
index 21c4569480fd3186f6953be4e7a7ee329851fbe7..b9c247a494a64252c9e32037bc12fb3fea8f027a 100644 (file)
@@ -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;
 }
index fb935c3ca5186b4656b15da93a3bbc3000d77609..7315ff2afe2a67999dc636209cc15d8665ac689d 100644 (file)
@@ -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;