Skip to content

Commit 37ae5f3

Browse files
committed
Merge branch 'PHP-7.0' into PHP-7.1
2 parents af1bf87 + 5aae011 commit 37ae5f3

File tree

11 files changed

+304
-46
lines changed

11 files changed

+304
-46
lines changed

run-tests.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@
127127
$phpdbg = $cwd . '/sapi/phpdbg/phpdbg';
128128

129129
if (file_exists($phpdbg)) {
130-
putenv("TEST_PHP_CGI_EXECUTABLE=$phpdbg");
130+
putenv("TEST_PHPDBG_EXECUTABLE=$phpdbg");
131131
} else {
132132
$phpdbg = null;
133133
}

sapi/phpdbg/phpdbg.c

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ static void php_phpdbg_destroy_file_source(zval *data) /* {{{ */
127127
if (source->buf) {
128128
efree(source->buf);
129129
}
130+
efree(source->filename);
130131
efree(source);
131132
} /* }}} */
132133

@@ -373,7 +374,7 @@ static PHP_FUNCTION(phpdbg_break_file)
373374
return;
374375
}
375376

376-
phpdbg_set_breakpoint_file(file, line);
377+
phpdbg_set_breakpoint_file(file, 0, line);
377378
} /* }}} */
378379

379380
/* {{{ proto void phpdbg_break_method(string class, string method) */
@@ -1076,6 +1077,7 @@ const opt_struct OPTIONS[] = { /* {{{ */
10761077
{'r', 0, "run"},
10771078
{'e', 0, "generate ext_stmt opcodes"},
10781079
{'E', 0, "step-through-eval"},
1080+
{'s', 1, "script from stdin"},
10791081
{'S', 1, "sapi-name"},
10801082
#ifndef _WIN32
10811083
{'l', 1, "listen"},
@@ -1374,6 +1376,8 @@ int main(int argc, char **argv) /* {{{ */
13741376
zend_bool ext_stmt = 0;
13751377
zend_bool is_exit;
13761378
int exit_status;
1379+
char *read_from_stdin = NULL;
1380+
zend_string *backup_phpdbg_compile = NULL;
13771381

13781382
#ifndef _WIN32
13791383
struct sigaction sigio_struct;
@@ -1482,6 +1486,12 @@ int main(int argc, char **argv) /* {{{ */
14821486

14831487
/* begin phpdbg options */
14841488

1489+
case 's': { /* read script from stdin */
1490+
if (settings == NULL) {
1491+
read_from_stdin = strdup(php_optarg);
1492+
}
1493+
} break;
1494+
14851495
case 'S': { /* set SAPI name */
14861496
sapi_name = strdup(php_optarg);
14871497
} break;
@@ -1593,8 +1603,10 @@ int main(int argc, char **argv) /* {{{ */
15931603
php_optarg = NULL;
15941604
}
15951605

1606+
quit_immediately = phpdbg_startup_run > 1;
1607+
15961608
/* set exec if present on command line */
1597-
if (argc > php_optind && (strcmp(argv[php_optind-1], "--") != SUCCESS)) {
1609+
if (!read_from_stdin && argc > php_optind && (strcmp(argv[php_optind-1], "--") != SUCCESS)) {
15981610
if (!exec && strlen(argv[php_optind])) {
15991611
exec = strdup(argv[php_optind]);
16001612
}
@@ -1849,13 +1861,6 @@ int main(int argc, char **argv) /* {{{ */
18491861
if (init_file) {
18501862
phpdbg_init(init_file, init_file_len, init_file_default);
18511863
}
1852-
if (bp_tmp) {
1853-
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
1854-
phpdbg_string_init(bp_tmp);
1855-
free(bp_tmp);
1856-
bp_tmp = NULL;
1857-
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
1858-
}
18591864
} zend_end_try();
18601865
PHPDBG_G(flags) &= ~PHPDBG_IS_INITIALIZING;
18611866

@@ -1865,18 +1870,55 @@ int main(int argc, char **argv) /* {{{ */
18651870
}
18661871

18671872
/* auto compile */
1868-
if (PHPDBG_G(exec)) {
1873+
if (read_from_stdin) {
1874+
if (!read_from_stdin[0]) {
1875+
if (!quit_immediately) {
1876+
phpdbg_error("error", "", "Impossible to not specify a stdin delimiter without -rr");
1877+
PHPDBG_G(flags) |= PHPDBG_IS_QUITTING;
1878+
goto phpdbg_out;
1879+
}
1880+
}
1881+
if (show_banner || read_from_stdin[0]) {
1882+
phpdbg_notice("stdin", "delimiter=\"%s\"", "Reading input from stdin; put '%s' followed by a newline on an own line after code to end input", read_from_stdin);
1883+
}
1884+
1885+
if (phpdbg_startup_run > 0) {
1886+
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
1887+
}
1888+
1889+
zend_try {
1890+
phpdbg_param_t cmd;
1891+
cmd.str = read_from_stdin;
1892+
cmd.len = strlen(read_from_stdin);
1893+
PHPDBG_COMMAND_HANDLER(stdin)(&cmd);
1894+
} zend_end_try();
1895+
1896+
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
1897+
} else if (PHPDBG_G(exec)) {
18691898
if (settings || phpdbg_startup_run > 0) {
18701899
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
18711900
}
18721901

18731902
zend_try {
1874-
phpdbg_compile();
1903+
if (backup_phpdbg_compile) {
1904+
phpdbg_compile_stdin(backup_phpdbg_compile);
1905+
} else {
1906+
phpdbg_compile();
1907+
}
18751908
} zend_end_try();
1909+
backup_phpdbg_compile = NULL;
18761910

18771911
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
18781912
}
18791913

1914+
if (bp_tmp) {
1915+
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT | PHPDBG_IS_INITIALIZING;
1916+
phpdbg_string_init(bp_tmp);
1917+
free(bp_tmp);
1918+
bp_tmp = NULL;
1919+
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT & ~PHPDBG_IS_INITIALIZING;
1920+
}
1921+
18801922
if (settings == (void *) 0x1) {
18811923
if (PHPDBG_G(ops)) {
18821924
phpdbg_print_opcodes(print_opline_func);
@@ -1898,7 +1940,6 @@ int main(int argc, char **argv) /* {{{ */
18981940
do {
18991941
zend_try {
19001942
if (phpdbg_startup_run) {
1901-
quit_immediately = phpdbg_startup_run > 1;
19021943
phpdbg_startup_run = 0;
19031944
if (quit_immediately) {
19041945
PHPDBG_G(flags) = (PHPDBG_G(flags) & ~PHPDBG_HAS_PAGINATION) | PHPDBG_IS_INTERACTIVE | PHPDBG_PREVENT_INTERACTIVE;
@@ -2073,6 +2114,12 @@ int main(int argc, char **argv) /* {{{ */
20732114
wrapper->wops->stream_opener = PHPDBG_G(orig_url_wrap_php);
20742115
}
20752116

2117+
if (PHPDBG_G(exec) && !memcmp("-", PHPDBG_G(exec), 2)) { /* i.e. execution context has been read from stdin - back it up */
2118+
phpdbg_file_source *data = zend_hash_str_find_ptr(&PHPDBG_G(file_sources), PHPDBG_G(exec), PHPDBG_G(exec_len));
2119+
backup_phpdbg_compile = zend_string_alloc(data->len + 2, 1);
2120+
sprintf(ZSTR_VAL(backup_phpdbg_compile), "?>%.*s", (int) data->len, data->buf);
2121+
}
2122+
20762123
zend_try {
20772124
php_module_shutdown();
20782125
} zend_end_try();
@@ -2097,6 +2144,11 @@ int main(int argc, char **argv) /* {{{ */
20972144
free(sapi_name);
20982145
}
20992146

2147+
if (read_from_stdin) {
2148+
free(read_from_stdin);
2149+
read_from_stdin = NULL;
2150+
}
2151+
21002152
#ifdef ZTS
21012153
tsrm_shutdown();
21022154
#endif
@@ -2108,6 +2160,10 @@ int main(int argc, char **argv) /* {{{ */
21082160
goto phpdbg_main;
21092161
}
21102162

2163+
if (backup_phpdbg_compile) {
2164+
zend_string_free(backup_phpdbg_compile);
2165+
}
2166+
21112167
#ifndef _WIN32
21122168
if (address) {
21132169
free(address);

sapi/phpdbg/phpdbg_bp.c

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ PHPDBG_API void phpdbg_export_breakpoints_to_string(char **str) /* {{{ */
230230
}
231231
} /* }}} */
232232

233-
PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num) /* {{{ */
233+
PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, size_t path_len, long line_num) /* {{{ */
234234
{
235235
php_stream_statbuf ssb;
236236
char realpath[MAXPATHLEN];
@@ -240,10 +240,11 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num) /* {
240240

241241
HashTable *broken, *file_breaks = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE];
242242
phpdbg_breakfile_t new_break;
243-
size_t path_len = 0L;
244243

245-
if (VCWD_REALPATH(path, realpath)) {
246-
path = realpath;
244+
if (!path_len) {
245+
if (VCWD_REALPATH(path, realpath)) {
246+
path = realpath;
247+
}
247248
}
248249
path_len = strlen(path);
249250

@@ -886,21 +887,13 @@ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_
886887
{
887888
HashTable *breaks;
888889
phpdbg_breakbase_t *brake;
889-
size_t path_len;
890-
char realpath[MAXPATHLEN];
891-
const char *path = ZSTR_VAL(op_array->filename);
892-
893-
if (VCWD_REALPATH(path, realpath)) {
894-
path = realpath;
895-
}
896-
897-
path_len = strlen(path);
898890

899891
#if 0
900-
phpdbg_debug("Op at: %.*s %d\n", path_len, path, (*EG(opline_ptr))->lineno);
892+
phpdbg_debug("Op at: %.*s %d\n", ZSTR_LEN(op_array->filename), ZSTR_VAL(op_array->filename), (*EG(opline_ptr))->lineno);
901893
#endif
902894

903-
if (!(breaks = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], path, path_len))) {
895+
/* NOTE: realpath resolution should have happened at compile time - no reason to do it here again */
896+
if (!(breaks = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], op_array->filename))) {
904897
return NULL;
905898
}
906899

sapi/phpdbg/phpdbg_bp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ PHPDBG_API HashTable *phpdbg_resolve_pending_file_break_ex(const char *file, uin
125125
PHPDBG_API void phpdbg_resolve_pending_file_break(const char *file); /* }}} */
126126

127127
/* {{{ Breakpoint Creation API */
128-
PHPDBG_API void phpdbg_set_breakpoint_file(const char* filename, long lineno);
128+
PHPDBG_API void phpdbg_set_breakpoint_file(const char* filename, size_t path_len, long lineno);
129129
PHPDBG_API void phpdbg_set_breakpoint_symbol(const char* func_name, size_t func_name_len);
130130
PHPDBG_API void phpdbg_set_breakpoint_method(const char* class_name, const char* func_name);
131131
PHPDBG_API void phpdbg_set_breakpoint_opcode(const char* opname, size_t opname_len);

sapi/phpdbg/phpdbg_help.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ phpdbg_help_text_t phpdbg_help_text[] = {
339339

340340
"**Starting and Stopping Execution**" CR
341341
" **exec** set execution context" CR
342+
" **stdin** set executing script from stdin" CR
342343
" **run** attempt execution" CR
343344
" **step** continue execution until other line is reached" CR
344345
" **continue** continue execution" CR
@@ -387,6 +388,7 @@ phpdbg_help_text_t phpdbg_help_text[] = {
387388
" **-rr** Run execution context and quit after execution (not respecting breakpoints)" CR
388389
" **-e** Generate extended information for debugger/profiler" CR
389390
" **-E** Enable step through eval, careful!" CR
391+
" **-s** **-s=**, **-s**=foo Read code to execute from stdin with an optional delimiter" CR
390392
" **-S** **-S**cli Override SAPI name, careful!" CR
391393
" **-l** **-l**4000 Setup remote console ports" CR
392394
" **-a** **-a**192.168.0.3 Setup remote console bind address" CR
@@ -397,6 +399,13 @@ phpdbg_help_text_t phpdbg_help_text[] = {
397399
" **--** **--** arg1 arg2 Use to delimit phpdbg arguments and php $argv; append any $argv "
398400
"argument after it" CR CR
399401

402+
"**Reading from stdin**" CR CR
403+
404+
"The **-s** option allows inputting a script to execute directly from stdin. The given delimiter "
405+
"(\"foo\" in the example) needs to be specified at the end of the input on its own line, followed by "
406+
"a line break. If **-rr** has been specified, it is allowed to omit the delimiter (**-s=**) and "
407+
"it will read until EOF. See also the help entry for the **stdin** command." CR CR
408+
400409
"**Remote Console Mode**" CR CR
401410

402411
"This mode is enabled by specifying the **-a** option. Phpdbg will bind only to the loopback "
@@ -635,6 +644,21 @@ phpdbg_help_text_t phpdbg_help_text[] = {
635644
" Set the execution context to **/tmp/script.php**"
636645
},
637646

647+
{"stdin",
648+
"The **stdin** command takes a string serving as delimiter. It will then read all the input from "
649+
"stdin until encountering the given delimiter on a standalone line. It can also be passed at "
650+
"startup using the **-s=** command line option (the delimiter then is optional if **-rr** is "
651+
"also passed - in that case it will just read until EOF)." CR
652+
"This input will be then compiled as PHP code and set as execution context." CR CR
653+
654+
"**Example**" CR CR
655+
656+
" $P stdin foo" CR
657+
" <?php" CR
658+
" echo \"Hello, world!\\n\";" CR
659+
" foo"
660+
},
661+
638662
//*********** Does F skip any breakpoints lower stack frames or only the current??
639663
{"finish",
640664
"The **finish** command causes control to be passed back to the vm, continuing execution. Any "

sapi/phpdbg/phpdbg_list.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,15 @@ PHPDBG_LIST(lines) /* {{{ */
6262
} break;
6363

6464
case FILE_PARAM: {
65-
zend_string *file = zend_string_init(param->file.name, strlen(param->file.name), 0);
65+
zend_string *file;
66+
char resolved_path_buf[MAXPATHLEN];
67+
const char *abspath = param->file.name;
68+
if (VCWD_REALPATH(abspath, resolved_path_buf)) {
69+
abspath = resolved_path_buf;
70+
}
71+
file = zend_string_init(abspath, strlen(abspath), 0);
6672
phpdbg_list_file(file, param->file.line, 0, 0);
67-
efree(file);
73+
zend_string_release(file);
6874
} break;
6975

7076
phpdbg_default_switch_case();
@@ -127,16 +133,8 @@ void phpdbg_list_file(zend_string *filename, uint count, int offset, uint highli
127133
{
128134
uint line, lastline;
129135
phpdbg_file_source *data;
130-
char resolved_path_buf[MAXPATHLEN];
131-
const char *abspath;
132-
133-
if (VCWD_REALPATH(ZSTR_VAL(filename), resolved_path_buf)) {
134-
abspath = resolved_path_buf;
135-
} else {
136-
abspath = ZSTR_VAL(filename);
137-
}
138136

139-
if (!(data = zend_hash_str_find_ptr(&PHPDBG_G(file_sources), abspath, strlen(abspath)))) {
137+
if (!(data = zend_hash_find_ptr(&PHPDBG_G(file_sources), filename))) {
140138
phpdbg_error("list", "type=\"unknownfile\"", "Could not find information about included file...");
141139
return;
142140
}
@@ -288,6 +286,7 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
288286
return NULL;
289287
}
290288

289+
dataptr->filename = estrdup(dataptr->filename);
291290
dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line);
292291
zend_hash_str_add_ptr(&PHPDBG_G(file_sources), filename, strlen(filename), dataptr);
293292
phpdbg_resolve_pending_file_break(filename);
@@ -306,6 +305,17 @@ zend_op_array *phpdbg_init_compile_file(zend_file_handle *file, int type) {
306305

307306
if (VCWD_REALPATH(filename, resolved_path_buf)) {
308307
filename = resolved_path_buf;
308+
309+
if (file->opened_path) {
310+
zend_string_release(file->opened_path);
311+
file->opened_path = zend_string_init(filename, strlen(filename), 0);
312+
} else {
313+
if (file->free_filename) {
314+
efree((char *) file->filename);
315+
}
316+
file->free_filename = 1;
317+
file->filename = estrdup(filename);
318+
}
309319
}
310320

311321
op_array = PHPDBG_G(init_compile_file)(file, type);
@@ -356,7 +366,7 @@ zend_op_array *phpdbg_compile_string(zval *source_string, char *filename) {
356366
return NULL;
357367
}
358368

359-
fake_name = strpprintf(0, "%s\0%p", filename, op_array->opcodes);
369+
fake_name = strpprintf(0, "%s%c%p", filename, 0, op_array->opcodes);
360370

361371
dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line);
362372
zend_hash_add_ptr(&PHPDBG_G(file_sources), fake_name, dataptr);

0 commit comments

Comments
 (0)