Linux vps-61133.fhnet.fr 4.9.0-19-amd64 #1 SMP Debian 4.9.320-2 (2022-06-30) x86_64
Apache/2.4.25 (Debian)
Server IP : 93.113.207.21 & Your IP : 216.73.216.112
Domains :
Cant Read [ /etc/named.conf ]
User : www-data
Terminal
Auto Root
Create File
Create Folder
Localroot Suggester
Backdoor Destroyer
Readme
/
usr /
src /
php-7.4.33 /
sapi /
phpdbg /
Delete
Unzip
Name
Size
Permission
Date
Action
.libs
[ DIR ]
drwxr-xr-x
2024-03-12 14:36
tests
[ DIR ]
drwxrwxr-x
2022-10-31 11:36
.gdbinit
250
B
-rw-rw-r--
2022-10-31 11:36
.phpdbginit
2.53
KB
-rw-rw-r--
2022-10-31 11:36
CREDITS
45
B
-rw-rw-r--
2022-10-31 11:36
Makefile.frag
1.52
KB
-rw-rw-r--
2022-10-31 11:36
README.md
2.27
KB
-rw-rw-r--
2022-10-31 11:36
config.m4
3.26
KB
-rw-rw-r--
2022-10-31 11:36
config.w32
1.32
KB
-rw-rw-r--
2022-10-31 11:36
create-test.php
4.41
KB
-rwxrwxr-x
2022-10-31 11:36
phpdbg
44.03
MB
-rwxr-xr-x
2024-03-12 14:36
phpdbg.1
2.75
KB
-rw-r--r--
2024-03-12 14:19
phpdbg.1.in
2.8
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg.c
61.2
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg.h
13.01
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg.init.d
2.78
KB
-rwxrwxr-x
2022-10-31 11:36
phpdbg.lo
321
B
-rw-r--r--
2024-03-12 14:36
phpdbg.o
334.69
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_bp.c
57.47
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_bp.h
6.12
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_bp.lo
330
B
-rw-r--r--
2024-03-12 14:36
phpdbg_bp.o
272.08
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_break.c
2.14
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_break.h
1.57
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_break.lo
339
B
-rw-r--r--
2024-03-12 14:36
phpdbg_break.o
87.73
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_btree.c
7.38
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_btree.h
2.97
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_btree.lo
339
B
-rw-r--r--
2024-03-12 14:36
phpdbg_btree.o
90.02
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_cmd.c
20.43
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_cmd.h
6.13
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_cmd.lo
333
B
-rw-r--r--
2024-03-12 14:36
phpdbg_cmd.o
152.28
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_eol.c
4.25
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_eol.h
1.55
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_eol.lo
333
B
-rw-r--r--
2024-03-12 14:36
phpdbg_eol.o
97.85
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_frame.c
10.13
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_frame.h
1.57
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_frame.lo
339
B
-rw-r--r--
2024-03-12 14:36
phpdbg_frame.o
150.81
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_help.c
39.09
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_help.h
2
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_help.lo
336
B
-rw-r--r--
2024-03-12 14:36
phpdbg_help.o
133.85
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_info.c
16.92
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_info.h
1.68
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_info.lo
336
B
-rw-r--r--
2024-03-12 14:36
phpdbg_info.o
152.36
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_io.c
7.9
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_io.h
1.92
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_io.lo
330
B
-rw-r--r--
2024-03-12 14:36
phpdbg_io.o
109.7
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_lexer.c
44.53
KB
-rw-r--r--
2022-10-31 11:36
phpdbg_lexer.h
1.71
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_lexer.l
3.81
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_lexer.lo
339
B
-rw-r--r--
2024-03-12 14:36
phpdbg_lexer.o
130.77
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_list.c
11.73
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_list.h
2.02
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_list.lo
336
B
-rw-r--r--
2024-03-12 14:36
phpdbg_list.o
124.72
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_opcode.c
6.47
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_opcode.h
1.98
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_opcode.lo
342
B
-rw-r--r--
2024-03-12 14:36
phpdbg_opcode.o
122.3
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_out.c
29.95
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_out.h
4.88
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_out.lo
333
B
-rw-r--r--
2024-03-12 14:36
phpdbg_out.o
190.24
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_parser.c
49.46
KB
-rw-r--r--
2022-10-31 11:36
phpdbg_parser.h
2.56
KB
-rw-r--r--
2022-10-31 11:36
phpdbg_parser.lo
342
B
-rw-r--r--
2024-03-12 14:36
phpdbg_parser.o
116.58
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_parser.output
14.23
KB
-rw-r--r--
2022-10-31 11:36
phpdbg_parser.y
4.35
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_print.c
14.06
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_print.h
1.69
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_print.lo
339
B
-rw-r--r--
2024-03-12 14:36
phpdbg_print.o
157.36
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_prompt.c
55.94
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_prompt.h
2.59
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_prompt.lo
342
B
-rw-r--r--
2024-03-12 14:36
phpdbg_prompt.o
299.74
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_rinit_hook.c
3.54
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_rinit_hook.h
1.82
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_set.c
9.59
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_set.h
1.71
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_set.lo
333
B
-rw-r--r--
2024-03-12 14:36
phpdbg_set.o
113.42
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_sigio_win32.c
2.9
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_sigio_win32.h
1.41
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_sigsafe.c
1.56
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_sigsafe.h
457
B
-rw-rw-r--
2022-10-31 11:36
phpdbg_sigsafe.lo
345
B
-rw-r--r--
2024-03-12 14:36
phpdbg_sigsafe.o
90.7
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_utils.c
23.21
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_utils.h
5.19
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_utils.lo
339
B
-rw-r--r--
2024-03-12 14:36
phpdbg_utils.o
173.69
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_wait.c
13.37
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_wait.h
1.3
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_wait.lo
336
B
-rw-r--r--
2024-03-12 14:36
phpdbg_wait.o
131.2
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_watch.c
54.1
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_watch.h
4.74
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_watch.lo
339
B
-rw-r--r--
2024-03-12 14:36
phpdbg_watch.o
226.91
KB
-rw-r--r--
2024-03-12 14:36
phpdbg_webdata_transfer.c
5.21
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_webdata_transfer.h
1.33
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_win.c
1.85
KB
-rw-rw-r--
2022-10-31 11:36
phpdbg_win.h
1.58
KB
-rw-rw-r--
2022-10-31 11:36
test.php
1.18
KB
-rw-rw-r--
2022-10-31 11:36
web-bootstrap.php
2.06
KB
-rw-rw-r--
2022-10-31 11:36
xml.md
20.03
KB
-rw-rw-r--
2022-10-31 11:36
Save
Rename
/* +----------------------------------------------------------------------+ | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Felipe Pena <felipe@php.net> | | Authors: Joe Watkins <joe.watkins@live.co.uk> | | Authors: Bob Weinand <bwoebi@php.net> | +----------------------------------------------------------------------+ */ #include "phpdbg.h" #include "phpdbg_cmd.h" #include "phpdbg_utils.h" #include "phpdbg_set.h" #include "phpdbg_prompt.h" #include "phpdbg_io.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg) static inline const char *phpdbg_command_name(const phpdbg_command_t *command, char *buffer) { size_t pos = 0; if (command->parent) { memcpy(&buffer[pos], command->parent->name, command->parent->name_len); pos += command->parent->name_len; memcpy(&buffer[pos], " ", sizeof(" ")-1); pos += (sizeof(" ")-1); } memcpy(&buffer[pos], command->name, command->name_len); pos += command->name_len; buffer[pos] = 0; return buffer; } PHPDBG_API const char *phpdbg_get_param_type(const phpdbg_param_t *param) /* {{{ */ { switch (param->type) { case STACK_PARAM: return "stack"; case EMPTY_PARAM: return "empty"; case ADDR_PARAM: return "address"; case NUMERIC_PARAM: return "numeric"; case METHOD_PARAM: return "method"; case NUMERIC_FUNCTION_PARAM: return "function opline"; case NUMERIC_METHOD_PARAM: return "method opline"; case FILE_PARAM: return "file or file opline"; case STR_PARAM: return "string"; default: /* this is bad */ return "unknown"; } } PHPDBG_API void phpdbg_clear_param(phpdbg_param_t *param) /* {{{ */ { if (param) { switch (param->type) { case FILE_PARAM: efree(param->file.name); break; case METHOD_PARAM: efree(param->method.class); efree(param->method.name); break; case STR_PARAM: efree(param->str); break; default: break; } } } /* }}} */ PHPDBG_API char* phpdbg_param_tostring(const phpdbg_param_t *param, char **pointer) /* {{{ */ { switch (param->type) { case STR_PARAM: ZEND_IGNORE_VALUE(asprintf(pointer, "%s", param->str)); break; case ADDR_PARAM: ZEND_IGNORE_VALUE(asprintf(pointer, ZEND_ULONG_FMT, param->addr)); break; case NUMERIC_PARAM: ZEND_IGNORE_VALUE(asprintf(pointer, "%li", param->num)); break; case METHOD_PARAM: ZEND_IGNORE_VALUE(asprintf(pointer, "%s::%s", param->method.class, param->method.name)); break; case FILE_PARAM: if (param->num) { ZEND_IGNORE_VALUE(asprintf(pointer, "%s:%lu#%lu", param->file.name, param->file.line, param->num)); } else { ZEND_IGNORE_VALUE(asprintf(pointer, "%s:%lu", param->file.name, param->file.line)); } break; case NUMERIC_FUNCTION_PARAM: ZEND_IGNORE_VALUE(asprintf(pointer, "%s#%lu", param->str, param->num)); break; case NUMERIC_METHOD_PARAM: ZEND_IGNORE_VALUE(asprintf(pointer, "%s::%s#%lu", param->method.class, param->method.name, param->num)); break; default: *pointer = strdup("unknown"); } return *pointer; } /* }}} */ PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t* src, phpdbg_param_t* dest) /* {{{ */ { switch ((dest->type = src->type)) { case STACK_PARAM: /* nope */ break; case STR_PARAM: dest->str = estrndup(src->str, src->len); dest->len = src->len; break; case OP_PARAM: dest->str = estrndup(src->str, src->len); dest->len = src->len; break; case ADDR_PARAM: dest->addr = src->addr; break; case NUMERIC_PARAM: dest->num = src->num; break; case METHOD_PARAM: dest->method.class = estrdup(src->method.class); dest->method.name = estrdup(src->method.name); break; case NUMERIC_FILE_PARAM: case FILE_PARAM: dest->file.name = estrdup(src->file.name); dest->file.line = src->file.line; if (src->num) dest->num = src->num; break; case NUMERIC_FUNCTION_PARAM: dest->str = estrndup(src->str, src->len); dest->num = src->num; dest->len = src->len; break; case NUMERIC_METHOD_PARAM: dest->method.class = estrdup(src->method.class); dest->method.name = estrdup(src->method.name); dest->num = src->num; break; case EMPTY_PARAM: { /* do nothing */ } break; default: { /* not yet */ } } } /* }}} */ PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t *param) /* {{{ */ { zend_ulong hash = param->type; switch (param->type) { case STACK_PARAM: /* nope */ break; case STR_PARAM: hash += zend_inline_hash_func(param->str, param->len); break; case METHOD_PARAM: hash += zend_inline_hash_func(param->method.class, strlen(param->method.class)); hash += zend_inline_hash_func(param->method.name, strlen(param->method.name)); break; case FILE_PARAM: hash += zend_inline_hash_func(param->file.name, strlen(param->file.name)); hash += param->file.line; if (param->num) hash += param->num; break; case ADDR_PARAM: hash += param->addr; break; case NUMERIC_PARAM: hash += param->num; break; case NUMERIC_FUNCTION_PARAM: hash += zend_inline_hash_func(param->str, param->len); hash += param->num; break; case NUMERIC_METHOD_PARAM: hash += zend_inline_hash_func(param->method.class, strlen(param->method.class)); hash += zend_inline_hash_func(param->method.name, strlen(param->method.name)); if (param->num) hash+= param->num; break; case EMPTY_PARAM: { /* do nothing */ } break; default: { /* not yet */ } } return hash; } /* }}} */ PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *l, const phpdbg_param_t *r) /* {{{ */ { if (l && r) { if (l->type == r->type) { switch (l->type) { case STACK_PARAM: /* nope, or yep */ return 1; break; case NUMERIC_FUNCTION_PARAM: if (l->num != r->num) { break; } /* break intentionally omitted */ case STR_PARAM: return (l->len == r->len) && (memcmp(l->str, r->str, l->len) == SUCCESS); case NUMERIC_PARAM: return (l->num == r->num); case ADDR_PARAM: return (l->addr == r->addr); case FILE_PARAM: { if (l->file.line == r->file.line) { size_t lengths[2] = { strlen(l->file.name), strlen(r->file.name)}; if (lengths[0] == lengths[1]) { if ((!l->num && !r->num) || (l->num == r->num)) { return (memcmp( l->file.name, r->file.name, lengths[0]) == SUCCESS); } } } } break; case NUMERIC_METHOD_PARAM: if (l->num != r->num) { break; } /* break intentionally omitted */ case METHOD_PARAM: { size_t lengths[2] = { strlen(l->method.class), strlen(r->method.class)}; if (lengths[0] == lengths[1]) { if (memcmp(l->method.class, r->method.class, lengths[0]) == SUCCESS) { lengths[0] = strlen(l->method.name); lengths[1] = strlen(r->method.name); if (lengths[0] == lengths[1]) { return (memcmp( l->method.name, r->method.name, lengths[0]) == SUCCESS); } } } } break; case EMPTY_PARAM: return 1; default: { /* not yet */ } } } } return 0; } /* }}} */ /* {{{ */ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) { if (param && param->type) { switch (param->type) { case STR_PARAM: fprintf(stderr, "%s STR_PARAM(%s=%zu)\n", msg, param->str, param->len); break; case ADDR_PARAM: fprintf(stderr, "%s ADDR_PARAM(" ZEND_ULONG_FMT ")\n", msg, param->addr); break; case NUMERIC_FILE_PARAM: fprintf(stderr, "%s NUMERIC_FILE_PARAM(%s:#%lu)\n", msg, param->file.name, param->file.line); break; case FILE_PARAM: fprintf(stderr, "%s FILE_PARAM(%s:%lu)\n", msg, param->file.name, param->file.line); break; case METHOD_PARAM: fprintf(stderr, "%s METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); break; case NUMERIC_METHOD_PARAM: fprintf(stderr, "%s NUMERIC_METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); break; case NUMERIC_FUNCTION_PARAM: fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%ld)\n", msg, param->str, param->num); break; case NUMERIC_PARAM: fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); break; case COND_PARAM: fprintf(stderr, "%s COND_PARAM(%s=%zu)\n", msg, param->str, param->len); break; case OP_PARAM: fprintf(stderr, "%s OP_PARAM(%s=%zu)\n", msg, param->str, param->len); break; default: { /* not yet */ } } } } /* }}} */ /* {{{ */ PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack) { if (stack && stack->next) { phpdbg_param_t *remove = stack->next; while (remove) { phpdbg_param_t *next = NULL; if (remove->next) next = remove->next; switch (remove->type) { case NUMERIC_METHOD_PARAM: case METHOD_PARAM: if (remove->method.class) { efree(remove->method.class); } if (remove->method.name) { efree(remove->method.name); } break; case NUMERIC_FUNCTION_PARAM: case STR_PARAM: case OP_PARAM: case EVAL_PARAM: case SHELL_PARAM: case COND_PARAM: case RUN_PARAM: if (remove->str) { efree(remove->str); } break; case NUMERIC_FILE_PARAM: case FILE_PARAM: if (remove->file.name) { efree(remove->file.name); } break; default: { /* nothing */ } } free(remove); remove = NULL; if (next) remove = next; else break; } } stack->next = NULL; } /* }}} */ /* {{{ */ PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { phpdbg_param_t *next = calloc(1, sizeof(phpdbg_param_t)); if (!next) { return; } *(next) = *(param); next->next = NULL; if (stack->top == NULL) { stack->top = next; next->top = NULL; stack->next = next; } else { stack->top->next = next; next->top = stack->top; stack->top = next; } stack->len++; } /* }}} */ /* {{{ */ PHPDBG_API void phpdbg_stack_separate(phpdbg_param_t *param) { phpdbg_param_t *stack = calloc(1, sizeof(phpdbg_param_t)); stack->type = STACK_PARAM; stack->next = param->next; param->next = stack; stack->top = param->top; } /* }}} */ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack) { if (command) { char buffer[128] = {0,}; const phpdbg_param_t *top = (stack != NULL) ? *stack : NULL; const char *arg = command->args; size_t least = 0L, received = 0L, current = 0L; zend_bool optional = 0; /* check for arg spec */ if (!(arg) || !(*arg)) { if (!top || top->type == STACK_PARAM) { return SUCCESS; } phpdbg_error("command", "type=\"toomanyargs\" command=\"%s\" expected=\"0\"", "The command \"%s\" expected no arguments", phpdbg_command_name(command, buffer)); return FAILURE; } least = 0L; /* count least amount of arguments */ while (arg && *arg) { if (arg[0] == '|') { break; } least++; arg++; } arg = command->args; #define verify_arg(e, a, t) if (!(a)) { \ if (!optional) { \ phpdbg_error("command", "type=\"noarg\" command=\"%s\" expected=\"%s\" num=\"%lu\"", "The command \"%s\" expected %s and got nothing at parameter %lu", \ phpdbg_command_name(command, buffer), \ (e), \ current); \ return FAILURE;\ } \ } else if ((a)->type != (t)) { \ phpdbg_error("command", "type=\"wrongarg\" command=\"%s\" expected=\"%s\" got=\"%s\" num=\"%lu\"", "The command \"%s\" expected %s and got %s at parameter %lu", \ phpdbg_command_name(command, buffer), \ (e),\ phpdbg_get_param_type((a)), \ current); \ return FAILURE; \ } while (arg && *arg) { if (top && top->type == STACK_PARAM) { break; } current++; switch (*arg) { case '|': { current--; optional = 1; arg++; } continue; case 'i': verify_arg("raw input", top, STR_PARAM); break; case 's': verify_arg("string", top, STR_PARAM); break; case 'n': verify_arg("number", top, NUMERIC_PARAM); break; case 'm': verify_arg("method", top, METHOD_PARAM); break; case 'a': verify_arg("address", top, ADDR_PARAM); break; case 'f': verify_arg("file:line", top, FILE_PARAM); break; case 'c': verify_arg("condition", top, COND_PARAM); break; case 'o': verify_arg("opcode", top, OP_PARAM); break; case 'b': verify_arg("boolean", top, NUMERIC_PARAM); break; case '*': { /* do nothing */ } break; } if (top) { top = top->next; } else { break; } received++; arg++; } #undef verify_arg if ((received < least)) { phpdbg_error("command", "type=\"toofewargs\" command=\"%s\" expected=\"%d\" argtypes=\"%s\" got=\"%d\"", "The command \"%s\" expected at least %lu arguments (%s) and received %lu", phpdbg_command_name(command, buffer), least, command->args, received); return FAILURE; } } return SUCCESS; } /* {{{ */ PHPDBG_API const phpdbg_command_t *phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top) { const phpdbg_command_t *command = commands; phpdbg_param_t *name = *top; const phpdbg_command_t *matched[3] = {NULL, NULL, NULL}; zend_ulong matches = 0L; while (command && command->name && command->handler) { if (name->len == 1 || command->name_len >= name->len) { /* match single letter alias */ if (command->alias && (name->len == 1)) { if (command->alias == (*name->str)) { matched[matches] = command; matches++; } } else { /* match full, case insensitive, command name */ if (strncasecmp(command->name, name->str, name->len) == SUCCESS) { if (matches < 3) { /* only allow abbreviating commands that can be aliased */ if ((name->len != command->name_len && command->alias) || name->len == command->name_len) { matched[matches] = command; matches++; } /* exact match */ if (name->len == command->name_len) { break; } } else { break; } } } } command++; } switch (matches) { case 0: if (parent) { phpdbg_error("command", "type=\"notfound\" command=\"%s\" subcommand=\"%s\"", "The command \"%s %s\" could not be found", parent->name, name->str); } else { phpdbg_error("command", "type=\"notfound\" command=\"%s\"", "The command \"%s\" could not be found", name->str); } return parent; case 1: (*top) = (*top)->next; command = matched[0]; break; default: { char *list = NULL; uint32_t it = 0; size_t pos = 0; while (it < matches) { if (!list) { list = emalloc(matched[it]->name_len + 1 + (it + 1 < matches ? sizeof(", ") - 1 : 0)); } else { list = erealloc(list, (pos + matched[it]->name_len) + 1 + (it + 1 < matches ? sizeof(", ") - 1 : 0)); } memcpy(&list[pos], matched[it]->name, matched[it]->name_len); pos += matched[it]->name_len; if ((it + 1) < matches) { memcpy(&list[pos], ", ", sizeof(", ") - 1); pos += (sizeof(", ") - 1); } list[pos] = 0; it++; } /* ", " separated matches */ phpdbg_error("command", "type=\"ambiguous\" command=\"%s\" matches=\"%lu\" matched=\"%s\"", "The command \"%s\" is ambiguous, matching %lu commands (%s)", name->str, matches, list); efree(list); return NULL; } } if (command->subs && (*top) && ((*top)->type == STR_PARAM)) { return phpdbg_stack_resolve(command->subs, command, top); } else { return command; } return NULL; } /* }}} */ static int phpdbg_internal_stack_execute(phpdbg_param_t *stack, zend_bool allow_async_unsafe) { const phpdbg_command_t *handler = NULL; phpdbg_param_t *top = (phpdbg_param_t *) stack->next; switch (top->type) { case EVAL_PARAM: phpdbg_activate_err_buf(0); phpdbg_free_err_buf(); return PHPDBG_COMMAND_HANDLER(ev)(top); case RUN_PARAM: if (!allow_async_unsafe) { phpdbg_error("signalsegv", "command=\"run\"", "run command is disallowed during hard interrupt"); } phpdbg_activate_err_buf(0); phpdbg_free_err_buf(); return PHPDBG_COMMAND_HANDLER(run)(top); case SHELL_PARAM: if (!allow_async_unsafe) { phpdbg_error("signalsegv", "command=\"sh\"", "sh command is disallowed during hard interrupt"); return FAILURE; } phpdbg_activate_err_buf(0); phpdbg_free_err_buf(); return PHPDBG_COMMAND_HANDLER(sh)(top); case STR_PARAM: { handler = phpdbg_stack_resolve(phpdbg_prompt_commands, NULL, &top); if (handler) { if (!allow_async_unsafe && !(handler->flags & PHPDBG_ASYNC_SAFE)) { phpdbg_error("signalsegv", "command=\"%s\"", "%s command is disallowed during hard interrupt", handler->name); return FAILURE; } if (phpdbg_stack_verify(handler, &top) == SUCCESS) { phpdbg_activate_err_buf(0); phpdbg_free_err_buf(); return handler->handler(top); } } } return FAILURE; default: phpdbg_error("command", "type=\"invalidcommand\"", "The first parameter makes no sense !"); return FAILURE; } return SUCCESS; } /* }}} */ /* {{{ */ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, zend_bool allow_async_unsafe) { phpdbg_param_t *top = stack; if (stack->type != STACK_PARAM) { phpdbg_error("command", "type=\"nostack\"", "The passed argument was not a stack !"); return FAILURE; } if (!stack->len) { phpdbg_error("command", "type=\"emptystack\"", "The stack contains nothing !"); return FAILURE; } do { if (top->type == STACK_PARAM) { int result; if ((result = phpdbg_internal_stack_execute(top, allow_async_unsafe)) != SUCCESS) { return result; } } } while ((top = top->next)); return SUCCESS; } /* }}} */ PHPDBG_API char *phpdbg_read_input(char *buffered) /* {{{ */ { char buf[PHPDBG_MAX_CMD]; char *cmd = NULL; char *buffer = NULL; if ((PHPDBG_G(flags) & (PHPDBG_IS_STOPPING | PHPDBG_IS_RUNNING)) != PHPDBG_IS_STOPPING) { if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) && (buffered == NULL) && !phpdbg_active_sigsafe_mem()) { fflush(PHPDBG_G(io)[PHPDBG_STDOUT].ptr); } if (buffered == NULL) { #ifdef HAVE_PHPDBG_READLINE /* note: EOF makes readline write prompt again in local console mode - and ignored if compiled without readline */ if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) || !isatty(PHPDBG_G(io)[PHPDBG_STDIN].fd)) #endif { phpdbg_write("prompt", "", "%s", phpdbg_get_prompt()); phpdbg_consume_stdin_line(cmd = buf); } #ifdef HAVE_PHPDBG_READLINE else { cmd = readline(phpdbg_get_prompt()); PHPDBG_G(last_was_newline) = 1; if (!cmd) { PHPDBG_G(flags) |= PHPDBG_IS_QUITTING | PHPDBG_IS_DISCONNECTED; zend_bailout(); } add_history(cmd); } #endif } else { cmd = buffered; } buffer = estrdup(cmd); #ifdef HAVE_PHPDBG_READLINE if (!buffered && cmd && !(PHPDBG_G(flags) & PHPDBG_IS_REMOTE) && isatty(PHPDBG_G(io)[PHPDBG_STDIN].fd)) { free(cmd); } #endif } if (buffer && isspace(*buffer)) { char *trimmed = buffer; while (isspace(*trimmed)) trimmed++; trimmed = estrdup(trimmed); efree(buffer); buffer = trimmed; } if (buffer && strlen(buffer)) { if (PHPDBG_G(buffer)) { free(PHPDBG_G(buffer)); } PHPDBG_G(buffer) = strdup(buffer); } else if (PHPDBG_G(buffer)) { if (buffer) { efree(buffer); } buffer = estrdup(PHPDBG_G(buffer)); } return buffer; } /* }}} */ PHPDBG_API void phpdbg_destroy_input(char **input) /*{{{ */ { efree(*input); } /* }}} */ PHPDBG_API int phpdbg_ask_user_permission(const char *question) { if (!(PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { char buf[PHPDBG_MAX_CMD]; phpdbg_out("%s", question); phpdbg_out(" (type y or n): "); while (1) { phpdbg_consume_stdin_line(buf); if ((buf[1] == '\n' || (buf[1] == '\r' && buf[2] == '\n')) && (buf[0] == 'y' || buf[0] == 'n')) { if (buf[0] == 'y') { return SUCCESS; } return FAILURE; } phpdbg_out("Please enter either y (yes) or n (no): "); } } return SUCCESS; }