diff options
Diffstat (limited to 'sapi/phpdbg')
| -rw-r--r-- | sapi/phpdbg/phpdbg.c | 11 | ||||
| -rw-r--r-- | sapi/phpdbg/phpdbg.h | 2 | ||||
| -rw-r--r-- | sapi/phpdbg/phpdbg_io.c | 10 | ||||
| -rw-r--r-- | sapi/phpdbg/phpdbg_list.c | 18 | ||||
| -rw-r--r-- | sapi/phpdbg/phpdbg_list.h | 1 | ||||
| -rw-r--r-- | sapi/phpdbg/phpdbg_parser.c | 60 | ||||
| -rw-r--r-- | sapi/phpdbg/phpdbg_parser.h | 2 | ||||
| -rw-r--r-- | sapi/phpdbg/phpdbg_prompt.c | 41 | ||||
| -rw-r--r-- | sapi/phpdbg/phpdbg_sigsafe.c | 4 | ||||
| -rw-r--r-- | sapi/phpdbg/tests/bug73615.phpt | 18 | ||||
| -rw-r--r-- | sapi/phpdbg/tests/bug73615/.phpdbginit | 2 | ||||
| -rw-r--r-- | sapi/phpdbg/tests/bug73704.phpt | 27 | ||||
| -rw-r--r-- | sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.inc | 6 | ||||
| -rw-r--r-- | sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.phpt | 84 |
14 files changed, 220 insertions, 66 deletions
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 2c43a9c853..8153772368 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -33,6 +33,7 @@ #include "zend_alloc.h" #include "phpdbg_eol.h" #include "phpdbg_print.h" +#include "phpdbg_help.h" #include "ext/standard/basic_functions.h" @@ -1299,7 +1300,7 @@ void phpdbg_free_wrapper(void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) /* {{ */ } else { phpdbg_watch_efree(p); - return _zend_mm_free(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + _zend_mm_free(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); } } /* }}} */ @@ -1575,7 +1576,7 @@ phpdbg_main: quit_immediately = phpdbg_startup_run > 1; /* set exec if present on command line */ - if (!read_from_stdin && argc > php_optind && (strcmp(argv[php_optind-1], "--") != SUCCESS)) { + if (!read_from_stdin && argc > php_optind) { if (!exec && strlen(argv[php_optind])) { exec = strdup(argv[php_optind]); } @@ -1873,9 +1874,7 @@ phpdbg_main: /* initialize from file */ PHPDBG_G(flags) |= PHPDBG_IS_INITIALIZING; zend_try { - if (init_file) { - phpdbg_init(init_file, init_file_len, init_file_default); - } + phpdbg_init(init_file, init_file_len, init_file_default); } zend_end_try(); PHPDBG_G(flags) &= ~PHPDBG_IS_INITIALIZING; @@ -1938,7 +1937,7 @@ phpdbg_main: if (PHPDBG_G(ops)) { phpdbg_print_opcodes(print_opline_func); } else { - quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("No opcodes could be compiled | No file specified or compilation failed?\n")); + zend_quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("No opcodes could be compiled | No file specified or compilation failed?\n")); } goto phpdbg_out; } diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h index 94c5471e22..3df2be0aed 100644 --- a/sapi/phpdbg/phpdbg.h +++ b/sapi/phpdbg/phpdbg.h @@ -113,8 +113,6 @@ #define memcpy(...) memcpy_tmp(__VA_ARGS__) #endif -#define quiet_write(...) ZEND_IGNORE_VALUE(write(__VA_ARGS__)) - #if !defined(PHPDBG_WEBDATA_TRANSFER_H) && !defined(PHPDBG_WEBHELPER_H) #ifdef ZTS diff --git a/sapi/phpdbg/phpdbg_io.c b/sapi/phpdbg/phpdbg_io.c index b2f4ba7c0d..65a14d0ccb 100644 --- a/sapi/phpdbg/phpdbg_io.c +++ b/sapi/phpdbg/phpdbg_io.c @@ -149,7 +149,7 @@ recv_once: #endif if (got_now == -1) { - quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Read operation timed out!\n")); + zend_quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Read operation timed out!\n")); return -1; } i -= got_now; @@ -203,7 +203,7 @@ static int phpdbg_output_pager(int sock, const char *ptr, int len) { if (memchr(p, '\n', endp - p)) { char buf[PHPDBG_MAX_CMD]; - write(sock, ZEND_STRL("\r---Type <return> to continue or q <return> to quit---")); + zend_quiet_write(sock, ZEND_STRL("\r---Type <return> to continue or q <return> to quit---")); phpdbg_consume_stdin_line(buf); if (*buf == 'q') { break; @@ -305,7 +305,7 @@ PHPDBG_API int phpdbg_create_listenable_socket(const char *addr, unsigned short wrote = snprintf(buf, 128, "Could not translate address '%s'", addr); buf[wrote] = '\0'; - quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf)); + zend_quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf)); return sock; } else { @@ -315,7 +315,7 @@ PHPDBG_API int phpdbg_create_listenable_socket(const char *addr, unsigned short wrote = snprintf(buf, 256, "Host '%s' not found. %s", addr, estrdup(gai_strerror(rc))); buf[wrote] = '\0'; - quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf)); + zend_quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf)); return sock; #ifndef PHP_WIN32 @@ -330,7 +330,7 @@ PHPDBG_API int phpdbg_create_listenable_socket(const char *addr, unsigned short wrote = sprintf(buf, "Unable to create socket"); buf[wrote] = '\0'; - quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf)); + zend_quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf)); return sock; } diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c index b0bb157f08..34e9187f52 100644 --- a/sapi/phpdbg/phpdbg_list.c +++ b/sapi/phpdbg/phpdbg_list.c @@ -235,21 +235,21 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) { phpdbg_file_source data, *dataptr; zend_file_handle fake; zend_op_array *ret; - char *filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename); + char *filename; uint line; char *bufptr, *endptr; - char resolved_path_buf[MAXPATHLEN]; if (zend_stream_fixup(file, &bufptr, &data.len) == FAILURE) { return PHPDBG_G(compile_file)(file, type); } + filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename); + data.buf = emalloc(data.len + ZEND_MMAP_AHEAD + 1); if (data.len > 0) { memcpy(data.buf, bufptr, data.len); } memset(data.buf + data.len, 0, ZEND_MMAP_AHEAD + 1); - data.filename = filename; data.line[0] = 0; memset(&fake, 0, sizeof(fake)); @@ -261,9 +261,6 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) { fake.opened_path = file->opened_path; *(dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint) * data.len)) = data; - if (VCWD_REALPATH(filename, resolved_path_buf)) { - filename = resolved_path_buf; - } for (line = 0, bufptr = data.buf - 1, endptr = data.buf + data.len; ++bufptr < endptr;) { if (*bufptr == '\n') { @@ -285,10 +282,9 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) { return NULL; } - dataptr->filename = estrdup(dataptr->filename); dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line); - zend_hash_str_add_ptr(&PHPDBG_G(file_sources), filename, strlen(filename), dataptr); - phpdbg_resolve_pending_file_break(filename); + zend_hash_add_ptr(&PHPDBG_G(file_sources), ret->filename, dataptr); + phpdbg_resolve_pending_file_break(ZSTR_VAL(ret->filename)); fake.opened_path = NULL; zend_file_handle_dtor(&fake); @@ -323,7 +319,7 @@ zend_op_array *phpdbg_init_compile_file(zend_file_handle *file, int type) { return NULL; } - dataptr = zend_hash_str_find_ptr(&PHPDBG_G(file_sources), filename, strlen(filename)); + dataptr = zend_hash_find_ptr(&PHPDBG_G(file_sources), op_array->filename); ZEND_ASSERT(dataptr != NULL); dataptr->op_array = *op_array; @@ -370,7 +366,6 @@ zend_op_array *phpdbg_compile_string(zval *source_string, char *filename) { dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line); zend_hash_add_ptr(&PHPDBG_G(file_sources), fake_name, dataptr); - dataptr->filename = estrndup(ZSTR_VAL(fake_name), ZSTR_LEN(fake_name)); zend_string_release(fake_name); dataptr->op_array = *op_array; @@ -387,7 +382,6 @@ void phpdbg_free_file_source(zval *zv) { if (data->buf) { efree(data->buf); } - efree(data->filename); destroy_op_array(&data->op_array); diff --git a/sapi/phpdbg/phpdbg_list.h b/sapi/phpdbg/phpdbg_list.h index c011b9598a..62ded66cf0 100644 --- a/sapi/phpdbg/phpdbg_list.h +++ b/sapi/phpdbg/phpdbg_list.h @@ -42,7 +42,6 @@ void phpdbg_init_list(void); void phpdbg_list_update(void); typedef struct { - char *filename; char *buf; size_t len; #if HAVE_MMAP diff --git a/sapi/phpdbg/phpdbg_parser.c b/sapi/phpdbg/phpdbg_parser.c index d68c0ff441..da08df2199 100644 --- a/sapi/phpdbg/phpdbg_parser.c +++ b/sapi/phpdbg/phpdbg_parser.c @@ -70,7 +70,7 @@ /* Copy the first part of user declarations. */ /* Line 371 of yacc.c */ -#line 1 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 1 "sapi/phpdbg/phpdbg_parser.y" /* @@ -134,7 +134,7 @@ extern int phpdbg_debug; #endif /* "%code requires" blocks. */ /* Line 387 of yacc.c */ -#line 36 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 36 "sapi/phpdbg/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -1469,49 +1469,49 @@ yyreduce: { case 2: /* Line 1802 of yacc.c */ -#line 71 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 71 "sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 3: /* Line 1802 of yacc.c */ -#line 72 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 72 "sapi/phpdbg/phpdbg_parser.y" { phpdbg_stack_separate((yyvsp[(1) - (3)]).top); (yyval) = (yyvsp[(3) - (3)]); } break; case 5: /* Line 1802 of yacc.c */ -#line 77 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 77 "sapi/phpdbg/phpdbg_parser.y" { (yyval).top = PHPDBG_G(parser_stack)->top; } break; case 6: /* Line 1802 of yacc.c */ -#line 78 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 78 "sapi/phpdbg/phpdbg_parser.y" { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); (yyval).top = PHPDBG_G(parser_stack)->top; } break; case 7: /* Line 1802 of yacc.c */ -#line 82 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 82 "sapi/phpdbg/phpdbg_parser.y" { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); (yyval).top = PHPDBG_G(parser_stack)->top; } break; case 8: /* Line 1802 of yacc.c */ -#line 83 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 83 "sapi/phpdbg/phpdbg_parser.y" { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(2) - (2)])); (yyval).top = PHPDBG_G(parser_stack)->top; } break; case 9: /* Line 1802 of yacc.c */ -#line 84 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 84 "sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (2)]); } break; case 10: /* Line 1802 of yacc.c */ -#line 88 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 88 "sapi/phpdbg/phpdbg_parser.y" { (yyval).type = FILE_PARAM; (yyval).file.name = (yyvsp[(2) - (3)]).str; @@ -1521,7 +1521,7 @@ yyreduce: case 11: /* Line 1802 of yacc.c */ -#line 93 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 93 "sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_FILE_PARAM; (yyval).file.name = (yyvsp[(1) - (4)]).str; @@ -1531,7 +1531,7 @@ yyreduce: case 12: /* Line 1802 of yacc.c */ -#line 98 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 98 "sapi/phpdbg/phpdbg_parser.y" { (yyval).type = FILE_PARAM; (yyval).file.name = malloc((yyvsp[(1) - (4)]).len + (yyvsp[(2) - (4)]).len + 1); @@ -1546,7 +1546,7 @@ yyreduce: case 13: /* Line 1802 of yacc.c */ -#line 108 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 108 "sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_FILE_PARAM; (yyval).file.name = malloc((yyvsp[(1) - (5)]).len + (yyvsp[(2) - (5)]).len + 1); @@ -1561,7 +1561,7 @@ yyreduce: case 14: /* Line 1802 of yacc.c */ -#line 118 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 118 "sapi/phpdbg/phpdbg_parser.y" { (yyval).type = METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (3)]).str; @@ -1571,7 +1571,7 @@ yyreduce: case 15: /* Line 1802 of yacc.c */ -#line 123 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 123 "sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (5)]).str; @@ -1582,7 +1582,7 @@ yyreduce: case 16: /* Line 1802 of yacc.c */ -#line 129 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 129 "sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_FUNCTION_PARAM; (yyval).str = (yyvsp[(1) - (3)]).str; @@ -1593,7 +1593,7 @@ yyreduce: case 17: /* Line 1802 of yacc.c */ -#line 135 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 135 "sapi/phpdbg/phpdbg_parser.y" { (yyval).type = COND_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; @@ -1603,55 +1603,55 @@ yyreduce: case 18: /* Line 1802 of yacc.c */ -#line 140 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 140 "sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 19: /* Line 1802 of yacc.c */ -#line 141 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 141 "sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 20: /* Line 1802 of yacc.c */ -#line 142 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 142 "sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 21: /* Line 1802 of yacc.c */ -#line 143 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 143 "sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 22: /* Line 1802 of yacc.c */ -#line 144 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 144 "sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 23: /* Line 1802 of yacc.c */ -#line 145 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 145 "sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 24: /* Line 1802 of yacc.c */ -#line 146 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 146 "sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 25: /* Line 1802 of yacc.c */ -#line 150 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 150 "sapi/phpdbg/phpdbg_parser.y" { PHPDBG_G(req_id) = (yyvsp[(1) - (1)]).num; } break; case 27: /* Line 1802 of yacc.c */ -#line 155 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 155 "sapi/phpdbg/phpdbg_parser.y" { (yyval).type = EVAL_PARAM; (yyval).str = (yyvsp[(3) - (3)]).str; @@ -1661,7 +1661,7 @@ yyreduce: case 28: /* Line 1802 of yacc.c */ -#line 160 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 160 "sapi/phpdbg/phpdbg_parser.y" { (yyval).type = SHELL_PARAM; (yyval).str = (yyvsp[(3) - (3)]).str; @@ -1671,7 +1671,7 @@ yyreduce: case 29: /* Line 1802 of yacc.c */ -#line 165 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 165 "sapi/phpdbg/phpdbg_parser.y" { (yyval).type = RUN_PARAM; (yyval).len = 0; @@ -1680,7 +1680,7 @@ yyreduce: case 30: /* Line 1802 of yacc.c */ -#line 169 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 169 "sapi/phpdbg/phpdbg_parser.y" { (yyval).type = RUN_PARAM; (yyval).str = (yyvsp[(3) - (3)]).str; @@ -1922,7 +1922,7 @@ yyreturn: /* Line 2050 of yacc.c */ -#line 176 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 176 "sapi/phpdbg/phpdbg_parser.y" static int yyerror(const char *msg) { diff --git a/sapi/phpdbg/phpdbg_parser.h b/sapi/phpdbg/phpdbg_parser.h index 38d3ecbf70..d13cfbc0a5 100644 --- a/sapi/phpdbg/phpdbg_parser.h +++ b/sapi/phpdbg/phpdbg_parser.h @@ -41,7 +41,7 @@ extern int phpdbg_debug; #endif /* "%code requires" blocks. */ /* Line 2060 of yacc.c */ -#line 36 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" +#line 36 "sapi/phpdbg/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index c126ce2029..450e57d02e 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -349,7 +349,9 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default) /* {{{ */ { - if (!init_file && use_default) { + if (init_file) { + phpdbg_try_file_init(init_file, init_file_len, 1); + } else if (use_default) { char *scan_dir = getenv("PHP_INI_SCAN_DIR"); char *sys_ini; int i; @@ -382,8 +384,6 @@ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default) / } phpdbg_try_file_init(PHPDBG_STRL(PHPDBG_INIT_FILENAME), 0); - } else { - phpdbg_try_file_init(init_file, init_file_len, 1); } } /* }}} */ @@ -544,6 +544,7 @@ int phpdbg_compile_stdin(zend_string *code) { PHPDBG_G(exec_len) = 1; { /* remove leading ?> from source */ int i; + /* remove trailing data after zero byte, used for avoiding conflicts in eval()'ed code snippets */ zend_string *source_path = strpprintf(0, "-%c%p", 0, PHPDBG_G(ops)->opcodes); phpdbg_file_source *data = zend_hash_find_ptr(&PHPDBG_G(file_sources), source_path); dtor_func_t dtor = PHPDBG_G(file_sources).pDestructor; @@ -553,9 +554,6 @@ int phpdbg_compile_stdin(zend_string *code) { zend_hash_str_update_ptr(&PHPDBG_G(file_sources), "-", 1, data); zend_string_release(source_path); - efree(data->filename); - data->filename = estrdup("-"); - for (i = 1; i <= data->lines; i++) { data->line[i] -= 2; } @@ -572,7 +570,10 @@ int phpdbg_compile(void) /* {{{ */ { zend_file_handle fh; char *buf; + char *start_line = NULL; size_t len; + size_t start_line_len; + int i; if (!PHPDBG_G(exec)) { phpdbg_error("inactive", "type=\"nocontext\"", "No execution context"); @@ -591,7 +592,10 @@ int phpdbg_compile(void) /* {{{ */ } case '\n': CG(start_lineno) = 2; - fh.handle.stream.mmap.len -= fh.handle.stream.mmap.buf - buf; + start_line_len = fh.handle.stream.mmap.buf - buf; + start_line = emalloc(start_line_len); + memcpy(start_line, buf, start_line_len); + fh.handle.stream.mmap.len -= start_line_len; end = fh.handle.stream.mmap.buf; } } while (fh.handle.stream.mmap.buf + 1 < end); @@ -599,6 +603,29 @@ int phpdbg_compile(void) /* {{{ */ PHPDBG_G(ops) = zend_compile_file(&fh, ZEND_INCLUDE); + /* prepend shebang line to file_source */ + if (start_line) { + phpdbg_file_source *data = zend_hash_find_ptr(&PHPDBG_G(file_sources), PHPDBG_G(ops)->filename); + + dtor_func_t dtor = PHPDBG_G(file_sources).pDestructor; + PHPDBG_G(file_sources).pDestructor = NULL; + zend_hash_del(&PHPDBG_G(file_sources), PHPDBG_G(ops)->filename); + PHPDBG_G(file_sources).pDestructor = dtor; + + data = erealloc(data, sizeof(phpdbg_file_source) + sizeof(uint) * ++data->lines); + memmove(data->line + 1, data->line, sizeof(uint) * data->lines); + data->line[0] = 0; + data->buf = erealloc(data->buf, data->len + start_line_len); + memmove(data->buf + start_line_len, data->buf, data->len * sizeof(uint)); + memcpy(data->buf, start_line, start_line_len); + efree(start_line); + data->len += start_line_len; + for (i = 1; i <= data->lines; i++) { + data->line[i] += start_line_len; + } + zend_hash_update_ptr(&PHPDBG_G(file_sources), PHPDBG_G(ops)->filename, data); + } + fh.handle.stream.mmap.buf = buf; fh.handle.stream.mmap.len = len; zend_destroy_file_handle(&fh); diff --git a/sapi/phpdbg/phpdbg_sigsafe.c b/sapi/phpdbg/phpdbg_sigsafe.c index 2f987b3a15..081d864c5c 100644 --- a/sapi/phpdbg/phpdbg_sigsafe.c +++ b/sapi/phpdbg/phpdbg_sigsafe.c @@ -13,13 +13,13 @@ static void* zend_mm_mem_alloc(zend_mm_storage *storage, size_t size, size_t ali return (void *) (((size_t) PHPDBG_G(sigsafe_mem).mem & ~(alignment - 1)) + alignment); } - quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Tried to allocate more than " EXP_STR(PHPDBG_SIGSAFE_MEM_SIZE) " bytes from stack memory in signal handler ... bailing out of signal handler\n")); + zend_quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Tried to allocate more than " EXP_STR(PHPDBG_SIGSAFE_MEM_SIZE) " bytes from stack memory in signal handler ... bailing out of signal handler\n")); if (*EG(bailout)) { LONGJMP(*EG(bailout), FAILURE); } - quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Bailed out without a bailout address in signal handler!\n")); + zend_quiet_write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Bailed out without a bailout address in signal handler!\n")); return NULL; } diff --git a/sapi/phpdbg/tests/bug73615.phpt b/sapi/phpdbg/tests/bug73615.phpt new file mode 100644 index 0000000000..e5fccef0a8 --- /dev/null +++ b/sapi/phpdbg/tests/bug73615.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #73615 (phpdbg without option never load .phpdbginit at startup) +--SKIPIF-- +<?php +if (!getenv('TEST_PHPDBG_EXECUTABLE')) die("SKIP: No TEST_PHPDBG_EXECUTABLE specified"); +?> +--FILE-- +<?php + +$phpdbg = getenv('TEST_PHPDBG_EXECUTABLE'); + +chdir(__DIR__."/bug73615"); + +print `$phpdbg -qn`; + +?> +--EXPECT-- +Executed .phpdbginit diff --git a/sapi/phpdbg/tests/bug73615/.phpdbginit b/sapi/phpdbg/tests/bug73615/.phpdbginit new file mode 100644 index 0000000000..29184ddf7c --- /dev/null +++ b/sapi/phpdbg/tests/bug73615/.phpdbginit @@ -0,0 +1,2 @@ +ev "Executed .phpdbginit" +q diff --git a/sapi/phpdbg/tests/bug73704.phpt b/sapi/phpdbg/tests/bug73704.phpt new file mode 100644 index 0000000000..a3ee92b126 --- /dev/null +++ b/sapi/phpdbg/tests/bug73704.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #73704 (phpdbg shows the wrong line in files with shebang) +--PHPDBG-- +list 6 +b 4 +r +c +q +--EXPECTF-- +[Successful compilation of %s] +prompt> 00001: #!/usr/bin/env php + 00002: <?php + 00003: + 00004: echo 1; + 00005: +prompt> [Breakpoint #0 added at %s:4] +prompt> [Breakpoint #0 at %s:4, hits: 1] +>00004: echo 1; + 00005: +prompt> 1 +[Script ended normally] +prompt> +--FILE-- +#!/usr/bin/env php +<?php + +echo 1; diff --git a/sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.inc b/sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.inc new file mode 100644 index 0000000000..4f4155715d --- /dev/null +++ b/sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.inc @@ -0,0 +1,6 @@ +<?php + +function foo() +{ + return '<result>'; // line 5 is executable +} diff --git a/sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.phpt b/sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.phpt new file mode 100644 index 0000000000..0ddbd6f527 --- /dev/null +++ b/sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.phpt @@ -0,0 +1,84 @@ +--TEST-- +Getting executable lines from custom wrappers +--PHPDBG-- +r +q +--EXPECTF-- +[Successful compilation of %s] +prompt> array(1) { + [5]=> + int(0) +} +[Script ended normally] +prompt> +--FILE-- +<?php + +/** + * This example demonstrates how phpdbg_get_executable() behaves differently + * when passed the 'files' option vs without, in the face of some mild abuse + * of stream wrappers. + */ + +/** + * First, we define a stream wrapper that simply maps to a real file on disk. + */ +final class StreamWrapper +{ + public function stream_open( + string $path, + string $mode, + int $options = 0, + string &$openedPath = null + ) : bool { + if ($mode[0] !== 'r') { + return false; + } + + list($scheme, $path) = explode('://', $path, 2); + + $stream = \fopen($path, $mode); + + if ($stream === false) { + return false; + } + + $this->stream = $stream; + + /** + * The $openedPath reference variable is assigned, indicating the + * *actual* path that was opened. This affects the behaviour of + * constants like __FILE__. + */ + $openedPath = \realpath($path); + + return true; + } + + public function stream_read(int $count) : string { return \fread($this->stream, $count); } + public function stream_close() : bool { return \fclose($this->stream); } + public function stream_eof() : bool { return \feof($this->stream); } + public function stream_stat() { return \fstat($this->stream); } + + private $stream = false; +} + +stream_wrapper_register('wrapper', StreamWrapper::class); + +/** + * Next, we include a PHP file that contains executable lines, via the stream + * wrapper. + */ +$filename = __DIR__ . '/phpdbg_get_executable_stream_wrapper.inc'; +require 'wrapper://' . $filename; + +/** + * If we call phpdbg_get_executable() and pass no options, the realpath of the + * included file is present in the array, but indicates no executable lines. + */ +$x = phpdbg_get_executable(); + +// We expect [5 => 0], but got an empty array ... +var_dump($x[$filename]); + +?> |
