summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--Zend/tests/bug68262.phpt24
-rw-r--r--Zend/zend.c12
-rw-r--r--Zend/zend.h6
-rw-r--r--Zend/zend_API.c108
-rw-r--r--Zend/zend_API.h98
-rw-r--r--Zend/zend_alloc.c18
-rw-r--r--Zend/zend_builtin_functions.c4
-rw-r--r--Zend/zend_compile.c55
-rw-r--r--Zend/zend_compile.h1
-rw-r--r--Zend/zend_constants.c28
-rw-r--r--Zend/zend_constants.h14
-rw-r--r--Zend/zend_exceptions.c2
-rw-r--r--Zend/zend_execute.c153
-rw-r--r--Zend/zend_execute.h6
-rw-r--r--Zend/zend_execute_API.c8
-rw-r--r--Zend/zend_hash.c44
-rw-r--r--Zend/zend_highlight.c2
-rw-r--r--Zend/zend_highlight.h2
-rw-r--r--Zend/zend_object_handlers.c92
-rw-r--r--Zend/zend_objects.c3
-rw-r--r--Zend/zend_operators.c141
-rw-r--r--Zend/zend_operators.h49
-rw-r--r--Zend/zend_variables.c4
-rw-r--r--Zend/zend_variables.h2
-rw-r--r--Zend/zend_virtual_cwd.c12
-rw-r--r--Zend/zend_vm_def.h286
-rw-r--r--Zend/zend_vm_execute.h3299
-rw-r--r--ext/fileinfo/libmagic/readcdf.c6
-rw-r--r--ext/gmp/gmp.c2
-rw-r--r--ext/opcache/Optimizer/block_pass.c2
-rw-r--r--ext/opcache/Optimizer/compact_literals.c6
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c2
-rw-r--r--ext/opcache/ZendAccelerator.c4
-rw-r--r--ext/opcache/zend_accelerator_util_funcs.c58
-rw-r--r--ext/opcache/zend_accelerator_util_funcs.h1
-rw-r--r--ext/pdo_dblib/dblib_driver.c39
-rw-r--r--ext/pdo_dblib/dblib_stmt.c23
-rw-r--r--ext/pdo_dblib/pdo_dblib.c28
-rw-r--r--ext/pdo_dblib/php_pdo_dblib_int.h6
-rw-r--r--ext/phar/phar.c1
-rw-r--r--ext/simplexml/simplexml.c16
-rw-r--r--ext/soap/php_encoding.c35
-rw-r--r--ext/spl/php_spl.c4
-rw-r--r--ext/standard/array.c44
-rw-r--r--ext/standard/assert.c18
-rw-r--r--ext/standard/basic_functions.c36
-rw-r--r--ext/standard/basic_functions.h4
-rw-r--r--ext/standard/crypt.c2
-rw-r--r--ext/standard/crypt_sha256.c10
-rw-r--r--ext/standard/dir.c4
-rw-r--r--ext/standard/dl.c2
-rw-r--r--ext/standard/dns_win32.c4
-rw-r--r--ext/standard/exec.c15
-rw-r--r--ext/standard/file.c23
-rw-r--r--ext/standard/filestat.c2
-rw-r--r--ext/standard/filters.c16
-rw-r--r--ext/standard/formatted_print.c2
-rw-r--r--ext/standard/fsock.c17
-rw-r--r--ext/standard/ftp_fopen_wrapper.c16
-rw-r--r--ext/standard/head.c8
-rw-r--r--ext/standard/head.h2
-rw-r--r--ext/standard/html.c8
-rw-r--r--ext/standard/http.c12
-rw-r--r--ext/standard/http_fopen_wrapper.c29
-rw-r--r--ext/standard/info.c12
-rw-r--r--ext/standard/levenshtein.c13
-rw-r--r--ext/standard/mail.c2
-rw-r--r--ext/standard/math.c26
-rw-r--r--ext/standard/pack.c6
-rw-r--r--ext/standard/password.c9
-rw-r--r--ext/standard/php_fopen_wrapper.c4
-rw-r--r--ext/standard/php_http.h6
-rw-r--r--ext/standard/proc_open.c12
-rw-r--r--ext/standard/quot_print.c2
-rw-r--r--ext/standard/soundex.c4
-rw-r--r--ext/standard/streamsfuncs.c42
-rw-r--r--ext/standard/string.c26
-rw-r--r--ext/standard/tests/serialize/bug68044.phpt4
-rw-r--r--ext/standard/type.c2
-rw-r--r--ext/standard/url.c12
-rw-r--r--ext/standard/url.h11
-rw-r--r--ext/standard/uuencode.c5
-rw-r--r--ext/standard/var.c8
-rw-r--r--ext/tidy/tidy.c4
-rw-r--r--main/snprintf.c4
-rw-r--r--main/snprintf.h4
-rw-r--r--main/streams/php_stream_transport.h6
-rw-r--r--main/streams/plain_wrapper.c1
-rw-r--r--main/streams/transports.c4
-rw-r--r--sapi/phpdbg/config.m422
-rw-r--r--sapi/phpdbg/config.w327
-rw-r--r--sapi/phpdbg/phpdbg.12
-rw-r--r--sapi/phpdbg/phpdbg.c683
-rw-r--r--sapi/phpdbg/phpdbg.h187
-rw-r--r--sapi/phpdbg/phpdbg_bp.c815
-rw-r--r--sapi/phpdbg/phpdbg_bp.h17
-rw-r--r--sapi/phpdbg/phpdbg_break.c10
-rw-r--r--sapi/phpdbg/phpdbg_break.h2
-rw-r--r--sapi/phpdbg/phpdbg_btree.c17
-rw-r--r--sapi/phpdbg/phpdbg_btree.h7
-rw-r--r--sapi/phpdbg/phpdbg_cmd.c383
-rw-r--r--sapi/phpdbg/phpdbg_cmd.h33
-rw-r--r--sapi/phpdbg/phpdbg_eol.c172
-rw-r--r--sapi/phpdbg/phpdbg_eol.h46
-rw-r--r--sapi/phpdbg/phpdbg_frame.c201
-rw-r--r--sapi/phpdbg/phpdbg_frame.h2
-rw-r--r--sapi/phpdbg/phpdbg_help.c60
-rw-r--r--sapi/phpdbg/phpdbg_help.h6
-rw-r--r--sapi/phpdbg/phpdbg_info.c481
-rw-r--r--sapi/phpdbg/phpdbg_info.h4
-rw-r--r--sapi/phpdbg/phpdbg_io.c272
-rw-r--r--sapi/phpdbg/phpdbg_io.h34
-rw-r--r--sapi/phpdbg/phpdbg_lexer.c1574
-rw-r--r--sapi/phpdbg/phpdbg_lexer.h2
-rw-r--r--sapi/phpdbg/phpdbg_lexer.l27
-rw-r--r--sapi/phpdbg/phpdbg_list.c235
-rw-r--r--sapi/phpdbg/phpdbg_list.h19
-rw-r--r--sapi/phpdbg/phpdbg_opcode.c215
-rw-r--r--sapi/phpdbg/phpdbg_opcode.h2
-rw-r--r--sapi/phpdbg/phpdbg_out.c1306
-rw-r--r--sapi/phpdbg/phpdbg_out.h93
-rw-r--r--sapi/phpdbg/phpdbg_parser.c316
-rw-r--r--sapi/phpdbg/phpdbg_parser.h16
-rw-r--r--sapi/phpdbg/phpdbg_parser.y29
-rw-r--r--sapi/phpdbg/phpdbg_print.c157
-rw-r--r--sapi/phpdbg/phpdbg_print.h2
-rw-r--r--sapi/phpdbg/phpdbg_prompt.c1098
-rw-r--r--sapi/phpdbg/phpdbg_prompt.h13
-rw-r--r--sapi/phpdbg/phpdbg_rinit_hook.c101
-rw-r--r--sapi/phpdbg/phpdbg_rinit_hook.h41
-rw-r--r--sapi/phpdbg/phpdbg_set.c118
-rw-r--r--sapi/phpdbg/phpdbg_set.h2
-rw-r--r--sapi/phpdbg/phpdbg_sigio_win32.c120
-rw-r--r--sapi/phpdbg/phpdbg_sigio_win32.h42
-rw-r--r--sapi/phpdbg/phpdbg_sigsafe.c56
-rw-r--r--sapi/phpdbg/phpdbg_sigsafe.h28
-rw-r--r--sapi/phpdbg/phpdbg_utils.c489
-rw-r--r--sapi/phpdbg/phpdbg_utils.h84
-rw-r--r--sapi/phpdbg/phpdbg_wait.c400
-rw-r--r--sapi/phpdbg/phpdbg_wait.h29
-rw-r--r--sapi/phpdbg/phpdbg_watch.c639
-rw-r--r--sapi/phpdbg/phpdbg_watch.h46
-rw-r--r--sapi/phpdbg/phpdbg_webdata_transfer.c170
-rw-r--r--sapi/phpdbg/phpdbg_webdata_transfer.h27
-rw-r--r--sapi/phpdbg/phpdbg_win.c2
-rw-r--r--sapi/phpdbg/phpdbg_win.h2
-rw-r--r--sapi/phpdbg/tests/commands/0002_set.test2
-rw-r--r--sapi/phpdbg/tests/commands/0102_print.test5
-rw-r--r--sapi/phpdbg/tests/commands/0104_clean.test10
-rw-r--r--sapi/phpdbg/tests/commands/0105_clear.test2
-rw-r--r--sapi/phpdbg/tests/commands/0106_compile.test4
-rw-r--r--sapi/phpdbg/tests/run-tests.php2
-rw-r--r--sapi/phpdbg/xml.md651
-rw-r--r--sapi/phpdbg/zend_mm_structs.h102
-rwxr-xr-xtravis/compile.sh1
156 files changed, 10632 insertions, 6320 deletions
diff --git a/.travis.yml b/.travis.yml
index 10ea74e4df..d9e11a07d2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -47,3 +47,4 @@ before_script:
# Run PHPs run-tests.php
script:
- ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --show-diff --set-timeout 120
+ - ./sapi/cli/php sapi/phpdbg/tests/run-tests.php -diff2stdout --phpdbg sapi/phpdbg/phpdbg
diff --git a/Zend/tests/bug68262.phpt b/Zend/tests/bug68262.phpt
new file mode 100644
index 0000000000..8d009f621e
--- /dev/null
+++ b/Zend/tests/bug68262.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Bug #68262: Broken reference across cloned objects
+--FILE--
+<?php
+
+class C {
+ public $p;
+}
+
+$first = new C;
+$first->p = 'init';
+
+$clone = clone $first;
+$ref =& $first->p;
+unset($ref);
+
+$clone = clone $first;
+$clone->p = 'foo';
+
+var_dump($first->p);
+
+?>
+--EXPECT--
+string(4) "init"
diff --git a/Zend/zend.c b/Zend/zend.c
index 7a4caf800d..21d354e5b3 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -224,13 +224,13 @@ ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy TSRMLS_DC) /*
}
/* }}} */
-ZEND_API int zend_print_zval(zval *expr, int indent TSRMLS_DC) /* {{{ */
+ZEND_API size_t zend_print_zval(zval *expr, int indent TSRMLS_DC) /* {{{ */
{
return zend_print_zval_ex(zend_write, expr, indent TSRMLS_CC);
}
/* }}} */
-ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC) /* {{{ */
+ZEND_API size_t zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC) /* {{{ */
{
zend_string *str = zval_get_string(expr);
size_t len = str->len;
@@ -797,7 +797,7 @@ void zend_shutdown(TSRMLS_D) /* {{{ */
void zend_set_utility_values(zend_utility_values *utility_values) /* {{{ */
{
zend_uv = *utility_values;
- zend_uv.import_use_extension_length = strlen(zend_uv.import_use_extension);
+ zend_uv.import_use_extension_length = (uint)strlen(zend_uv.import_use_extension);
}
/* }}} */
@@ -831,11 +831,11 @@ ZEND_API void zend_append_version_info(const zend_extension *extension) /* {{{ *
char *new_info;
uint new_info_length;
- new_info_length = sizeof(" with v, , by \n")
+ new_info_length = (uint)(sizeof(" with v, , by \n")
+ strlen(extension->name)
+ strlen(extension->version)
+ strlen(extension->copyright)
- + strlen(extension->author);
+ + strlen(extension->author));
new_info = (char *) malloc(new_info_length + 1);
@@ -1101,7 +1101,7 @@ static void zend_error_va_list(int type, const char *format, va_list args)
# endif
#endif
va_copy(usr_copy, args);
- len = zend_vspprintf(&str, 0, format, usr_copy);
+ len = (int)zend_vspprintf(&str, 0, format, usr_copy);
ZVAL_NEW_STR(&params[1], zend_string_init(str, len, 0));
efree(str);
#ifdef va_copy
diff --git a/Zend/zend.h b/Zend/zend.h
index 8fbbcb190f..dfd15c6a76 100644
--- a/Zend/zend.h
+++ b/Zend/zend.h
@@ -213,7 +213,7 @@ typedef struct _zend_utility_values {
zend_bool html_errors;
} zend_utility_values;
-typedef int (*zend_write_func_t)(const char *str, uint str_length);
+typedef int (*zend_write_func_t)(const char *str, size_t str_length);
#define zend_bailout() _zend_bailout(__FILE__, __LINE__)
@@ -244,8 +244,8 @@ ZEND_API void _zend_bailout(char *filename, uint lineno);
ZEND_API char *get_zend_version(void);
ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy TSRMLS_DC);
-ZEND_API int zend_print_zval(zval *expr, int indent TSRMLS_DC);
-ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC);
+ZEND_API size_t zend_print_zval(zval *expr, int indent TSRMLS_DC);
+ZEND_API size_t zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC);
ZEND_API void zend_print_zval_r(zval *expr, int indent TSRMLS_DC);
ZEND_API void zend_print_flat_zval_r(zval *expr TSRMLS_DC);
ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC);
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index fe17968f06..c6b34e03f1 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -1336,7 +1336,7 @@ ZEND_API int add_assoc_function(zval *arg, const char *key, void (*function_ptr)
}
/* }}} */
-ZEND_API int add_assoc_long_ex(zval *arg, const char *key, uint key_len, zend_long n) /* {{{ */
+ZEND_API int add_assoc_long_ex(zval *arg, const char *key, size_t key_len, zend_long n) /* {{{ */
{
zval *ret, tmp;
@@ -1346,7 +1346,7 @@ ZEND_API int add_assoc_long_ex(zval *arg, const char *key, uint key_len, zend_lo
}
/* }}} */
-ZEND_API int add_assoc_null_ex(zval *arg, const char *key, uint key_len) /* {{{ */
+ZEND_API int add_assoc_null_ex(zval *arg, const char *key, size_t key_len) /* {{{ */
{
zval *ret, tmp;
@@ -1356,7 +1356,7 @@ ZEND_API int add_assoc_null_ex(zval *arg, const char *key, uint key_len) /* {{{
}
/* }}} */
-ZEND_API int add_assoc_bool_ex(zval *arg, const char *key, uint key_len, int b) /* {{{ */
+ZEND_API int add_assoc_bool_ex(zval *arg, const char *key, size_t key_len, int b) /* {{{ */
{
zval *ret, tmp;
@@ -1366,7 +1366,7 @@ ZEND_API int add_assoc_bool_ex(zval *arg, const char *key, uint key_len, int b)
}
/* }}} */
-ZEND_API int add_assoc_resource_ex(zval *arg, const char *key, uint key_len, zend_resource *r) /* {{{ */
+ZEND_API int add_assoc_resource_ex(zval *arg, const char *key, size_t key_len, zend_resource *r) /* {{{ */
{
zval *ret, tmp;
@@ -1376,7 +1376,7 @@ ZEND_API int add_assoc_resource_ex(zval *arg, const char *key, uint key_len, zen
}
/* }}} */
-ZEND_API int add_assoc_double_ex(zval *arg, const char *key, uint key_len, double d) /* {{{ */
+ZEND_API int add_assoc_double_ex(zval *arg, const char *key, size_t key_len, double d) /* {{{ */
{
zval *ret, tmp;
@@ -1386,7 +1386,7 @@ ZEND_API int add_assoc_double_ex(zval *arg, const char *key, uint key_len, doubl
}
/* }}} */
-ZEND_API int add_assoc_str_ex(zval *arg, const char *key, uint key_len, zend_string *str) /* {{{ */
+ZEND_API int add_assoc_str_ex(zval *arg, const char *key, size_t key_len, zend_string *str) /* {{{ */
{
zval *ret, tmp;
@@ -1396,7 +1396,7 @@ ZEND_API int add_assoc_str_ex(zval *arg, const char *key, uint key_len, zend_str
}
/* }}} */
-ZEND_API int add_assoc_string_ex(zval *arg, const char *key, uint key_len, char *str) /* {{{ */
+ZEND_API int add_assoc_string_ex(zval *arg, const char *key, size_t key_len, char *str) /* {{{ */
{
zval *ret, tmp;
@@ -1406,7 +1406,7 @@ ZEND_API int add_assoc_string_ex(zval *arg, const char *key, uint key_len, char
}
/* }}} */
-ZEND_API int add_assoc_stringl_ex(zval *arg, const char *key, uint key_len, char *str, size_t length) /* {{{ */
+ZEND_API int add_assoc_stringl_ex(zval *arg, const char *key, size_t key_len, char *str, size_t length) /* {{{ */
{
zval *ret, tmp;
@@ -1416,7 +1416,7 @@ ZEND_API int add_assoc_stringl_ex(zval *arg, const char *key, uint key_len, char
}
/* }}} */
-ZEND_API int add_assoc_zval_ex(zval *arg, const char *key, uint key_len, zval *value) /* {{{ */
+ZEND_API int add_assoc_zval_ex(zval *arg, const char *key, size_t key_len, zval *value) /* {{{ */
{
zval *ret;
@@ -1689,7 +1689,7 @@ ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value TSRMLS_DC)
}
/* }}} */
-ZEND_API int add_property_long_ex(zval *arg, const char *key, uint key_len, zend_long n TSRMLS_DC) /* {{{ */
+ZEND_API int add_property_long_ex(zval *arg, const char *key, size_t key_len, zend_long n TSRMLS_DC) /* {{{ */
{
zval tmp;
zval z_key;
@@ -1703,7 +1703,7 @@ ZEND_API int add_property_long_ex(zval *arg, const char *key, uint key_len, zend
}
/* }}} */
-ZEND_API int add_property_bool_ex(zval *arg, const char *key, uint key_len, zend_long b TSRMLS_DC) /* {{{ */
+ZEND_API int add_property_bool_ex(zval *arg, const char *key, size_t key_len, zend_long b TSRMLS_DC) /* {{{ */
{
zval tmp;
zval z_key;
@@ -1717,7 +1717,7 @@ ZEND_API int add_property_bool_ex(zval *arg, const char *key, uint key_len, zend
}
/* }}} */
-ZEND_API int add_property_null_ex(zval *arg, const char *key, uint key_len TSRMLS_DC) /* {{{ */
+ZEND_API int add_property_null_ex(zval *arg, const char *key, size_t key_len TSRMLS_DC) /* {{{ */
{
zval tmp;
zval z_key;
@@ -1731,7 +1731,7 @@ ZEND_API int add_property_null_ex(zval *arg, const char *key, uint key_len TSRML
}
/* }}} */
-ZEND_API int add_property_resource_ex(zval *arg, const char *key, uint key_len, zend_resource *r TSRMLS_DC) /* {{{ */
+ZEND_API int add_property_resource_ex(zval *arg, const char *key, size_t key_len, zend_resource *r TSRMLS_DC) /* {{{ */
{
zval tmp;
zval z_key;
@@ -1745,7 +1745,7 @@ ZEND_API int add_property_resource_ex(zval *arg, const char *key, uint key_len,
}
/* }}} */
-ZEND_API int add_property_double_ex(zval *arg, const char *key, uint key_len, double d TSRMLS_DC) /* {{{ */
+ZEND_API int add_property_double_ex(zval *arg, const char *key, size_t key_len, double d TSRMLS_DC) /* {{{ */
{
zval tmp;
zval z_key;
@@ -1759,7 +1759,7 @@ ZEND_API int add_property_double_ex(zval *arg, const char *key, uint key_len, do
}
/* }}} */
-ZEND_API int add_property_str_ex(zval *arg, const char *key, uint key_len, zend_string *str TSRMLS_DC) /* {{{ */
+ZEND_API int add_property_str_ex(zval *arg, const char *key, size_t key_len, zend_string *str TSRMLS_DC) /* {{{ */
{
zval tmp;
zval z_key;
@@ -1773,7 +1773,7 @@ ZEND_API int add_property_str_ex(zval *arg, const char *key, uint key_len, zend_
}
/* }}} */
-ZEND_API int add_property_string_ex(zval *arg, const char *key, uint key_len, const char *str TSRMLS_DC) /* {{{ */
+ZEND_API int add_property_string_ex(zval *arg, const char *key, size_t key_len, const char *str TSRMLS_DC) /* {{{ */
{
zval tmp;
zval z_key;
@@ -1787,7 +1787,7 @@ ZEND_API int add_property_string_ex(zval *arg, const char *key, uint key_len, co
}
/* }}} */
-ZEND_API int add_property_stringl_ex(zval *arg, const char *key, uint key_len, const char *str, size_t length TSRMLS_DC) /* {{{ */
+ZEND_API int add_property_stringl_ex(zval *arg, const char *key, size_t key_len, const char *str, size_t length TSRMLS_DC) /* {{{ */
{
zval tmp;
zval z_key;
@@ -1801,7 +1801,7 @@ ZEND_API int add_property_stringl_ex(zval *arg, const char *key, uint key_len, c
}
/* }}} */
-ZEND_API int add_property_zval_ex(zval *arg, const char *key, uint key_len, zval *value TSRMLS_DC) /* {{{ */
+ZEND_API int add_property_zval_ex(zval *arg, const char *key, size_t key_len, zval *value TSRMLS_DC) /* {{{ */
{
zval z_key;
@@ -1814,7 +1814,7 @@ ZEND_API int add_property_zval_ex(zval *arg, const char *key, uint key_len, zval
ZEND_API int zend_startup_module_ex(zend_module_entry *module TSRMLS_DC) /* {{{ */
{
- int name_len;
+ size_t name_len;
zend_string *lcname;
if (module->module_started) {
@@ -2001,7 +2001,7 @@ ZEND_API void zend_destroy_modules(void) /* {{{ */
ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module TSRMLS_DC) /* {{{ */
{
- int name_len;
+ size_t name_len;
zend_string *lcname;
zend_module_entry *module_ptr;
@@ -2070,7 +2070,7 @@ ZEND_API zend_module_entry* zend_register_internal_module(zend_module_entry *mod
ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, int error_type TSRMLS_DC) /* {{{ */
{
char lcname[16];
- int name_len;
+ size_t name_len;
/* we don't care if the function name is longer, in fact lowercasing only
* the beginning of the name speeds up the check process */
@@ -2142,9 +2142,9 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
int error_type;
zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL, *__debugInfo = NULL;
zend_string *lowercase_name;
- int fname_len;
+ size_t fname_len;
const char *lc_class_name = NULL;
- int class_name_len = 0;
+ size_t class_name_len = 0;
if (type==MODULE_PERSISTENT) {
error_type = E_CORE_WARNING;
@@ -2417,7 +2417,7 @@ ZEND_API void zend_unregister_functions(const zend_function_entry *functions, in
int i=0;
HashTable *target_function_table = function_table;
zend_string *lowercase_name;
- int fname_len;
+ size_t fname_len;
if (!target_function_table) {
target_function_table = CG(function_table);
@@ -2699,7 +2699,7 @@ ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *or
}
/* }}} */
-ZEND_API int zend_register_class_alias_ex(const char *name, int name_len, zend_class_entry *ce TSRMLS_DC) /* {{{ */
+ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce TSRMLS_DC) /* {{{ */
{
zend_string *lcname;
@@ -2759,7 +2759,7 @@ static zend_function_entry disabled_function[] = {
ZEND_FE_END
};
-ZEND_API int zend_disable_function(char *function_name, uint function_name_length TSRMLS_DC) /* {{{ */
+ZEND_API int zend_disable_function(char *function_name, size_t function_name_length TSRMLS_DC) /* {{{ */
{
int ret;
@@ -2792,7 +2792,7 @@ static const zend_function_entry disabled_class_new[] = {
ZEND_FE_END
};
-ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_DC) /* {{{ */
+ZEND_API int zend_disable_class(char *class_name, size_t class_name_length TSRMLS_DC) /* {{{ */
{
zend_class_entry *disabled_class;
zend_string *key;
@@ -2814,7 +2814,7 @@ static int zend_is_callable_check_class(zend_string *name, zend_fcall_info_cache
{
int ret = 0;
zend_class_entry *ce;
- int name_len = name->len;
+ size_t name_len = name->len;
zend_string *lcname;
ALLOCA_FLAG(use_heap);
@@ -2893,7 +2893,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
zend_string *mname, *cname;
zend_string *lmname;
const char *colon;
- int clen, mlen;
+ size_t clen, mlen;
zend_class_entry *last_scope;
HashTable *ftable;
int call_via_handler = 0;
@@ -3579,7 +3579,7 @@ ZEND_API int zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *f
ZEND_API const char *zend_get_module_version(const char *module_name) /* {{{ */
{
zend_string *lname;
- int name_len = strlen(module_name);
+ size_t name_len = strlen(module_name);
zend_module_entry *module;
lname = zend_string_alloc(name_len, 0);
@@ -3667,7 +3667,7 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
}
/* }}} */
-ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, int name_length, zval *property, int access_type TSRMLS_DC) /* {{{ */
+ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, size_t name_length, zval *property, int access_type TSRMLS_DC) /* {{{ */
{
zend_string *key = zend_string_init(name, name_length, ce->type & ZEND_INTERNAL_CLASS);
int ret = zend_declare_property_ex(ce, key, property, access_type, NULL TSRMLS_CC);
@@ -3676,7 +3676,7 @@ ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, int n
}
/* }}} */
-ZEND_API int zend_declare_property_null(zend_class_entry *ce, const char *name, int name_length, int access_type TSRMLS_DC) /* {{{ */
+ZEND_API int zend_declare_property_null(zend_class_entry *ce, const char *name, size_t name_length, int access_type TSRMLS_DC) /* {{{ */
{
zval property;
@@ -3685,7 +3685,7 @@ ZEND_API int zend_declare_property_null(zend_class_entry *ce, const char *name,
}
/* }}} */
-ZEND_API int zend_declare_property_bool(zend_class_entry *ce, const char *name, int name_length, zend_long value, int access_type TSRMLS_DC) /* {{{ */
+ZEND_API int zend_declare_property_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type TSRMLS_DC) /* {{{ */
{
zval property;
@@ -3694,7 +3694,7 @@ ZEND_API int zend_declare_property_bool(zend_class_entry *ce, const char *name,
}
/* }}} */
-ZEND_API int zend_declare_property_long(zend_class_entry *ce, const char *name, int name_length, zend_long value, int access_type TSRMLS_DC) /* {{{ */
+ZEND_API int zend_declare_property_long(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type TSRMLS_DC) /* {{{ */
{
zval property;
@@ -3703,7 +3703,7 @@ ZEND_API int zend_declare_property_long(zend_class_entry *ce, const char *name,
}
/* }}} */
-ZEND_API int zend_declare_property_double(zend_class_entry *ce, const char *name, int name_length, double value, int access_type TSRMLS_DC) /* {{{ */
+ZEND_API int zend_declare_property_double(zend_class_entry *ce, const char *name, size_t name_length, double value, int access_type TSRMLS_DC) /* {{{ */
{
zval property;
@@ -3712,7 +3712,7 @@ ZEND_API int zend_declare_property_double(zend_class_entry *ce, const char *name
}
/* }}} */
-ZEND_API int zend_declare_property_string(zend_class_entry *ce, const char *name, int name_length, const char *value, int access_type TSRMLS_DC) /* {{{ */
+ZEND_API int zend_declare_property_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value, int access_type TSRMLS_DC) /* {{{ */
{
zval property;
@@ -3721,7 +3721,7 @@ ZEND_API int zend_declare_property_string(zend_class_entry *ce, const char *name
}
/* }}} */
-ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *name, int name_length, const char *value, size_t value_len, int access_type TSRMLS_DC) /* {{{ */
+ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_len, int access_type TSRMLS_DC) /* {{{ */
{
zval property;
@@ -3791,7 +3791,7 @@ ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, const char
}
/* }}} */
-ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const char *name, int name_length, zval *value TSRMLS_DC) /* {{{ */
+ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zval *value TSRMLS_DC) /* {{{ */
{
zval property;
zend_class_entry *old_scope = EG(scope);
@@ -3809,7 +3809,7 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const
}
/* }}} */
-ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, const char *name, int name_length TSRMLS_DC) /* {{{ */
+ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, const char *name, size_t name_length TSRMLS_DC) /* {{{ */
{
zval tmp;
@@ -3818,7 +3818,7 @@ ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, c
}
/* }}} */
-ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, const char *name, int name_length, zend_long value TSRMLS_DC) /* {{{ */
+ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value TSRMLS_DC) /* {{{ */
{
zval tmp;
@@ -3827,7 +3827,7 @@ ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, c
}
/* }}} */
-ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, const char *name, int name_length, zend_long value TSRMLS_DC) /* {{{ */
+ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value TSRMLS_DC) /* {{{ */
{
zval tmp;
@@ -3836,7 +3836,7 @@ ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, c
}
/* }}} */
-ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, const char *name, int name_length, double value TSRMLS_DC) /* {{{ */
+ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, const char *name, size_t name_length, double value TSRMLS_DC) /* {{{ */
{
zval tmp;
@@ -3845,7 +3845,7 @@ ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object,
}
/* }}} */
-ZEND_API void zend_update_property_str(zend_class_entry *scope, zval *object, const char *name, int name_length, zend_string *value TSRMLS_DC) /* {{{ */
+ZEND_API void zend_update_property_str(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_string *value TSRMLS_DC) /* {{{ */
{
zval tmp;
@@ -3854,7 +3854,7 @@ ZEND_API void zend_update_property_str(zend_class_entry *scope, zval *object, co
}
/* }}} */
-ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, const char *name, int name_length, const char *value TSRMLS_DC) /* {{{ */
+ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, const char *name, size_t name_length, const char *value TSRMLS_DC) /* {{{ */
{
zval tmp;
@@ -3864,7 +3864,7 @@ ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object,
}
/* }}} */
-ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, const char *name, int name_length, const char *value, size_t value_len TSRMLS_DC) /* {{{ */
+ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, const char *name, size_t name_length, const char *value, size_t value_len TSRMLS_DC) /* {{{ */
{
zval tmp;
@@ -3874,7 +3874,7 @@ ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object
}
/* }}} */
-ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *name, int name_length, zval *value TSRMLS_DC) /* {{{ */
+ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *name, size_t name_length, zval *value TSRMLS_DC) /* {{{ */
{
zval *property;
zend_class_entry *old_scope = EG(scope);
@@ -3913,7 +3913,7 @@ ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *na
}
/* }}} */
-ZEND_API int zend_update_static_property_null(zend_class_entry *scope, const char *name, int name_length TSRMLS_DC) /* {{{ */
+ZEND_API int zend_update_static_property_null(zend_class_entry *scope, const char *name, size_t name_length TSRMLS_DC) /* {{{ */
{
zval tmp;
@@ -3922,7 +3922,7 @@ ZEND_API int zend_update_static_property_null(zend_class_entry *scope, const cha
}
/* }}} */
-ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, const char *name, int name_length, zend_long value TSRMLS_DC) /* {{{ */
+ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, const char *name, size_t name_length, zend_long value TSRMLS_DC) /* {{{ */
{
zval tmp;
@@ -3931,7 +3931,7 @@ ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, const cha
}
/* }}} */
-ZEND_API int zend_update_static_property_long(zend_class_entry *scope, const char *name, int name_length, zend_long value TSRMLS_DC) /* {{{ */
+ZEND_API int zend_update_static_property_long(zend_class_entry *scope, const char *name, size_t name_length, zend_long value TSRMLS_DC) /* {{{ */
{
zval tmp;
@@ -3940,7 +3940,7 @@ ZEND_API int zend_update_static_property_long(zend_class_entry *scope, const cha
}
/* }}} */
-ZEND_API int zend_update_static_property_double(zend_class_entry *scope, const char *name, int name_length, double value TSRMLS_DC) /* {{{ */
+ZEND_API int zend_update_static_property_double(zend_class_entry *scope, const char *name, size_t name_length, double value TSRMLS_DC) /* {{{ */
{
zval tmp;
@@ -3949,7 +3949,7 @@ ZEND_API int zend_update_static_property_double(zend_class_entry *scope, const c
}
/* }}} */
-ZEND_API int zend_update_static_property_string(zend_class_entry *scope, const char *name, int name_length, const char *value TSRMLS_DC) /* {{{ */
+ZEND_API int zend_update_static_property_string(zend_class_entry *scope, const char *name, size_t name_length, const char *value TSRMLS_DC) /* {{{ */
{
zval tmp;
@@ -3959,7 +3959,7 @@ ZEND_API int zend_update_static_property_string(zend_class_entry *scope, const c
}
/* }}} */
-ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, const char *name, int name_length, const char *value, size_t value_len TSRMLS_DC) /* {{{ */
+ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, const char *name, size_t name_length, const char *value, size_t value_len TSRMLS_DC) /* {{{ */
{
zval tmp;
@@ -3969,7 +3969,7 @@ ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, const
}
/* }}} */
-ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, int name_length, zend_bool silent TSRMLS_DC) /* {{{ */
+ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent TSRMLS_DC) /* {{{ */
{
zval property, *value;
zend_class_entry *old_scope = EG(scope);
@@ -3990,7 +3990,7 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const c
}
/* }}} */
-ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, int name_length, zend_bool silent TSRMLS_DC) /* {{{ */
+ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, size_t name_length, zend_bool silent TSRMLS_DC) /* {{{ */
{
zval *property;
zend_class_entry *old_scope = EG(scope);
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index b2faf7e253..46e284be7f 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -276,15 +276,15 @@ ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *cla
ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry TSRMLS_DC);
ZEND_API void zend_class_implements(zend_class_entry *class_entry TSRMLS_DC, int num_interfaces, ...);
-ZEND_API int zend_register_class_alias_ex(const char *name, int name_len, zend_class_entry *ce TSRMLS_DC);
+ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce TSRMLS_DC);
#define zend_register_class_alias(name, ce) \
zend_register_class_alias_ex(name, sizeof(name)-1, ce TSRMLS_CC)
#define zend_register_ns_class_alias(ns, name, ce) \
zend_register_class_alias_ex(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name))-1, ce TSRMLS_CC)
-ZEND_API int zend_disable_function(char *function_name, uint function_name_length TSRMLS_DC);
-ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_DC);
+ZEND_API int zend_disable_function(char *function_name, size_t function_name_length TSRMLS_DC);
+ZEND_API int zend_disable_class(char *class_name, size_t class_name_length TSRMLS_DC);
ZEND_API void zend_wrong_param_count(TSRMLS_D);
@@ -301,13 +301,13 @@ ZEND_API zend_bool zend_make_callable(zval *callable, zend_string **callable_nam
ZEND_API const char *zend_get_module_version(const char *module_name);
ZEND_API int zend_get_module_started(const char *module_name);
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment TSRMLS_DC);
-ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, int name_length, zval *property, int access_type TSRMLS_DC);
-ZEND_API int zend_declare_property_null(zend_class_entry *ce, const char *name, int name_length, int access_type TSRMLS_DC);
-ZEND_API int zend_declare_property_bool(zend_class_entry *ce, const char *name, int name_length, zend_long value, int access_type TSRMLS_DC);
-ZEND_API int zend_declare_property_long(zend_class_entry *ce, const char *name, int name_length, zend_long value, int access_type TSRMLS_DC);
-ZEND_API int zend_declare_property_double(zend_class_entry *ce, const char *name, int name_length, double value, int access_type TSRMLS_DC);
-ZEND_API int zend_declare_property_string(zend_class_entry *ce, const char *name, int name_length, const char *value, int access_type TSRMLS_DC);
-ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *name, int name_length, const char *value, size_t value_len, int access_type TSRMLS_DC);
+ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, size_t name_length, zval *property, int access_type TSRMLS_DC);
+ZEND_API int zend_declare_property_null(zend_class_entry *ce, const char *name, size_t name_length, int access_type TSRMLS_DC);
+ZEND_API int zend_declare_property_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type TSRMLS_DC);
+ZEND_API int zend_declare_property_long(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type TSRMLS_DC);
+ZEND_API int zend_declare_property_double(zend_class_entry *ce, const char *name, size_t name_length, double value, int access_type TSRMLS_DC);
+ZEND_API int zend_declare_property_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value, int access_type TSRMLS_DC);
+ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_len, int access_type TSRMLS_DC);
ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value TSRMLS_DC);
ZEND_API int zend_declare_class_constant_null(zend_class_entry *ce, const char *name, size_t name_length TSRMLS_DC);
@@ -318,26 +318,26 @@ ZEND_API int zend_declare_class_constant_stringl(zend_class_entry *ce, const cha
ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value TSRMLS_DC);
ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC);
-ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const char *name, int name_length, zval *value TSRMLS_DC);
-ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, const char *name, int name_length TSRMLS_DC);
-ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, const char *name, int name_length, zend_long value TSRMLS_DC);
-ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, const char *name, int name_length, zend_long value TSRMLS_DC);
-ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, const char *name, int name_length, double value TSRMLS_DC);
-ZEND_API void zend_update_property_str(zend_class_entry *scope, zval *object, const char *name, int name_length, zend_string *value TSRMLS_DC);
-ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, const char *name, int name_length, const char *value TSRMLS_DC);
-ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, const char *name, int name_length, const char *value, size_t value_length TSRMLS_DC);
-
-ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *name, int name_length, zval *value TSRMLS_DC);
-ZEND_API int zend_update_static_property_null(zend_class_entry *scope, const char *name, int name_length TSRMLS_DC);
-ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, const char *name, int name_length, zend_long value TSRMLS_DC);
-ZEND_API int zend_update_static_property_long(zend_class_entry *scope, const char *name, int name_length, zend_long value TSRMLS_DC);
-ZEND_API int zend_update_static_property_double(zend_class_entry *scope, const char *name, int name_length, double value TSRMLS_DC);
-ZEND_API int zend_update_static_property_string(zend_class_entry *scope, const char *name, int name_length, const char *value TSRMLS_DC);
-ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, const char *name, int name_length, const char *value, size_t value_length TSRMLS_DC);
-
-ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, int name_length, zend_bool silent TSRMLS_DC);
-
-ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, int name_length, zend_bool silent TSRMLS_DC);
+ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zval *value TSRMLS_DC);
+ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, const char *name, size_t name_length TSRMLS_DC);
+ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value TSRMLS_DC);
+ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value TSRMLS_DC);
+ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, const char *name, size_t name_length, double value TSRMLS_DC);
+ZEND_API void zend_update_property_str(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_string *value TSRMLS_DC);
+ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, const char *name, size_t name_length, const char *value TSRMLS_DC);
+ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, const char *name, size_t name_length, const char *value, size_t value_length TSRMLS_DC);
+
+ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *name, size_t name_length, zval *value TSRMLS_DC);
+ZEND_API int zend_update_static_property_null(zend_class_entry *scope, const char *name, size_t name_length TSRMLS_DC);
+ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, const char *name, size_t name_length, zend_long value TSRMLS_DC);
+ZEND_API int zend_update_static_property_long(zend_class_entry *scope, const char *name, size_t name_length, zend_long value TSRMLS_DC);
+ZEND_API int zend_update_static_property_double(zend_class_entry *scope, const char *name, size_t name_length, double value TSRMLS_DC);
+ZEND_API int zend_update_static_property_string(zend_class_entry *scope, const char *name, size_t name_length, const char *value TSRMLS_DC);
+ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, const char *name, size_t name_length, const char *value, size_t value_length TSRMLS_DC);
+
+ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent TSRMLS_DC);
+
+ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, size_t name_length, zend_bool silent TSRMLS_DC);
ZEND_API char *zend_get_type_by_const(int type);
@@ -373,15 +373,15 @@ ZEND_API void zend_merge_properties(zval *obj, HashTable *properties TSRMLS_DC);
/* no longer supported */
ZEND_API int add_assoc_function(zval *arg, const char *key, void (*function_ptr)(INTERNAL_FUNCTION_PARAMETERS));
-ZEND_API int add_assoc_long_ex(zval *arg, const char *key, uint key_len, zend_long n);
-ZEND_API int add_assoc_null_ex(zval *arg, const char *key, uint key_len);
-ZEND_API int add_assoc_bool_ex(zval *arg, const char *key, uint key_len, int b);
-ZEND_API int add_assoc_resource_ex(zval *arg, const char *key, uint key_len, zend_resource *r);
-ZEND_API int add_assoc_double_ex(zval *arg, const char *key, uint key_len, double d);
-ZEND_API int add_assoc_str_ex(zval *arg, const char *key, uint key_len, zend_string *str);
-ZEND_API int add_assoc_string_ex(zval *arg, const char *key, uint key_len, char *str);
-ZEND_API int add_assoc_stringl_ex(zval *arg, const char *key, uint key_len, char *str, size_t length);
-ZEND_API int add_assoc_zval_ex(zval *arg, const char *key, uint key_len, zval *value);
+ZEND_API int add_assoc_long_ex(zval *arg, const char *key, size_t key_len, zend_long n);
+ZEND_API int add_assoc_null_ex(zval *arg, const char *key, size_t key_len);
+ZEND_API int add_assoc_bool_ex(zval *arg, const char *key, size_t key_len, int b);
+ZEND_API int add_assoc_resource_ex(zval *arg, const char *key, size_t key_len, zend_resource *r);
+ZEND_API int add_assoc_double_ex(zval *arg, const char *key, size_t key_len, double d);
+ZEND_API int add_assoc_str_ex(zval *arg, const char *key, size_t key_len, zend_string *str);
+ZEND_API int add_assoc_string_ex(zval *arg, const char *key, size_t key_len, char *str);
+ZEND_API int add_assoc_stringl_ex(zval *arg, const char *key, size_t key_len, char *str, size_t length);
+ZEND_API int add_assoc_zval_ex(zval *arg, const char *key, size_t key_len, zval *value);
#define add_assoc_long(__arg, __key, __n) add_assoc_long_ex(__arg, __key, strlen(__key), __n)
#define add_assoc_null(__arg, __key) add_assoc_null_ex(__arg, __key, strlen(__key))
@@ -433,15 +433,15 @@ ZEND_API zval *add_get_index_stringl(zval *arg, zend_ulong idx, const char *str,
ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value TSRMLS_DC);
-ZEND_API int add_property_long_ex(zval *arg, const char *key, uint key_len, zend_long l TSRMLS_DC);
-ZEND_API int add_property_null_ex(zval *arg, const char *key, uint key_len TSRMLS_DC);
-ZEND_API int add_property_bool_ex(zval *arg, const char *key, uint key_len, zend_long b TSRMLS_DC);
-ZEND_API int add_property_resource_ex(zval *arg, const char *key, uint key_len, zend_resource *r TSRMLS_DC);
-ZEND_API int add_property_double_ex(zval *arg, const char *key, uint key_len, double d TSRMLS_DC);
-ZEND_API int add_property_str_ex(zval *arg, const char *key, uint key_len, zend_string *str TSRMLS_DC);
-ZEND_API int add_property_string_ex(zval *arg, const char *key, uint key_len, const char *str TSRMLS_DC);
-ZEND_API int add_property_stringl_ex(zval *arg, const char *key, uint key_len, const char *str, size_t length TSRMLS_DC);
-ZEND_API int add_property_zval_ex(zval *arg, const char *key, uint key_len, zval *value TSRMLS_DC);
+ZEND_API int add_property_long_ex(zval *arg, const char *key, size_t key_len, zend_long l TSRMLS_DC);
+ZEND_API int add_property_null_ex(zval *arg, const char *key, size_t key_len TSRMLS_DC);
+ZEND_API int add_property_bool_ex(zval *arg, const char *key, size_t key_len, zend_long b TSRMLS_DC);
+ZEND_API int add_property_resource_ex(zval *arg, const char *key, size_t key_len, zend_resource *r TSRMLS_DC);
+ZEND_API int add_property_double_ex(zval *arg, const char *key, size_t key_len, double d TSRMLS_DC);
+ZEND_API int add_property_str_ex(zval *arg, const char *key, size_t key_len, zend_string *str TSRMLS_DC);
+ZEND_API int add_property_string_ex(zval *arg, const char *key, size_t key_len, const char *str TSRMLS_DC);
+ZEND_API int add_property_stringl_ex(zval *arg, const char *key, size_t key_len, const char *str, size_t length TSRMLS_DC);
+ZEND_API int add_property_zval_ex(zval *arg, const char *key, size_t key_len, zval *value TSRMLS_DC);
#define add_property_long(__arg, __key, __n) add_property_long_ex(__arg, __key, strlen(__key), __n TSRMLS_CC)
#define add_property_null(__arg, __key) add_property_null_ex(__arg, __key, strlen(__key) TSRMLS_CC)
@@ -451,7 +451,7 @@ ZEND_API int add_property_zval_ex(zval *arg, const char *key, uint key_len, zval
#define add_property_str(__arg, __key, __str) add_property_str_ex(__arg, __key, strlen(__key), __str TSRMLS_CC)
#define add_property_string(__arg, __key, __str) add_property_string_ex(__arg, __key, strlen(__key), __str TSRMLS_CC)
#define add_property_stringl(__arg, __key, __str, __length) add_property_stringl_ex(__arg, __key, strlen(__key), __str, __length TSRMLS_CC)
-#define add_property_zval(__arg, __key, __value) add_property_zval_ex(__arg, __key, strlen(__key), __value TSRMLS_CC)
+#define add_property_zval(__arg, __key, __value) add_property_zval_ex(__arg, __key, strlen(__key), __value TSRMLS_CC)
ZEND_API int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[] TSRMLS_DC);
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
index 8bc7bcb44d..578c3a80ea 100644
--- a/Zend/zend_alloc.c
+++ b/Zend/zend_alloc.c
@@ -1028,7 +1028,7 @@ found:
static zend_always_inline void *zend_mm_alloc_large(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
- int pages_count = ZEND_MM_SIZE_TO_NUM(size, ZEND_MM_PAGE_SIZE);
+ int pages_count = (int)ZEND_MM_SIZE_TO_NUM(size, ZEND_MM_PAGE_SIZE);
#if ZEND_DEBUG
void *ptr = zend_mm_alloc_pages(heap, pages_count, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#else
@@ -1261,7 +1261,7 @@ static zend_always_inline zend_mm_debug_info *zend_mm_get_debug_info(zend_mm_hea
ZEND_MM_CHECK(page_offset != 0, "zend_mm_heap corrupted");
chunk = (zend_mm_chunk*)ZEND_MM_ALIGNED_BASE(ptr, ZEND_MM_CHUNK_SIZE);
- page_num = page_offset / ZEND_MM_PAGE_SIZE;
+ page_num = (int)(page_offset / ZEND_MM_PAGE_SIZE);
info = chunk->map[page_num];
ZEND_MM_CHECK(chunk->heap == heap, "zend_mm_heap corrupted");
if (EXPECTED(info & ZEND_MM_IS_SRUN)) {
@@ -1326,7 +1326,7 @@ static zend_always_inline void zend_mm_free_heap(zend_mm_heap *heap, void *ptr Z
}
} else {
zend_mm_chunk *chunk = (zend_mm_chunk*)ZEND_MM_ALIGNED_BASE(ptr, ZEND_MM_CHUNK_SIZE);
- int page_num = page_offset / ZEND_MM_PAGE_SIZE;
+ int page_num = (int)(page_offset / ZEND_MM_PAGE_SIZE);
zend_mm_page_info info = chunk->map[page_num];
ZEND_MM_CHECK(chunk->heap == heap, "zend_mm_heap corrupted");
@@ -1357,7 +1357,7 @@ static size_t zend_mm_size(zend_mm_heap *heap, void *ptr ZEND_FILE_LINE_DC ZEND_
zend_mm_page_info info;
chunk = (zend_mm_chunk*)ZEND_MM_ALIGNED_BASE(ptr, ZEND_MM_CHUNK_SIZE);
- page_num = page_offset / ZEND_MM_PAGE_SIZE;
+ page_num = (int)(page_offset / ZEND_MM_PAGE_SIZE);
info = chunk->map[page_num];
ZEND_MM_CHECK(chunk->heap == heap, "zend_mm_heap corrupted");
if (EXPECTED(info & ZEND_MM_IS_SRUN)) {
@@ -1451,7 +1451,7 @@ static void *zend_mm_realloc_heap(zend_mm_heap *heap, void *ptr, size_t size ZEN
}
} else {
zend_mm_chunk *chunk = (zend_mm_chunk*)ZEND_MM_ALIGNED_BASE(ptr, ZEND_MM_CHUNK_SIZE);
- int page_num = page_offset / ZEND_MM_PAGE_SIZE;
+ int page_num = (int)(page_offset / ZEND_MM_PAGE_SIZE);
zend_mm_page_info info = chunk->map[page_num];
#if ZEND_DEBUG
size_t real_size = size;
@@ -1494,8 +1494,8 @@ static void *zend_mm_realloc_heap(zend_mm_heap *heap, void *ptr, size_t size ZEN
return ptr;
} else if (new_size < old_size) {
/* free tail pages */
- int new_pages_count = new_size / ZEND_MM_PAGE_SIZE;
- int rest_pages_count = (old_size - new_size) / ZEND_MM_PAGE_SIZE;
+ int new_pages_count = (int)(new_size / ZEND_MM_PAGE_SIZE);
+ int rest_pages_count = (int)((old_size - new_size) / ZEND_MM_PAGE_SIZE);
#if ZEND_MM_STAT
heap->size -= rest_pages_count * ZEND_MM_PAGE_SIZE;
@@ -1513,8 +1513,8 @@ static void *zend_mm_realloc_heap(zend_mm_heap *heap, void *ptr, size_t size ZEN
#endif
return ptr;
} else /* if (new_size > old_size) */ {
- int new_pages_count = new_size / ZEND_MM_PAGE_SIZE;
- int old_pages_count = old_size / ZEND_MM_PAGE_SIZE;
+ int new_pages_count = (int)(new_size / ZEND_MM_PAGE_SIZE);
+ int old_pages_count = (int)(old_size / ZEND_MM_PAGE_SIZE);
/* try to allocate tail pages after this block */
if (page_num + new_pages_count <= ZEND_MM_PAGES &&
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 9487bb6c1e..8203d39e51 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -1059,7 +1059,7 @@ ZEND_FUNCTION(get_object_vars)
}
/* }}} */
-static int same_name(const char *key, const char *name, uint32_t name_len) /* {{{ */
+static int same_name(const char *key, const char *name, size_t name_len) /* {{{ */
{
char *lcname = zend_str_tolower_dup(name, name_len);
int ret = memcmp(lcname, key, name_len) == 0;
@@ -1102,7 +1102,7 @@ ZEND_FUNCTION(get_class_methods)
zend_check_protected(mptr->common.scope, EG(scope)))
|| ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) &&
EG(scope) == mptr->common.scope)))) {
- uint len = mptr->common.function_name->len;
+ size_t len = mptr->common.function_name->len;
/* Do not display old-style inherited constructors */
if (!key) {
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index e1246b28dc..c72a972007 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -514,7 +514,7 @@ void zend_do_free(znode *op1 TSRMLS_DC) /* {{{ */
opline->result_type |= EXT_TYPE_UNUSED;
}
} else {
- while (opline>CG(active_op_array)->opcodes) {
+ while (opline >= CG(active_op_array)->opcodes) {
if (opline->opcode == ZEND_FETCH_LIST &&
opline->op1_type == IS_VAR &&
opline->op1.var == op1->u.op.var) {
@@ -1107,7 +1107,7 @@ ZEND_API zend_string *zend_mangle_property_name(const char *src1, size_t src1_le
}
/* }}} */
-static int zend_strnlen(const char* s, size_t maxlen) /* {{{ */
+static size_t zend_strnlen(const char* s, size_t maxlen) /* {{{ */
{
size_t len = 0;
while (*s++ && maxlen--) len++;
@@ -1641,11 +1641,8 @@ static void zend_adjust_for_fetch_type(zend_op *opline, uint32_t type) /* {{{ */
case BP_VAR_R:
return;
case BP_VAR_W:
- opline->opcode += 3;
- return;
case BP_VAR_REF:
opline->opcode += 3;
- opline->extended_value |= ZEND_FETCH_MAKE_REF;
return;
case BP_VAR_RW:
opline->opcode += 6;
@@ -2281,8 +2278,6 @@ void zend_compile_assign(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
opline->opcode = ZEND_ASSIGN_DIM;
opline = zend_emit_op_data(&expr_node TSRMLS_CC);
- opline->op2.var = get_temporary_variable(CG(active_op_array));
- opline->op2_type = IS_VAR;
return;
case ZEND_AST_PROP:
offset = zend_delayed_compile_begin(TSRMLS_C);
@@ -2374,8 +2369,6 @@ void zend_compile_compound_assign(znode *result, zend_ast *ast TSRMLS_DC) /* {{{
opline->extended_value = ZEND_ASSIGN_DIM;
opline = zend_emit_op_data(&expr_node TSRMLS_CC);
- opline->op2.var = get_temporary_variable(CG(active_op_array));
- opline->op2_type = IS_VAR;
return;
case ZEND_AST_PROP:
offset = zend_delayed_compile_begin(TSRMLS_C);
@@ -2944,10 +2937,23 @@ void zend_compile_new(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
zend_op *opline;
uint32_t opnum;
- zend_compile_class_ref(&class_node, class_ast TSRMLS_CC);
+ if (zend_is_const_default_class_ref(class_ast)) {
+ class_node.op_type = IS_CONST;
+ ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast TSRMLS_CC));
+ } else {
+ zend_compile_class_ref(&class_node, class_ast TSRMLS_CC);
+ }
opnum = get_next_op_number(CG(active_op_array));
- zend_emit_op(result, ZEND_NEW, &class_node, NULL TSRMLS_CC);
+ opline = zend_emit_op(result, ZEND_NEW, NULL, NULL TSRMLS_CC);
+
+ if (class_node.op_type == IS_CONST) {
+ opline->op1_type = IS_CONST;
+ opline->op1.constant = zend_add_class_name_literal(
+ CG(active_op_array), Z_STR(class_node.u.constant) TSRMLS_CC);
+ } else {
+ SET_NODE(opline->op1, &class_node);
+ }
zend_compile_call_common(&ctor_result, args_ast, NULL TSRMLS_CC);
zend_do_free(&ctor_result TSRMLS_CC);
@@ -3125,7 +3131,7 @@ void zend_compile_return(zend_ast *ast TSRMLS_DC) /* {{{ */
if (expr_ast) {
if (zend_is_call(expr_ast)) {
opline->extended_value = ZEND_RETURNS_FUNCTION;
- } else if (!zend_is_variable(expr_ast)) {
+ } else if (by_ref && !zend_is_variable(expr_ast)) {
opline->extended_value = ZEND_RETURNS_VALUE;
}
}
@@ -3812,7 +3818,7 @@ void zend_compile_params(zend_ast *ast TSRMLS_DC) /* {{{ */
arg_info = &arg_infos[i];
arg_info->name = estrndup(name->val, name->len);
- arg_info->name_len = name->len;
+ arg_info->name_len = (uint32_t)name->len;
arg_info->pass_by_reference = is_ref;
arg_info->is_variadic = is_variadic;
arg_info->type_hint = 0;
@@ -3856,7 +3862,7 @@ void zend_compile_params(zend_ast *ast TSRMLS_DC) /* {{{ */
arg_info->type_hint = IS_OBJECT;
arg_info->class_name = estrndup(class_name->val, class_name->len);
- arg_info->class_name_len = class_name->len;
+ arg_info->class_name_len = (uint32_t)class_name->len;
zend_string_release(class_name);
@@ -4389,7 +4395,6 @@ void zend_compile_use_trait(zend_ast *ast TSRMLS_DC) /* {{{ */
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_ADD_TRAIT;
SET_NODE(opline->op1, &CG(implementing_class));
- opline->extended_value = ZEND_FETCH_CLASS_TRAIT;
opline->op2_type = IS_CONST;
opline->op2.constant = zend_add_class_name_literal(CG(active_op_array),
zend_resolve_class_name_ast(trait_ast TSRMLS_CC) TSRMLS_CC);
@@ -4438,7 +4443,6 @@ void zend_compile_implements(znode *class_node, zend_ast *ast TSRMLS_DC) /* {{{
}
opline = zend_emit_op(NULL, ZEND_ADD_INTERFACE, class_node, NULL TSRMLS_CC);
- opline->extended_value = ZEND_FETCH_CLASS_INTERFACE;
opline->op2_type = IS_CONST;
opline->op2.constant = zend_add_class_name_literal(CG(active_op_array),
zend_resolve_class_name_ast(class_ast TSRMLS_CC) TSRMLS_CC);
@@ -5420,10 +5424,23 @@ void zend_compile_instanceof(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
"instanceof expects an object instance, constant given");
}
- opline = zend_compile_class_ref(&class_node, class_ast TSRMLS_CC);
- opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD;
+ if (zend_is_const_default_class_ref(class_ast)) {
+ class_node.op_type = IS_CONST;
+ ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast TSRMLS_CC));
+ } else {
+ opline = zend_compile_class_ref(&class_node, class_ast TSRMLS_CC);
+ opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD;
+ }
+
+ opline = zend_emit_op_tmp(result, ZEND_INSTANCEOF, &obj_node, NULL TSRMLS_CC);
- zend_emit_op_tmp(result, ZEND_INSTANCEOF, &obj_node, &class_node TSRMLS_CC);
+ if (class_node.op_type == IS_CONST) {
+ opline->op2_type = IS_CONST;
+ opline->op2.constant = zend_add_class_name_literal(
+ CG(active_op_array), Z_STR(class_node.u.constant) TSRMLS_CC);
+ } else {
+ SET_NODE(opline->op2, &class_node);
+ }
}
/* }}} */
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index e9ee6e56d7..bc9b88227f 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -619,7 +619,6 @@ int zend_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC);
#define ZEND_FETCH_TYPE_MASK 0x70000000
#define ZEND_FETCH_STANDARD 0x00000000
-#define ZEND_FETCH_MAKE_REF 0x04000000
#define ZEND_ISSET 0x02000000
#define ZEND_ISEMPTY 0x01000000
diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c
index 164901f898..61cc49e5c5 100644
--- a/Zend/zend_constants.c
+++ b/Zend/zend_constants.c
@@ -161,7 +161,7 @@ void clean_non_persistent_constants(TSRMLS_D)
}
}
-ZEND_API void zend_register_null_constant(const char *name, uint name_len, int flags, int module_number TSRMLS_DC)
+ZEND_API void zend_register_null_constant(const char *name, size_t name_len, int flags, int module_number TSRMLS_DC)
{
zend_constant c;
@@ -172,7 +172,7 @@ ZEND_API void zend_register_null_constant(const char *name, uint name_len, int f
zend_register_constant(&c TSRMLS_CC);
}
-ZEND_API void zend_register_bool_constant(const char *name, uint name_len, zend_bool bval, int flags, int module_number TSRMLS_DC)
+ZEND_API void zend_register_bool_constant(const char *name, size_t name_len, zend_bool bval, int flags, int module_number TSRMLS_DC)
{
zend_constant c;
@@ -183,7 +183,7 @@ ZEND_API void zend_register_bool_constant(const char *name, uint name_len, zend_
zend_register_constant(&c TSRMLS_CC);
}
-ZEND_API void zend_register_long_constant(const char *name, uint name_len, zend_long lval, int flags, int module_number TSRMLS_DC)
+ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zend_long lval, int flags, int module_number TSRMLS_DC)
{
zend_constant c;
@@ -195,7 +195,7 @@ ZEND_API void zend_register_long_constant(const char *name, uint name_len, zend_
}
-ZEND_API void zend_register_double_constant(const char *name, uint name_len, double dval, int flags, int module_number TSRMLS_DC)
+ZEND_API void zend_register_double_constant(const char *name, size_t name_len, double dval, int flags, int module_number TSRMLS_DC)
{
zend_constant c;
@@ -207,7 +207,7 @@ ZEND_API void zend_register_double_constant(const char *name, uint name_len, dou
}
-ZEND_API void zend_register_stringl_constant(const char *name, uint name_len, char *strval, uint strlen, int flags, int module_number TSRMLS_DC)
+ZEND_API void zend_register_stringl_constant(const char *name, size_t name_len, char *strval, size_t strlen, int flags, int module_number TSRMLS_DC)
{
zend_constant c;
@@ -219,12 +219,12 @@ ZEND_API void zend_register_stringl_constant(const char *name, uint name_len, ch
}
-ZEND_API void zend_register_string_constant(const char *name, uint name_len, char *strval, int flags, int module_number TSRMLS_DC)
+ZEND_API void zend_register_string_constant(const char *name, size_t name_len, char *strval, int flags, int module_number TSRMLS_DC)
{
zend_register_stringl_constant(name, name_len, strval, strlen(strval), flags, module_number TSRMLS_CC);
}
-static zend_constant *zend_get_special_constant(const char *name, uint name_len TSRMLS_DC)
+static zend_constant *zend_get_special_constant(const char *name, size_t name_len TSRMLS_DC)
{
zend_constant *c;
static char haltoff[] = "__COMPILER_HALT_OFFSET__";
@@ -236,7 +236,7 @@ static zend_constant *zend_get_special_constant(const char *name, uint name_len
/* Returned constants may be cached, so they have to be stored */
if (EG(scope) && EG(scope)->name) {
- int const_name_len;
+ size_t const_name_len;
zend_string *const_name;
const_name_len = sizeof("\0__CLASS__") + EG(scope)->name->len;
@@ -265,7 +265,7 @@ static zend_constant *zend_get_special_constant(const char *name, uint name_len
!memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) {
const char *cfilename;
zend_string *haltname;
- int clen;
+ size_t clen;
cfilename = zend_get_executed_filename(TSRMLS_C);
clen = strlen(cfilename);
@@ -281,7 +281,7 @@ static zend_constant *zend_get_special_constant(const char *name, uint name_len
}
-ZEND_API zval *zend_get_constant_str(const char *name, uint name_len TSRMLS_DC)
+ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len TSRMLS_DC)
{
zend_constant *c;
ALLOCA_FLAG(use_heap)
@@ -330,7 +330,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
zend_class_entry *ce = NULL;
zend_string *class_name;
const char *name = cname->val;
- uint name_len = cname->len;
+ size_t name_len = cname->len;
/* Skip leading \\ */
if (name[0] == '\\') {
@@ -342,7 +342,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
if ((colon = zend_memrchr(name, ':', name_len)) &&
colon > name && (*(colon - 1) == ':')) {
int class_name_len = colon - name - 1;
- int const_name_len = name_len - class_name_len - 2;
+ size_t const_name_len = name_len - class_name_len - 2;
zend_string *constant_name = zend_string_init(colon + 1, const_name_len, 0);
char *lcname;
zval *ret_constant = NULL;
@@ -408,10 +408,10 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
if ((colon = zend_memrchr(name, '\\', name_len)) != NULL) {
/* compound constant name */
int prefix_len = colon - name;
- int const_name_len = name_len - prefix_len - 1;
+ size_t const_name_len = name_len - prefix_len - 1;
const char *constant_name = colon + 1;
char *lcname;
- int lcname_len;
+ size_t lcname_len;
ALLOCA_FLAG(use_heap)
lcname_len = prefix_len + 1 + const_name_len;
diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h
index d81476f3f4..6d5542e1ec 100644
--- a/Zend/zend_constants.h
+++ b/Zend/zend_constants.h
@@ -66,14 +66,14 @@ int zend_shutdown_constants(TSRMLS_D);
void zend_register_standard_constants(TSRMLS_D);
void clean_non_persistent_constants(TSRMLS_D);
ZEND_API zval *zend_get_constant(zend_string *name TSRMLS_DC);
-ZEND_API zval *zend_get_constant_str(const char *name, uint name_len TSRMLS_DC);
+ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len TSRMLS_DC);
ZEND_API zval *zend_get_constant_ex(zend_string *name, zend_class_entry *scope, zend_ulong flags TSRMLS_DC);
-ZEND_API void zend_register_bool_constant(const char *name, uint name_len, zend_bool bval, int flags, int module_number TSRMLS_DC);
-ZEND_API void zend_register_null_constant(const char *name, uint name_len, int flags, int module_number TSRMLS_DC);
-ZEND_API void zend_register_long_constant(const char *name, uint name_len, zend_long lval, int flags, int module_number TSRMLS_DC);
-ZEND_API void zend_register_double_constant(const char *name, uint name_len, double dval, int flags, int module_number TSRMLS_DC);
-ZEND_API void zend_register_string_constant(const char *name, uint name_len, char *strval, int flags, int module_number TSRMLS_DC);
-ZEND_API void zend_register_stringl_constant(const char *name, uint name_len, char *strval, uint strlen, int flags, int module_number TSRMLS_DC);
+ZEND_API void zend_register_bool_constant(const char *name, size_t name_len, zend_bool bval, int flags, int module_number TSRMLS_DC);
+ZEND_API void zend_register_null_constant(const char *name, size_t name_len, int flags, int module_number TSRMLS_DC);
+ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zend_long lval, int flags, int module_number TSRMLS_DC);
+ZEND_API void zend_register_double_constant(const char *name, size_t name_len, double dval, int flags, int module_number TSRMLS_DC);
+ZEND_API void zend_register_string_constant(const char *name, size_t name_len, char *strval, int flags, int module_number TSRMLS_DC);
+ZEND_API void zend_register_stringl_constant(const char *name, size_t name_len, char *strval, size_t strlen, int flags, int module_number TSRMLS_DC);
ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC);
void zend_copy_constants(HashTable *target, HashTable *sourc);
zend_constant *zend_quick_get_constant(const zval *key, zend_ulong flags TSRMLS_DC);
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index f9c1a509a6..4159a46d3c 100644
--- a/Zend/zend_exceptions.c
+++ b/Zend/zend_exceptions.c
@@ -90,7 +90,7 @@ ZEND_API void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */
#ifdef HAVE_DTRACE
if (DTRACE_EXCEPTION_THROWN_ENABLED()) {
if (exception != NULL) {
- DTRACE_EXCEPTION_THROWN(Z_OBJ_P(exception)->ce->val);
+ DTRACE_EXCEPTION_THROWN(Z_OBJ_P(exception)->ce->name->val);
} else {
DTRACE_EXCEPTION_THROWN(NULL);
}
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 58038c94a4..61a605971e 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -547,13 +547,13 @@ static inline zval* make_real_object(zval *object_ptr TSRMLS_DC)
return object;
}
-ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, zend_ulong fetch_type, char **class_name, zend_class_entry **pce TSRMLS_DC)
+ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, char **class_name, zend_class_entry **pce TSRMLS_DC)
{
zend_string *key;
ALLOCA_FLAG(use_heap);
STR_ALLOCA_INIT(key, cur_arg_info->class_name, cur_arg_info->class_name_len, use_heap);
- *pce = zend_fetch_class(key, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
+ *pce = zend_fetch_class(key, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
STR_ALLOCA_FREE(key, use_heap);
*class_name = (*pce) ? (*pce)->name->val : (char*)cur_arg_info->class_name;
@@ -596,7 +596,7 @@ ZEND_API void zend_verify_arg_error(int error_type, const zend_function *zf, uin
}
}
-static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, zend_ulong fetch_type TSRMLS_DC)
+static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg TSRMLS_DC)
{
zend_arg_info *cur_arg_info;
char *need_msg;
@@ -619,12 +619,12 @@ static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg,
ZVAL_DEREF(arg);
if (Z_TYPE_P(arg) == IS_OBJECT) {
- need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
+ need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC);
if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name->val, arg TSRMLS_CC);
}
} else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
- need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
+ need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC);
zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "", arg TSRMLS_CC);
}
} else if (cur_arg_info->type_hint) {
@@ -645,7 +645,7 @@ static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg,
}
}
-static inline int zend_verify_missing_arg_type(zend_function *zf, uint32_t arg_num, zend_ulong fetch_type TSRMLS_DC)
+static inline int zend_verify_missing_arg_type(zend_function *zf, uint32_t arg_num TSRMLS_DC)
{
zend_arg_info *cur_arg_info;
char *need_msg;
@@ -666,7 +666,7 @@ static inline int zend_verify_missing_arg_type(zend_function *zf, uint32_t arg_n
if (cur_arg_info->class_name) {
char *class_name;
- need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
+ need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC);
zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "none", "", NULL TSRMLS_CC);
return 0;
} else if (cur_arg_info->type_hint) {
@@ -687,7 +687,7 @@ static inline int zend_verify_missing_arg_type(zend_function *zf, uint32_t arg_n
static void zend_verify_missing_arg(zend_execute_data *execute_data, uint32_t arg_num TSRMLS_DC)
{
if (EXPECTED(!(EX(func)->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) ||
- zend_verify_missing_arg_type(EX(func), arg_num, EX(opline)->extended_value TSRMLS_CC)) {
+ zend_verify_missing_arg_type(EX(func), arg_num TSRMLS_CC)) {
const char *class_name = EX(func)->common.scope ? EX(func)->common.scope->name->val : "";
const char *space = EX(func)->common.scope ? "::" : "";
const char *func_name = EX(func)->common.function_name ? EX(func)->common.function_name->val : "main";
@@ -1048,12 +1048,61 @@ str_index:
return retval;
}
-static zend_always_inline zval *zend_fetch_dimension_address(zval *result, zval *container_ptr, zval *dim, int dim_type, int type, int is_ref, int allow_str_offset TSRMLS_DC)
+static zend_never_inline zend_long zend_check_string_offset(zval *container, zval *dim, int type TSRMLS_DC)
+{
+ zend_long offset;
+
+ if (dim == NULL) {
+ zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
+ }
+
+ if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
+ switch(Z_TYPE_P(dim)) {
+ case IS_STRING:
+ if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
+ break;
+ }
+ if (type != BP_VAR_UNSET) {
+ zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
+ }
+ break;
+ case IS_DOUBLE:
+ case IS_NULL:
+ case IS_FALSE:
+ case IS_TRUE:
+ zend_error(E_NOTICE, "String offset cast occurred");
+ break;
+ default:
+ zend_error(E_WARNING, "Illegal offset type");
+ break;
+ }
+
+ offset = zval_get_long(dim);
+ } else {
+ offset = Z_LVAL_P(dim);
+ }
+
+ return offset;
+}
+
+static zend_always_inline zend_long zend_fetch_string_offset(zval *container, zval *dim, int type TSRMLS_DC)
+{
+ zend_long offset = zend_check_string_offset(container, dim, type TSRMLS_CC);
+
+ if (Z_REFCOUNTED_P(container)) {
+ if (Z_REFCOUNT_P(container) > 1) {
+ Z_DELREF_P(container);
+ zval_copy_ctor_func(container);
+ }
+ Z_ADDREF_P(container);
+ }
+ return offset;
+}
+
+static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *container, zval *dim, int dim_type, int type TSRMLS_DC)
{
zval *retval;
- zval *container = container_ptr;
- ZVAL_DEREF(container);
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
SEPARATE_ARRAY(container);
fetch_from_array:
@@ -1066,13 +1115,8 @@ fetch_from_array:
} else {
retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
}
- if (is_ref) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(result, retval);
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- zend_long offset;
-
if (type != BP_VAR_UNSET && UNEXPECTED(Z_STRLEN_P(container) == 0)) {
zval_ptr_dtor_nogc(container);
convert_to_array:
@@ -1081,49 +1125,9 @@ convert_to_array:
goto fetch_from_array;
}
- if (dim == NULL) {
- zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
- }
-
- if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
- switch(Z_TYPE_P(dim)) {
- case IS_STRING:
- if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
- break;
- }
- if (type != BP_VAR_UNSET) {
- zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
- }
- break;
- case IS_DOUBLE:
- case IS_NULL:
- case IS_FALSE:
- case IS_TRUE:
- zend_error(E_NOTICE, "String offset cast occurred");
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- break;
- }
-
- offset = zval_get_long(dim);
- } else {
- offset = Z_LVAL_P(dim);
- }
-
- if (allow_str_offset) {
- if (Z_REFCOUNTED_P(container)) {
- if (Z_REFCOUNT_P(container) > 1) {
- Z_DELREF_P(container);
- zval_copy_ctor_func(container);
- }
- Z_ADDREF_P(container);
- }
- ZVAL_LONG(result, offset);
- return container; /* assignment to string offset */
- } else {
- ZVAL_INDIRECT(result, NULL); /* wrong string offset */
- }
+ zend_check_string_offset(container, dim, type TSRMLS_CC);
+
+ ZVAL_INDIRECT(result, NULL); /* wrong string offset */
} else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (!Z_OBJ_HT_P(container)->read_dimension) {
zend_error_noreturn(E_ERROR, "Cannot use object as array");
@@ -1154,9 +1158,6 @@ convert_to_array:
}
}
if (result != retval) {
- if (is_ref) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(result, retval);
}
} else {
@@ -1185,32 +1186,21 @@ convert_to_array:
ZVAL_INDIRECT(result, &EG(error_zval));
}
}
- return NULL; /* not an assignment to string offset */
}
static zend_never_inline void zend_fetch_dimension_address_W(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
{
- zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 0, 0 TSRMLS_CC);
-}
-
-static zend_never_inline zval *zend_fetch_dimension_address_W_str(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
-{
- return zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 0, 1 TSRMLS_CC);
-}
-
-static zend_never_inline void zend_fetch_dimension_address_W_ref(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
-{
- zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 1, 0 TSRMLS_CC);
+ zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W TSRMLS_CC);
}
static zend_never_inline void zend_fetch_dimension_address_RW(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
{
- zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_RW, 0, 0 TSRMLS_CC);
+ zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_RW TSRMLS_CC);
}
static zend_never_inline void zend_fetch_dimension_address_UNSET(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
{
- zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET, 0, 0 TSRMLS_CC);
+ zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET TSRMLS_CC);
}
static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type TSRMLS_DC)
@@ -1302,7 +1292,7 @@ ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *
zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR TSRMLS_CC);
}
-static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, void **cache_slot, int type, int is_ref TSRMLS_DC)
+static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, void **cache_slot, int type TSRMLS_DC)
{
if (container_op_type != IS_UNUSED) {
ZVAL_DEREF(container);
@@ -1332,26 +1322,17 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
if (Z_OBJ_HT_P(container)->read_property &&
(ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result TSRMLS_CC)) != NULL) {
if (ptr != result) {
- if (is_ref && ptr != &EG(uninitialized_zval)) {
- ZVAL_MAKE_REF(ptr);
- }
ZVAL_INDIRECT(result, ptr);
}
} else {
zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access");
}
} else {
- if (is_ref) {
- ZVAL_MAKE_REF(ptr);
- }
ZVAL_INDIRECT(result, ptr);
}
} else if (EXPECTED(Z_OBJ_HT_P(container)->read_property)) {
zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result TSRMLS_CC);
if (ptr != result) {
- if (is_ref && ptr != &EG(uninitialized_zval)) {
- ZVAL_MAKE_REF(ptr);
- }
ZVAL_INDIRECT(result, ptr);
}
} else {
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h
index 95421191f0..982413e032 100644
--- a/Zend/zend_execute.h
+++ b/Zend/zend_execute.h
@@ -44,11 +44,11 @@ ZEND_API int zend_is_true(zval *op TSRMLS_DC);
ZEND_API zend_class_entry *zend_lookup_class(zend_string *name TSRMLS_DC);
ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *key, int use_autoload TSRMLS_DC);
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC);
-ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *string_name TSRMLS_DC);
+ZEND_API int zend_eval_stringl(char *str, size_t str_len, zval *retval_ptr, char *string_name TSRMLS_DC);
ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
-ZEND_API int zend_eval_stringl_ex(char *str, int str_len, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
+ZEND_API int zend_eval_stringl_ex(char *str, size_t str_len, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
-ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, zend_ulong fetch_type, char **class_name, zend_class_entry **pce TSRMLS_DC);
+ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, char **class_name, zend_class_entry **pce TSRMLS_DC);
ZEND_API void zend_verify_arg_error(int error_type, const zend_function *zf, uint32_t arg_num, const char *need_msg, const char *need_kind, const char *given_msg, const char *given_kind, zval *arg TSRMLS_DC);
static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC TSRMLS_DC)
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index bd24609d01..7cbf2ac87c 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -529,7 +529,7 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas
char *actual = Z_STRVAL_P(p);
if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) {
- int len;
+ size_t len;
zend_error(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p));
len = Z_STRLEN_P(p) - ((colon - Z_STRVAL_P(p)) + 1);
@@ -544,7 +544,7 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas
} else {
zend_string *save = Z_STR_P(p);
char *slash;
- int actual_len = Z_STRLEN_P(p);
+ size_t actual_len = Z_STRLEN_P(p);
if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) {
actual = slash + 1;
actual_len -= (actual - Z_STRVAL_P(p));
@@ -1055,7 +1055,7 @@ ZEND_API zend_class_entry *zend_lookup_class(zend_string *name TSRMLS_DC) /* {{{
}
/* }}} */
-ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *string_name TSRMLS_DC) /* {{{ */
+ZEND_API int zend_eval_stringl(char *str, size_t str_len, zval *retval_ptr, char *string_name TSRMLS_DC) /* {{{ */
{
zval pv;
zend_op_array *new_op_array;
@@ -1123,7 +1123,7 @@ ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSR
}
/* }}} */
-ZEND_API int zend_eval_stringl_ex(char *str, int str_len, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) /* {{{ */
+ZEND_API int zend_eval_stringl_ex(char *str, size_t str_len, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) /* {{{ */
{
int result;
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index dfd63aa7e1..6dc0941c6f 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -99,19 +99,34 @@ static const uint32_t uninitialized_bucket = {INVALID_IDX};
ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
{
- uint32_t i = 3;
-
- SET_INCONSISTENT(HT_OK);
-
- if (nSize >= 0x80000000) {
+ /* Use big enough power of 2 */
+#ifdef PHP_WIN32
+ if (nSize <= 8) {
+ ht->nTableSize = 8;
+ } else if (nSize >= 0x80000000) {
/* prevent overflow */
ht->nTableSize = 0x80000000;
} else {
- while ((1U << i) < nSize) {
- i++;
+ ht->nTableSize = 1U << __lzcnt(nSize);
+ if (ht->nTableSize < nSize) {
+ ht->nTableSize <<= 1;
}
- ht->nTableSize = 1 << i;
}
+#else
+ /* size should be between 8 and 0x80000000 */
+ nSize = (nSize <= 8 ? 8 : (nSize >= 0x80000000 ? 0x80000000 : nSize));
+# if defined(__GNUC__)
+ ht->nTableSize = 0x2 << (__builtin_clz(nSize - 1) ^ 0x1f);
+# else
+ nSize -= 1;
+ nSize |= (nSize >> 1);
+ nSize |= (nSize >> 2);
+ nSize |= (nSize >> 4);
+ nSize |= (nSize >> 8);
+ nSize |= (nSize >> 16);
+ ht->nTableSize = nSize + 1;
+# endif
+#endif
ht->nTableMask = 0; /* 0 means that ht->arBuckets is uninitialized */
ht->nNumUsed = 0;
@@ -121,11 +136,7 @@ ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestru
ht->arHash = (uint32_t*)&uninitialized_bucket;
ht->pDestructor = pDestructor;
ht->nInternalPointer = INVALID_IDX;
- if (persistent) {
- ht->u.flags = HASH_FLAG_PERSISTENT | HASH_FLAG_APPLY_PROTECTION;
- } else {
- ht->u.flags = HASH_FLAG_APPLY_PROTECTION;
- }
+ ht->u.flags = (persistent ? HASH_FLAG_PERSISTENT : 0) | HASH_FLAG_APPLY_PROTECTION;
}
static void zend_hash_packed_grow(HashTable *ht)
@@ -1749,11 +1760,12 @@ ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t co
return result;
}
} else { /* string indices */
- result = (p1->key ? p1->key->len : 0) - (p2->key ? p2->key->len : 0);
- if (result != 0) {
+ size_t len0 = (p1->key ? p1->key->len : 0);
+ size_t len1 = (p2->key ? p2->key->len : 0);
+ if (len0 != len1) {
HASH_UNPROTECT_RECURSION(ht1);
HASH_UNPROTECT_RECURSION(ht2);
- return result;
+ return len0 > len1 ? 1 : -1;
}
result = memcmp(p1->key->val, p2->key->val, p1->key->len);
if (result != 0) {
diff --git a/Zend/zend_highlight.c b/Zend/zend_highlight.c
index 26c34686a6..79a552635f 100644
--- a/Zend/zend_highlight.c
+++ b/Zend/zend_highlight.c
@@ -54,7 +54,7 @@ ZEND_API void zend_html_putc(char c)
}
-ZEND_API void zend_html_puts(const char *s, uint len TSRMLS_DC)
+ZEND_API void zend_html_puts(const char *s, size_t len TSRMLS_DC)
{
const unsigned char *ptr = (const unsigned char*)s, *end = ptr + len;
unsigned char *filtered = NULL;
diff --git a/Zend/zend_highlight.h b/Zend/zend_highlight.h
index 1a35505135..3e91fd71f4 100644
--- a/Zend/zend_highlight.h
+++ b/Zend/zend_highlight.h
@@ -44,7 +44,7 @@ ZEND_API void zend_strip(TSRMLS_D);
ZEND_API int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini TSRMLS_DC);
ZEND_API int highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, char *str_name TSRMLS_DC);
ZEND_API void zend_html_putc(char c);
-ZEND_API void zend_html_puts(const char *s, uint len TSRMLS_DC);
+ZEND_API void zend_html_puts(const char *s, size_t len TSRMLS_DC);
END_EXTERN_C()
extern zend_syntax_highlighter_ini syntax_highlighter_ini;
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index e9897ed34e..6b4e8f1a97 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -268,12 +268,7 @@ static zend_always_inline int zend_verify_property_access(zend_property_info *pr
case ZEND_ACC_PROTECTED:
return zend_check_protected(property_info->ce, EG(scope));
case ZEND_ACC_PRIVATE:
- if ((ce==EG(scope) || property_info->ce == EG(scope)) && EG(scope)) {
- return 1;
- } else {
- return 0;
- }
- break;
+ return (ce == EG(scope) || property_info->ce == EG(scope));
}
return 0;
}
@@ -295,9 +290,9 @@ static zend_always_inline zend_bool is_derived_class(zend_class_entry *child_cla
static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_class_entry *ce, zend_string *member, int silent, void **cache_slot TSRMLS_DC) /* {{{ */
{
- zend_property_info *property_info;
- zend_property_info *scope_property_info;
- zend_bool denied_access = 0;
+ zval *zv;
+ zend_property_info *property_info = NULL;
+ uint32_t flags;
if (cache_slot && EXPECTED(ce == CACHED_PTR_EX(cache_slot))) {
return CACHED_PTR_EX(cache_slot + 1);
@@ -313,60 +308,61 @@ static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_
}
return ZEND_WRONG_PROPERTY_INFO;
}
- property_info = zend_hash_find_ptr(&ce->properties_info, member);
- if (property_info != NULL) {
- if (UNEXPECTED((property_info->flags & ZEND_ACC_SHADOW) != 0)) {
+
+ if (UNEXPECTED(zend_hash_num_elements(&ce->properties_info) == 0)) {
+ goto exit_dynamic;
+ }
+
+ zv = zend_hash_find(&ce->properties_info, member);
+ if (EXPECTED(zv != NULL)) {
+ property_info = (zend_property_info*)Z_PTR_P(zv);
+ flags = property_info->flags;
+ if (UNEXPECTED((flags & ZEND_ACC_SHADOW) != 0)) {
/* if it's a shadow - go to access it's private */
property_info = NULL;
} else {
if (EXPECTED(zend_verify_property_access(property_info, ce TSRMLS_CC) != 0)) {
- if (EXPECTED((property_info->flags & ZEND_ACC_CHANGED) != 0)
- && EXPECTED(!(property_info->flags & ZEND_ACC_PRIVATE))) {
- /* We still need to make sure that we're not in a context
- * where the right property is a different 'statically linked' private
- * continue checking below...
- */
- } else {
- if (UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) != 0) && !silent) {
+ if (UNEXPECTED(!(flags & ZEND_ACC_CHANGED))
+ || UNEXPECTED((flags & ZEND_ACC_PRIVATE))) {
+ if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0) && !silent) {
zend_error(E_STRICT, "Accessing static property %s::$%s as non static", ce->name->val, member->val);
}
- if (cache_slot) {
- CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, property_info);
- }
- return property_info;
+ goto exit;
}
} else {
/* Try to look in the scope instead */
- denied_access = 1;
+ property_info = ZEND_WRONG_PROPERTY_INFO;
}
}
}
+
if (EG(scope) != ce
&& EG(scope)
&& is_derived_class(ce, EG(scope))
- && (scope_property_info = zend_hash_find_ptr(&EG(scope)->properties_info, member)) != NULL
- && scope_property_info->flags & ZEND_ACC_PRIVATE) {
+ && (zv = zend_hash_find(&EG(scope)->properties_info, member)) != NULL
+ && ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE) {
+ property_info = (zend_property_info*)Z_PTR_P(zv);
+ goto exit;
+ } else if (UNEXPECTED(property_info == NULL)) {
+exit_dynamic:
if (cache_slot) {
- CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, scope_property_info);
+ CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, NULL);
}
- return scope_property_info;
- } else if (property_info) {
- if (UNEXPECTED(denied_access != 0)) {
- /* Information was available, but we were denied access. Error out. */
- if (!silent) {
- zend_error_noreturn(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name->val, member->val);
- }
- return ZEND_WRONG_PROPERTY_INFO;
- } else {
- /* fall through, return property_info... */
- if (cache_slot) {
- CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, property_info);
- }
+ return NULL;
+ } else if (UNEXPECTED(property_info == ZEND_WRONG_PROPERTY_INFO)) {
+ /* Information was available, but we were denied access. Error out. */
+ if (!silent) {
+ zend_error_noreturn(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(flags), ce->name->val, member->val);
}
- } else {
if (cache_slot) {
- CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, NULL);
+ CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, ZEND_WRONG_PROPERTY_INFO);
}
+ return ZEND_WRONG_PROPERTY_INFO;
+ }
+
+exit:
+ if (cache_slot) {
+ CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, property_info);
}
return property_info;
}
@@ -462,12 +458,12 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_
EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) {
retval = &zobj->properties_table[property_info->offset];
- if (Z_TYPE_P(retval) != IS_UNDEF) {
+ if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
goto exit;
}
- } else if (UNEXPECTED(zobj->properties != NULL)) {
+ } else if (EXPECTED(zobj->properties != NULL)) {
retval = zend_hash_find(zobj->properties, Z_STR_P(member));
- if (retval) goto exit;
+ if (EXPECTED(retval)) goto exit;
}
}
@@ -831,7 +827,7 @@ static void zend_std_unset_property(zval *object, zval *member, void **cache_slo
ZVAL_UNDEF(&zobj->properties_table[property_info->offset]);
goto exit;
}
- } else if (zobj->properties &&
+ } else if (EXPECTED(zobj->properties != NULL) &&
EXPECTED(zend_hash_del(zobj->properties, Z_STR_P(member)) != FAILURE)) {
goto exit;
}
@@ -1427,7 +1423,7 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists,
if (Z_TYPE_P(value) != IS_UNDEF) {
goto found;
}
- } else if (UNEXPECTED(zobj->properties != NULL) &&
+ } else if (EXPECTED(zobj->properties != NULL) &&
(value = zend_hash_find(zobj->properties, Z_STR_P(member))) != NULL) {
found:
switch (has_set_exists) {
diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c
index 40d37b3d36..58c034163e 100644
--- a/Zend/zend_objects.c
+++ b/Zend/zend_objects.c
@@ -144,7 +144,8 @@ ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *o
if (old_object->ce->default_properties_count) {
for (i = 0; i < old_object->ce->default_properties_count; i++) {
zval_ptr_dtor(&new_object->properties_table[i]);
- ZVAL_COPY(&new_object->properties_table[i], &old_object->properties_table[i]);
+ ZVAL_COPY_VALUE(&new_object->properties_table[i], &old_object->properties_table[i]);
+ zval_add_ref(&new_object->properties_table[i]);
}
}
if (old_object->properties) {
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index b0a0e7519e..03e913c31d 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -924,7 +924,7 @@ ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ *
} else if (Z_ISREF_P(op2)) {
op2 = Z_REFVAL_P(op2);
} else if (!converted) {
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD);
+ ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD, add_function);
zendi_convert_scalar_to_number(op1, op1_copy, result);
zendi_convert_scalar_to_number(op2, op2_copy, result);
@@ -977,7 +977,7 @@ ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ *
} else if (Z_ISREF_P(op2)) {
op2 = Z_REFVAL_P(op2);
} else if (!converted) {
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB);
+ ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB, sub_function);
zendi_convert_scalar_to_number(op1, op1_copy, result);
zendi_convert_scalar_to_number(op2, op2_copy, result);
@@ -1024,7 +1024,7 @@ ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ *
} else if (Z_ISREF_P(op2)) {
op2 = Z_REFVAL_P(op2);
} else if (!converted) {
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL);
+ ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL, mul_function);
zendi_convert_scalar_to_number(op1, op1_copy, result);
zendi_convert_scalar_to_number(op2, op2_copy, result);
@@ -1102,7 +1102,7 @@ ZEND_API int pow_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ *
} else if (Z_ISREF_P(op2)) {
op2 = Z_REFVAL_P(op2);
} else if (!converted) {
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_POW);
+ ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_POW, pow_function);
if (Z_TYPE_P(op1) == IS_ARRAY) {
ZVAL_LONG(result, 0);
@@ -1183,7 +1183,7 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ *
} else if (Z_ISREF_P(op2)) {
op2 = Z_REFVAL_P(op2);
} else if (!converted) {
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV);
+ ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV, div_function);
zendi_convert_scalar_to_number(op1, op1_copy, result);
zendi_convert_scalar_to_number(op2, op2_copy, result);
@@ -1202,14 +1202,14 @@ ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ *
zval op1_copy, op2_copy;
zend_long op1_lval;
- if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MOD);
-
+ if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_MOD, mod_function);
zendi_convert_to_long(op1, op1_copy, result);
- op1_lval = Z_LVAL_P(op1);
+ }
+ op1_lval = Z_LVAL_P(op1);
+ if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
+ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_MOD);
zendi_convert_to_long(op2, op2_copy, result);
- } else {
- op1_lval = Z_LVAL_P(op1);
}
if (Z_LVAL_P(op2) == 0) {
@@ -1234,15 +1234,14 @@ ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
zval op1_copy, op2_copy;
zend_long op1_lval;
- if ((Z_TYPE_P(op1) != IS_FALSE && Z_TYPE_P(op1) != IS_TRUE) ||
- (Z_TYPE_P(op2) != IS_FALSE && Z_TYPE_P(op2) != IS_TRUE)) {
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BOOL_XOR);
-
+ if (UNEXPECTED(Z_TYPE_P(op1) != IS_FALSE && Z_TYPE_P(op1) != IS_TRUE)) {
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BOOL_XOR, boolean_xor_function);
zendi_convert_to_boolean(op1, op1_copy, result);
- op1_lval = Z_TYPE_P(op1) == IS_TRUE;
+ }
+ op1_lval = Z_TYPE_P(op1) == IS_TRUE;
+ if (UNEXPECTED(Z_TYPE_P(op2) != IS_FALSE && Z_TYPE_P(op2) != IS_TRUE)) {
+ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BOOL_XOR);
zendi_convert_to_boolean(op2, op2_copy, result);
- } else {
- op1_lval = Z_TYPE_P(op1) == IS_TRUE;
}
ZVAL_BOOL(result, op1_lval ^ (Z_TYPE_P(op2) == IS_TRUE));
@@ -1281,11 +1280,10 @@ ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
return SUCCESS;
case IS_STRING: {
size_t i;
- zval op1_copy = *op1;
- ZVAL_NEW_STR(result, zend_string_alloc(Z_STRLEN(op1_copy), 0));
- for (i = 0; i < Z_STRLEN(op1_copy); i++) {
- Z_STRVAL_P(result)[i] = ~Z_STRVAL(op1_copy)[i];
+ ZVAL_NEW_STR(result, zend_string_alloc(Z_STRLEN_P(op1), 0));
+ for (i = 0; i < Z_STRLEN_P(op1); i++) {
+ Z_STRVAL_P(result)[i] = ~Z_STRVAL_P(op1)[i];
}
Z_STRVAL_P(result)[i] = 0;
return SUCCESS;
@@ -1329,14 +1327,14 @@ ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /
return SUCCESS;
}
- if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_OR);
-
+ if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_OR, bitwise_or_function);
zendi_convert_to_long(op1, op1_copy, result);
- op1_lval = Z_LVAL_P(op1);
+ }
+ op1_lval = Z_LVAL_P(op1);
+ if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
+ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_OR);
zendi_convert_to_long(op2, op2_copy, result);
- } else {
- op1_lval = Z_LVAL_P(op1);
}
ZVAL_LONG(result, op1_lval | Z_LVAL_P(op2));
@@ -1374,14 +1372,14 @@ ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
return SUCCESS;
}
- if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_AND);
-
+ if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_AND, bitwise_and_function);
zendi_convert_to_long(op1, op1_copy, result);
- op1_lval = Z_LVAL_P(op1);
+ }
+ op1_lval = Z_LVAL_P(op1);
+ if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
+ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_AND);
zendi_convert_to_long(op2, op2_copy, result);
- } else {
- op1_lval = Z_LVAL_P(op1);
}
ZVAL_LONG(result, op1_lval & Z_LVAL_P(op2));
@@ -1419,14 +1417,14 @@ ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
return SUCCESS;
}
- if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_XOR);
-
+ if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_XOR, bitwise_xor_function);
zendi_convert_to_long(op1, op1_copy, result);
- op1_lval = Z_LVAL_P(op1);
+ }
+ op1_lval = Z_LVAL_P(op1);
+ if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
+ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_XOR);
zendi_convert_to_long(op2, op2_copy, result);
- } else {
- op1_lval = Z_LVAL_P(op1);
}
ZVAL_LONG(result, op1_lval ^ Z_LVAL_P(op2));
@@ -1439,14 +1437,14 @@ ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /
zval op1_copy, op2_copy;
zend_long op1_lval;
- if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SL);
-
+ if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_SL, shift_left_function);
zendi_convert_to_long(op1, op1_copy, result);
- op1_lval = Z_LVAL_P(op1);
+ }
+ op1_lval = Z_LVAL_P(op1);
+ if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
+ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_SL);
zendi_convert_to_long(op2, op2_copy, result);
- } else {
- op1_lval = Z_LVAL_P(op1);
}
/* prevent wrapping quirkiness on some processors where << 64 + x == << x */
@@ -1471,14 +1469,14 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
zval op1_copy, op2_copy;
zend_long op1_lval;
- if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SR);
-
+ if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_SR, shift_right_function);
zendi_convert_to_long(op1, op1_copy, result);
- op1_lval = Z_LVAL_P(op1);
+ }
+ op1_lval = Z_LVAL_P(op1);
+ if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
+ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_SR);
zendi_convert_to_long(op2, op2_copy, result);
- } else {
- op1_lval = Z_LVAL_P(op1);
}
/* prevent wrapping quirkiness on some processors where >> 64 + x == >> x */
@@ -1530,29 +1528,28 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{
zval op1_copy, op2_copy;
int use_copy1 = 0, use_copy2 = 0;
- if (UNEXPECTED(Z_TYPE_P(op1) != IS_STRING) ||
- UNEXPECTED(Z_TYPE_P(op2) != IS_STRING)) {
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT);
-
- if (Z_TYPE_P(op1) != IS_STRING) {
- use_copy1 = zend_make_printable_zval(op1, &op1_copy TSRMLS_CC);
- }
- if (Z_TYPE_P(op2) != IS_STRING) {
- use_copy2 = zend_make_printable_zval(op2, &op2_copy TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(op1) != IS_STRING)) {
+ ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT, concat_function);
+ use_copy1 = zend_make_printable_zval(op1, &op1_copy TSRMLS_CC);
+ if (use_copy1) {
+ /* We have created a converted copy of op1. Therefore, op1 won't become the result so
+ * we have to free it.
+ */
+ if (result == op1) {
+ zval_dtor(op1);
+ if (UNEXPECTED(op1 == op2)) {
+ op2 = &op1_copy;
+ }
+ }
+ op1 = &op1_copy;
}
}
-
- if (use_copy1) {
- /* We have created a converted copy of op1. Therefore, op1 won't become the result so
- * we have to free it.
- */
- if (result == op1) {
- zval_dtor(op1);
+ if (UNEXPECTED(Z_TYPE_P(op2) != IS_STRING)) {
+ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_CONCAT);
+ use_copy2 = zend_make_printable_zval(op2, &op2_copy TSRMLS_CC);
+ if (use_copy2) {
+ op2 = &op2_copy;
}
- op1 = &op1_copy;
- }
- if (use_copy2) {
- op2 = &op2_copy;
}
{
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index 8075edf939..f95e856e68 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -887,22 +887,43 @@ static zend_always_inline void fast_is_not_identical_function(zval *result, zval
ZVAL_BOOL(result, Z_TYPE_P(result) != IS_TRUE);
}
-#define ZEND_TRY_BINARY_OBJECT_OPERATION(opcode) \
- if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, do_operation)) { \
- if (SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, op2 TSRMLS_CC)) { \
- return SUCCESS; \
- } \
- } else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, do_operation)) { \
- if (SUCCESS == Z_OBJ_HANDLER_P(op2, do_operation)(opcode, result, op1, op2 TSRMLS_CC)) { \
- return SUCCESS; \
- } \
+#define ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode, binary_op) \
+ if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT) \
+ && op1 == result \
+ && UNEXPECTED(Z_OBJ_HANDLER_P(op1, get)) \
+ && EXPECTED(Z_OBJ_HANDLER_P(op1, set))) { \
+ int ret; \
+ zval rv; \
+ zval *objval = Z_OBJ_HANDLER_P(op1, get)(op1, &rv TSRMLS_CC); \
+ Z_ADDREF_P(objval); \
+ ret = binary_op(objval, objval, op2 TSRMLS_CC); \
+ Z_OBJ_HANDLER_P(op1, set)(op1, objval TSRMLS_CC); \
+ zval_ptr_dtor(objval); \
+ return ret; \
+ } else if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT) \
+ && UNEXPECTED(Z_OBJ_HANDLER_P(op1, do_operation))) { \
+ if (EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, op2 TSRMLS_CC))) { \
+ return SUCCESS; \
+ } \
}
-#define ZEND_TRY_UNARY_OBJECT_OPERATION(opcode) \
- if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, do_operation) \
- && SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, NULL TSRMLS_CC) \
- ) { \
- return SUCCESS; \
+#define ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(opcode) \
+ if (UNEXPECTED(Z_TYPE_P(op2) == IS_OBJECT) \
+ && UNEXPECTED(Z_OBJ_HANDLER_P(op2, do_operation)) \
+ && EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op2, do_operation)(opcode, result, op1, op2 TSRMLS_CC))) { \
+ return SUCCESS; \
+ }
+
+#define ZEND_TRY_BINARY_OBJECT_OPERATION(opcode, binary_op) \
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode, binary_op) \
+ else \
+ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(opcode)
+
+#define ZEND_TRY_UNARY_OBJECT_OPERATION(opcode) \
+ if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT) \
+ && UNEXPECTED(Z_OBJ_HANDLER_P(op1, do_operation)) \
+ && EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, NULL TSRMLS_CC))) { \
+ return SUCCESS; \
}
/* buf points to the END of the buffer */
diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c
index 3e68a38487..aae8465791 100644
--- a/Zend/zend_variables.c
+++ b/Zend/zend_variables.c
@@ -221,7 +221,7 @@ ZEND_API void zval_add_ref_unref(zval *p)
{
if (Z_REFCOUNTED_P(p)) {
if (Z_ISREF_P(p)) {
- ZVAL_DUP(p, Z_REFVAL_P(p));
+ ZVAL_COPY(p, Z_REFVAL_P(p));
} else {
Z_ADDREF_P(p);
}
@@ -266,7 +266,7 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
}
-ZEND_API int zend_print_variable(zval *var TSRMLS_DC)
+ZEND_API size_t zend_print_variable(zval *var TSRMLS_DC)
{
return zend_print_zval(var, 0 TSRMLS_CC);
}
diff --git a/Zend/zend_variables.h b/Zend/zend_variables.h
index 94ae438e9d..4f840bdd8a 100644
--- a/Zend/zend_variables.h
+++ b/Zend/zend_variables.h
@@ -93,7 +93,7 @@ static zend_always_inline void _zval_opt_copy_ctor_no_imm(zval *zvalue ZEND_FILE
ZEND_API int zval_copy_static_var(zval *p TSRMLS_DC, int num_args, va_list args, zend_hash_key *key);
-ZEND_API int zend_print_variable(zval *var TSRMLS_DC);
+ZEND_API size_t zend_print_variable(zval *var TSRMLS_DC);
ZEND_API void _zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC);
ZEND_API void _zval_internal_dtor_for_ptr(zval *zvalue ZEND_FILE_LINE_DC);
ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC);
diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c
index 01a91cad80..a596b7ca06 100644
--- a/Zend/zend_virtual_cwd.c
+++ b/Zend/zend_virtual_cwd.c
@@ -380,7 +380,7 @@ CWD_API int php_sys_stat_ex(const char *path, zend_stat_t *buf, int lstat) /* {{
}
if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
- int len = strlen(path);
+ size_t len = strlen(path);
if (path[len-4] == '.') {
if (_memicmp(path+len-3, "exe", 3) == 0 ||
@@ -467,7 +467,7 @@ CWD_API void virtual_cwd_startup(void) /* {{{ */
cwd[0] = '\0';
}
- main_cwd_state.cwd_length = strlen(cwd);
+ main_cwd_state.cwd_length = (int)strlen(cwd);
#ifdef TSRM_WIN32
if (main_cwd_state.cwd_length >= 2 && cwd[1] == ':') {
cwd[0] = toupper(cwd[0]);
@@ -1146,7 +1146,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
return -1;
}
if (save) {
- i = strlen(data.cFileName);
+ i = (int)strlen(data.cFileName);
memcpy(path+j, data.cFileName, i+1);
j += i;
} else {
@@ -1180,7 +1180,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
/* returns 0 for ok, 1 for error */
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath TSRMLS_DC) /* {{{ */
{
- int path_length = strlen(path);
+ int path_length = (int)strlen(path);
char resolved_path[MAXPATHLEN];
int start = 1;
int ll = 0;
@@ -1394,7 +1394,7 @@ CWD_API int virtual_chdir(const char *path TSRMLS_DC) /* {{{ */
CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path TSRMLS_DC) TSRMLS_DC) /* {{{ */
{
- int length = strlen(path);
+ size_t length = strlen(path);
char *temp;
int retval;
ALLOCA_FLAG(use_heap)
@@ -1972,7 +1972,7 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{
} else if (!IS_ABSOLUTE_PATH(path, strlen(path)) &&
VCWD_GETCWD(cwd, MAXPATHLEN)) {
new_state.cwd = estrdup(cwd);
- new_state.cwd_length = strlen(cwd);
+ new_state.cwd_length = (int)strlen(cwd);
} else {
new_state.cwd = (char*)emalloc(1);
if (new_state.cwd == NULL) {
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index fad4d5b99c..72fbf7fbb4 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -333,7 +333,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
zval *object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -356,21 +356,17 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -427,15 +423,19 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV, int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC))
{
USE_OPLINE
- zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (OP1_TYPE == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (OP1_TYPE != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (OP1_TYPE == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (OP1_TYPE == IS_VAR && !OP1_FREE) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -443,9 +443,10 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR
} else {
zval *dim = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, OP2_TYPE TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, OP2_TYPE TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -456,33 +457,19 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- ZEND_VM_C_GOTO(assign_op_dim_exit);
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-ZEND_VM_C_LABEL(assign_op_dim_exit):
FREE_OP2();
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
FREE_OP1_VAR_PTR();
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -508,30 +495,17 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- ZEND_VM_C_GOTO(assign_op_exit);
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-ZEND_VM_C_LABEL(assign_op_exit):
FREE_OP2();
FREE_OP1_VAR_PTR();
CHECK_EXCEPTION();
@@ -688,7 +662,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
@@ -716,21 +690,17 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -783,7 +753,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
@@ -809,19 +779,15 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -1161,9 +1127,6 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -1233,11 +1196,8 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -1259,6 +1219,7 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -1300,6 +1261,7 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNU
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -1331,6 +1293,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -1389,7 +1352,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -1413,7 +1376,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -1475,7 +1438,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -1501,7 +1464,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -1579,29 +1542,33 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_free_op free_op2;
zval *property_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, OP1_TYPE, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
FREE_OP2();
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, OP2_TYPE TSRMLS_CC);
- FREE_OP2();
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ FREE_OP2();
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, OP2_TYPE TSRMLS_CC);
+ FREE_OP2();
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -1615,7 +1582,6 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -1669,10 +1635,13 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
SAVE_OPLINE();
value_ptr = GET_OP2_ZVAL_PTR_PTR(BP_VAR_W);
+ if (OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (OP2_TYPE == IS_VAR &&
- opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
- !Z_ISREF_P(value_ptr)) {
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
if (!OP2_FREE) {
PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
}
@@ -1689,15 +1658,14 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
}
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (OP1_TYPE == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- if ((OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
- (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
- zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- }
if ((OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
(OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
variable_ptr = &EG(uninitialized_zval);
@@ -2101,7 +2069,7 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV)
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -2662,7 +2630,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
zval *p = ZEND_CALL_ARG(call, 1);
for (i = 0; i < call->num_args; ++i) {
- zend_verify_arg_type(fbc, i + 1, p, 0 TSRMLS_CC);
+ zend_verify_arg_type(fbc, i + 1, p TSRMLS_CC);
p++;
}
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -2862,10 +2830,10 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (OP1_TYPE == IS_VAR && !Z_ISREF_P(retval_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
- } else {
+ if (OP1_TYPE == IS_VAR) {
+ if (retval_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
@@ -3521,7 +3489,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
} else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
- zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
CHECK_EXCEPTION();
}
@@ -3549,7 +3517,7 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
}
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
- zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
}
CHECK_EXCEPTION();
@@ -3574,7 +3542,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY)
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
do {
- zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
param++;
@@ -3667,23 +3635,38 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY)
+ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY)
{
USE_OPLINE
zval object_zval;
zend_function *constructor;
+ zend_class_entry *ce;
SAVE_OPLINE();
- if (UNEXPECTED((Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) {
- if (Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & ZEND_ACC_INTERFACE) {
- zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
- } else if ((Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
- zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
+ if (OP1_TYPE == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
}
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op1.var));
}
- object_init_ex(&object_zval, Z_CE_P(EX_VAR(opline->op1.var)));
+ if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) {
+ if (ce->ce_flags & ZEND_ACC_INTERFACE) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", ce->name->val);
+ } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", ce->name->val);
+ } else {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", ce->name->val);
+ }
+ }
+ object_init_ex(&object_zval, ce);
constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval) TSRMLS_CC);
if (constructor == NULL) {
@@ -3702,7 +3685,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY)
ZEND_CALL_CTOR : (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED)),
constructor,
opline->extended_value,
- Z_CE_P(EX_VAR(opline->op1.var)),
+ ce,
Z_OBJ(object_zval),
EX(call) TSRMLS_CC);
@@ -3829,7 +3812,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
} else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -5321,7 +5304,7 @@ ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY)
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMP|VAR|CV, ANY)
+ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMP|VAR|CV, CONST|VAR)
{
USE_OPLINE
zend_free_op free_op1;
@@ -5332,7 +5315,25 @@ ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMP|VAR|CV, ANY)
expr = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
if (Z_TYPE_P(expr) == IS_OBJECT) {
- result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
+ zend_class_entry *ce;
+
+ if (OP2_TYPE == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ FREE_OP1();
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
} else {
result = 0;
}
@@ -5362,7 +5363,7 @@ ZEND_VM_HANDLER(144, ZEND_ADD_INTERFACE, ANY, CONST)
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
iface = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else {
- iface = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ iface = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_INTERFACE TSRMLS_CC);
if (UNEXPECTED(iface == NULL)) {
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -5391,7 +5392,7 @@ ZEND_VM_HANDLER(154, ZEND_ADD_TRAIT, ANY, ANY)
} else {
trait = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv),
opline->op2.zv + 1,
- opline->extended_value TSRMLS_CC);
+ ZEND_FETCH_CLASS_TRAIT TSRMLS_CC);
if (UNEXPECTED(trait == NULL)) {
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -5686,9 +5687,10 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (OP1_TYPE == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (OP1_TYPE == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 4b58d95618..94466c581b 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -538,7 +538,7 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *p = ZEND_CALL_ARG(call, 1);
for (i = 0; i < call->num_args; ++i) {
- zend_verify_arg_type(fbc, i + 1, p, 0 TSRMLS_CC);
+ zend_verify_arg_type(fbc, i + 1, p TSRMLS_CC);
p++;
}
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -978,7 +978,7 @@ static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
} else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
- zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
CHECK_EXCEPTION();
}
@@ -1003,7 +1003,7 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
do {
- zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
param++;
@@ -1023,57 +1023,6 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
ZEND_VM_NEXT_OPCODE();
}
-static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zval object_zval;
- zend_function *constructor;
-
- SAVE_OPLINE();
- if (UNEXPECTED((Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) {
- if (Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & ZEND_ACC_INTERFACE) {
- zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
- } else if ((Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
- zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
- } else {
- zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
- }
- }
- object_init_ex(&object_zval, Z_CE_P(EX_VAR(opline->op1.var)));
- constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval) TSRMLS_CC);
-
- if (constructor == NULL) {
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval);
- } else {
- zval_ptr_dtor(&object_zval);
- }
- ZEND_VM_JMP(opline->op2.jmp_addr);
- } else {
- /* We are not handling overloaded classes right now */
- EX(call) = zend_vm_stack_push_call_frame(
- VM_FRAME_INFO(
- VM_FRAME_NESTED_FUNCTION,
- RETURN_VALUE_USED(opline) ?
- ZEND_CALL_CTOR : (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED)),
- constructor,
- opline->extended_value,
- Z_CE_P(EX_VAR(opline->op1.var)),
- Z_OBJ(object_zval),
- EX(call) TSRMLS_CC);
-
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
- EX(call)->return_value = EX_VAR(opline->result.var);
- } else {
- EX(call)->return_value = NULL;
- }
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
-}
-
static int ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -1225,7 +1174,7 @@ static int ZEND_FASTCALL ZEND_ADD_TRAIT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
} else {
trait = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv),
opline->op2.zv + 1,
- opline->extended_value TSRMLS_CC);
+ ZEND_FETCH_CLASS_TRAIT TSRMLS_CC);
if (UNEXPECTED(trait == NULL)) {
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -1474,7 +1423,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLE
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -1713,7 +1662,7 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_
}
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
- zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
}
CHECK_EXCEPTION();
@@ -1772,7 +1721,7 @@ static int ZEND_FASTCALL ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
iface = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else {
- iface = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ iface = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_INTERFACE TSRMLS_CC);
if (UNEXPECTED(iface == NULL)) {
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -1809,7 +1758,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -1995,7 +1944,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -2181,7 +2130,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDL
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -2220,7 +2169,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -2662,10 +2611,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (IS_CONST == IS_VAR && !Z_ISREF_P(retval_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
- } else {
+ if (IS_CONST == IS_VAR) {
+ if (retval_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
@@ -2769,6 +2718,72 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval object_zval;
+ zend_function *constructor;
+ zend_class_entry *ce;
+
+ SAVE_OPLINE();
+ if (IS_CONST == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op1.var));
+ }
+ if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) {
+ if (ce->ce_flags & ZEND_ACC_INTERFACE) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", ce->name->val);
+ } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", ce->name->val);
+ } else {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", ce->name->val);
+ }
+ }
+ object_init_ex(&object_zval, ce);
+ constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval) TSRMLS_CC);
+
+ if (constructor == NULL) {
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval);
+ } else {
+ zval_ptr_dtor(&object_zval);
+ }
+ ZEND_VM_JMP(opline->op2.jmp_addr);
+ } else {
+ /* We are not handling overloaded classes right now */
+ EX(call) = zend_vm_stack_push_call_frame(
+ VM_FRAME_INFO(
+ VM_FRAME_NESTED_FUNCTION,
+ RETURN_VALUE_USED(opline) ?
+ ZEND_CALL_CTOR : (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED)),
+ constructor,
+ opline->extended_value,
+ ce,
+ Z_OBJ(object_zval),
+ EX(call) TSRMLS_CC);
+
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
+ EX(call)->return_value = EX_VAR(opline->result.var);
+ } else {
+ EX(call)->return_value = NULL;
+ }
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+}
+
static int ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -3840,9 +3855,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -3931,6 +3943,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -4033,7 +4046,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -4324,7 +4337,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
} else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -4855,9 +4868,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -5275,6 +5289,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -5379,7 +5394,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -5898,9 +5913,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -6378,9 +6394,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -6469,6 +6482,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -6573,7 +6587,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -7237,9 +7251,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -7442,9 +7457,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -7503,6 +7515,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -7981,9 +7994,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -8386,6 +8400,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -8488,7 +8503,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -9056,9 +9071,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -9444,10 +9460,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(retval_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
- } else {
+ if (IS_TMP_VAR == IS_VAR) {
+ if (retval_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
@@ -10154,27 +10170,6 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
ZEND_VM_NEXT_OPCODE();
}
-static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zend_free_op free_op1;
- zval *expr;
- zend_bool result;
-
- SAVE_OPLINE();
- expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-
- if (Z_TYPE_P(expr) == IS_OBJECT) {
- result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
- } else {
- result = 0;
- }
- ZVAL_BOOL(EX_VAR(opline->result.var), result);
- zval_ptr_dtor_nogc(free_op1.var);
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
-}
-
static int ZEND_FASTCALL ZEND_STRLEN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -10643,9 +10638,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -10734,6 +10726,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -10836,7 +10829,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -11451,6 +11444,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_HANDLER(ZEN
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_CONST == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -11497,9 +11529,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -11917,6 +11950,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -12021,7 +12055,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -12513,9 +12547,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -12993,9 +13028,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -13084,6 +13116,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -13188,7 +13221,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -13780,6 +13813,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_VAR_HANDLER(ZEND_
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_VAR == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -13826,9 +13898,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -14031,9 +14104,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -14092,6 +14162,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_O
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -14422,9 +14493,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -14827,6 +14899,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -14929,7 +15002,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -15416,9 +15489,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -15970,10 +16044,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (IS_VAR == IS_VAR && !Z_ISREF_P(retval_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
- } else {
+ if (IS_VAR == IS_VAR) {
+ if (retval_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
@@ -16243,6 +16317,72 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval object_zval;
+ zend_function *constructor;
+ zend_class_entry *ce;
+
+ SAVE_OPLINE();
+ if (IS_VAR == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op1.var));
+ }
+ if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) {
+ if (ce->ce_flags & ZEND_ACC_INTERFACE) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", ce->name->val);
+ } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", ce->name->val);
+ } else {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", ce->name->val);
+ }
+ }
+ object_init_ex(&object_zval, ce);
+ constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval) TSRMLS_CC);
+
+ if (constructor == NULL) {
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval);
+ } else {
+ zval_ptr_dtor(&object_zval);
+ }
+ ZEND_VM_JMP(opline->op2.jmp_addr);
+ } else {
+ /* We are not handling overloaded classes right now */
+ EX(call) = zend_vm_stack_push_call_frame(
+ VM_FRAME_INFO(
+ VM_FRAME_NESTED_FUNCTION,
+ RETURN_VALUE_USED(opline) ?
+ ZEND_CALL_CTOR : (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED)),
+ constructor,
+ opline->extended_value,
+ ce,
+ Z_OBJ(object_zval),
+ EX(call) TSRMLS_CC);
+
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
+ EX(call)->return_value = EX_VAR(opline->result.var);
+ } else {
+ EX(call)->return_value = NULL;
+ }
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+}
+
static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -17082,27 +17222,6 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
ZEND_VM_NEXT_OPCODE();
}
-static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zend_free_op free_op1;
- zval *expr;
- zend_bool result;
-
- SAVE_OPLINE();
- expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-
- if (Z_TYPE_P(expr) == IS_OBJECT) {
- result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
- } else {
- result = 0;
- }
- ZVAL_BOOL(EX_VAR(opline->result.var), result);
- zval_ptr_dtor_nogc(free_op1.var);
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
-}
-
static int ZEND_FASTCALL ZEND_STRLEN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -17472,7 +17591,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = opline->op2.zv;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -17495,21 +17614,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -17565,15 +17680,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -17581,9 +17700,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b
} else {
zval *dim = opline->op2.zv;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -17594,33 +17714,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -17646,31 +17751,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -17826,7 +17917,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -17854,21 +17945,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -17920,7 +18007,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -17946,19 +18033,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -18107,9 +18190,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -18179,11 +18259,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18205,6 +18282,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -18246,6 +18324,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18277,6 +18356,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -18334,7 +18414,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18358,7 +18438,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18419,7 +18499,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18445,7 +18525,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18523,29 +18603,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = opline->op2.zv;
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = opline->op2.zv;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CONST TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -18559,7 +18643,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -18902,7 +18985,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
} else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -19468,6 +19551,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CONST_HANDLER(ZEN
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_CONST == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -19514,9 +19636,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -19901,7 +20024,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -19924,21 +20047,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -19995,15 +20114,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -20011,9 +20134,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin
} else {
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -20024,33 +20148,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -20076,30 +20186,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
@@ -20256,7 +20353,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -20284,21 +20381,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -20351,7 +20444,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -20377,19 +20470,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -20460,11 +20549,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20486,6 +20572,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -20527,6 +20614,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20558,6 +20646,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -20616,7 +20705,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20640,7 +20729,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20702,7 +20791,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20728,7 +20817,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20773,29 +20862,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -20809,7 +20902,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -21526,9 +21618,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -21913,7 +22006,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -21936,21 +22029,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -22007,15 +22096,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -22023,9 +22116,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin
} else {
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -22036,33 +22130,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -22088,30 +22168,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
@@ -22268,7 +22335,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -22296,21 +22363,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -22363,7 +22426,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -22389,19 +22452,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -22551,9 +22610,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -22623,11 +22679,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22649,6 +22702,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -22690,6 +22744,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22721,6 +22776,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -22779,7 +22835,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22803,7 +22859,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22865,7 +22921,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22891,7 +22947,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22936,29 +22992,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -22972,7 +23032,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -23026,10 +23085,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_VAR == IS_VAR &&
- opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
- !Z_ISREF_P(value_ptr)) {
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
if (!(free_op2.var != NULL)) {
PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
}
@@ -23046,15 +23108,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
}
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_VAR == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
- (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
- zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- }
if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
(IS_VAR == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
variable_ptr = &EG(uninitialized_zval);
@@ -23853,6 +23914,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_VAR == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -23899,9 +23999,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -24011,7 +24112,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = NULL;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -24034,21 +24135,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -24104,15 +24201,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -24120,9 +24221,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (*
} else {
zval *dim = NULL;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -24133,33 +24235,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (*
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -24185,31 +24272,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -24464,9 +24537,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -24521,11 +24591,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -24547,6 +24614,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -24573,6 +24641,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -24604,29 +24673,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = NULL;
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = NULL;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_UNUSED TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -24640,7 +24713,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -25104,9 +25176,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -25476,7 +25549,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -25499,21 +25572,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -25569,15 +25638,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -25585,9 +25658,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina
} else {
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -25598,33 +25672,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -25650,31 +25709,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -25830,7 +25875,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -25858,21 +25903,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -25924,7 +25965,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -25950,19 +25991,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -26032,11 +26069,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26058,6 +26092,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -26099,6 +26134,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26130,6 +26166,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -26187,7 +26224,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26211,7 +26248,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26272,7 +26309,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26298,7 +26335,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26343,29 +26380,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CV TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -26379,7 +26420,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -26432,10 +26472,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op2.var TSRMLS_CC);
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_CV == IS_VAR &&
- opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
- !Z_ISREF_P(value_ptr)) {
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
if (!0) {
PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
}
@@ -26452,15 +26495,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
}
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_VAR == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
- (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
- zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- }
if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
(IS_CV == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
variable_ptr = &EG(uninitialized_zval);
@@ -27154,9 +27196,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -27346,7 +27389,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = opline->op2.zv;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -27369,21 +27412,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -27438,15 +27477,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -27454,9 +27497,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int
} else {
zval *dim = opline->op2.zv;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -27467,33 +27511,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -27519,31 +27548,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -27699,7 +27714,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -27727,21 +27742,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -27793,7 +27804,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -27819,19 +27830,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -27921,7 +27928,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -27945,7 +27952,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -28006,7 +28013,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -28032,7 +28039,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OP
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -28262,7 +28269,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
} else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -28640,9 +28647,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -28736,7 +28744,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -28759,21 +28767,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -28829,15 +28833,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -28845,9 +28853,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (*
} else {
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -28858,33 +28867,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (*
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -28910,30 +28905,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
CHECK_EXCEPTION();
@@ -29090,7 +29072,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -29118,21 +29100,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -29185,7 +29163,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -29211,19 +29189,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -29315,7 +29289,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -29339,7 +29313,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -29401,7 +29375,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_O
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -29427,7 +29401,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCO
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -29948,9 +29922,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -30044,7 +30019,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -30067,21 +30042,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -30137,15 +30108,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -30153,9 +30128,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (*
} else {
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -30166,33 +30142,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (*
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -30218,30 +30180,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
CHECK_EXCEPTION();
@@ -30398,7 +30347,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -30426,21 +30375,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -30493,7 +30438,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -30519,19 +30464,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -30623,7 +30564,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -30647,7 +30588,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -30709,7 +30650,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -30735,7 +30676,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCO
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -31256,9 +31197,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -31352,7 +31294,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = NULL;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -31375,21 +31317,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -31444,15 +31382,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -31460,9 +31402,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int
} else {
zval *dim = NULL;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -31473,33 +31416,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -31525,31 +31453,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -31775,9 +31689,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -31871,7 +31786,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -31894,21 +31809,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -31963,15 +31874,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -31979,9 +31894,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b
} else {
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -31992,33 +31908,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -32044,31 +31945,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -32224,7 +32111,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -32252,21 +32139,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -32318,7 +32201,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -32344,19 +32227,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -32446,7 +32325,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -32470,7 +32349,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -32531,7 +32410,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OP
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -32557,7 +32436,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCOD
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -33074,9 +32953,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -33603,10 +33483,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (IS_CV == IS_VAR && !Z_ISREF_P(retval_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
- } else {
+ if (IS_CV == IS_VAR) {
+ if (retval_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
@@ -34456,27 +34336,6 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZEND_VM_NEXT_OPCODE();
}
-static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
-
- zval *expr;
- zend_bool result;
-
- SAVE_OPLINE();
- expr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
-
- if (Z_TYPE_P(expr) == IS_OBJECT) {
- result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
- } else {
- result = 0;
- }
- ZVAL_BOOL(EX_VAR(opline->result.var), result);
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
-}
-
static int ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -34846,7 +34705,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = opline->op2.zv;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -34869,21 +34728,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -34938,15 +34793,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -34954,9 +34813,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi
} else {
zval *dim = opline->op2.zv;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -34967,33 +34827,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -35019,31 +34864,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -35199,7 +35030,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -35227,21 +35058,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -35293,7 +35120,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -35319,19 +35146,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -35480,9 +35303,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -35552,11 +35372,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35578,6 +35395,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -35619,6 +35437,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35650,6 +35469,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -35707,7 +35527,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35731,7 +35551,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35792,7 +35612,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35818,7 +35638,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35896,29 +35716,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = opline->op2.zv;
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = opline->op2.zv;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CONST TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -35932,7 +35756,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -36618,6 +36441,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_CONST == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -36664,9 +36526,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -37107,7 +36970,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -37130,21 +36993,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -37200,15 +37059,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -37216,9 +37079,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina
} else {
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -37229,33 +37093,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -37281,30 +37131,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
CHECK_EXCEPTION();
@@ -37461,7 +37298,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -37489,21 +37326,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -37556,7 +37389,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -37582,19 +37415,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -37665,11 +37494,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37691,6 +37517,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -37732,6 +37559,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37763,6 +37591,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -37821,7 +37650,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37845,7 +37674,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37907,7 +37736,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37933,7 +37762,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37978,29 +37807,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -38014,7 +37847,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -38605,9 +38437,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -38991,7 +38824,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -39014,21 +38847,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -39084,15 +38913,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -39100,9 +38933,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina
} else {
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -39113,33 +38947,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -39165,30 +38985,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
CHECK_EXCEPTION();
@@ -39345,7 +39152,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -39373,21 +39180,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -39440,7 +39243,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -39466,19 +39269,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -39628,9 +39427,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -39700,11 +39496,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39726,6 +39519,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -39767,6 +39561,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39798,6 +39593,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -39856,7 +39652,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39880,7 +39676,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39942,7 +39738,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39968,7 +39764,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -40013,29 +39809,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -40049,7 +39849,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -40103,10 +39902,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_VAR == IS_VAR &&
- opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
- !Z_ISREF_P(value_ptr)) {
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
if (!(free_op2.var != NULL)) {
PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
}
@@ -40123,15 +39925,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
}
variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+ if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_CV == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
- (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
- zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- }
if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
(IS_VAR == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
variable_ptr = &EG(uninitialized_zval);
@@ -40802,6 +40603,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_VAR_HANDLER(ZEND_O
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_VAR == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -40848,9 +40688,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -40959,7 +40800,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = NULL;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -40982,21 +40823,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -41051,15 +40888,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -41067,9 +40908,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b
} else {
zval *dim = NULL;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -41080,33 +40922,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -41132,31 +40959,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -41411,9 +41224,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -41468,11 +41278,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -41494,6 +41301,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -41520,6 +41328,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -41551,29 +41360,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = NULL;
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = NULL;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_UNUSED TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -41587,7 +41400,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -41908,9 +41720,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -42279,7 +42092,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -42302,21 +42115,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -42371,15 +42180,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -42387,9 +42200,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binar
} else {
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -42400,33 +42214,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binar
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -42452,31 +42251,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -42632,7 +42417,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -42660,21 +42445,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -42726,7 +42507,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -42752,19 +42533,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -42834,11 +42611,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -42860,6 +42634,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -42901,6 +42676,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -42932,6 +42708,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -42989,7 +42766,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -43013,7 +42790,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -43074,7 +42851,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -43100,7 +42877,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -43145,29 +42922,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CV TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -43181,7 +42962,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -43234,10 +43014,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op2.var TSRMLS_CC);
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_CV == IS_VAR &&
- opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
- !Z_ISREF_P(value_ptr)) {
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
if (!0) {
PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
}
@@ -43254,15 +43037,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
}
variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+ if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_CV == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
- (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
- zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- }
if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
(IS_CV == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
variable_ptr = &EG(uninitialized_zval);
@@ -43829,9 +43611,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -45643,31 +45426,31 @@ void zend_init_opcodes_handlers(void)
ZEND_SEND_REF_SPEC_CV_HANDLER,
ZEND_SEND_REF_SPEC_CV_HANDLER,
ZEND_SEND_REF_SPEC_CV_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
@@ -47398,26 +47181,26 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
+ ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_VAR_CONST_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_VAR_VAR_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
ZEND_DECLARE_CLASS_SPEC_HANDLER,
ZEND_DECLARE_CLASS_SPEC_HANDLER,
ZEND_DECLARE_CLASS_SPEC_HANDLER,
diff --git a/ext/fileinfo/libmagic/readcdf.c b/ext/fileinfo/libmagic/readcdf.c
index ec97ced44b..175719a2d7 100644
--- a/ext/fileinfo/libmagic/readcdf.c
+++ b/ext/fileinfo/libmagic/readcdf.c
@@ -88,6 +88,9 @@ static const struct cv {
{ 0x00000000000c1084LLU, 0x46000000000000c0LLU },
#endif
"x-msi",
+ },
+ { { 0, 0 },
+ NULL,
}
}, clsid2desc[] = {
{
@@ -98,6 +101,9 @@ static const struct cv {
#endif
"MSI Installer",
},
+ { { 0, 0 },
+ NULL,
+ }
};
private const char *
diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c
index 926fc30e8b..2a77132ba3 100644
--- a/ext/gmp/gmp.c
+++ b/ext/gmp/gmp.c
@@ -1798,7 +1798,7 @@ ZEND_FUNCTION(gmp_random)
Gets a random number in the range 0 to (2 ** n) - 1 */
ZEND_FUNCTION(gmp_random_bits)
{
- long bits;
+ zend_long bits;
mpz_ptr gmpnum_result;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &bits) == FAILURE) {
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
index f43802647b..5c6880beea 100644
--- a/ext/opcache/Optimizer/block_pass.c
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -616,7 +616,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array,
VAR_SOURCE(opline->op1)->opcode == ZEND_QM_ASSIGN &&
ZEND_OP1_TYPE(VAR_SOURCE(opline->op1)) == IS_CONST &&
opline->opcode != ZEND_CASE && /* CASE _always_ expects variable */
- opline->opcode != ZEND_FETCH_LIST && /* in 5.1, FETCH_DIM_TMP_VAR expects T */
+ opline->opcode != ZEND_FETCH_LIST &&
opline->opcode != ZEND_FE_RESET &&
opline->opcode != ZEND_FREE
) {
diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c
index 091437e119..8fb5a9b0c9 100644
--- a/ext/opcache/Optimizer/compact_literals.c
+++ b/ext/opcache/Optimizer/compact_literals.c
@@ -227,10 +227,16 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
case ZEND_FETCH_CLASS:
case ZEND_ADD_INTERFACE:
case ZEND_ADD_TRAIT:
+ case ZEND_INSTANCEOF:
if (ZEND_OP2_TYPE(opline) == IS_CONST) {
LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 1, 1, 2);
}
break;
+ case ZEND_NEW:
+ if (ZEND_OP1_TYPE(opline) == IS_CONST) {
+ LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2);
+ }
+ break;
case ZEND_ASSIGN_OBJ:
case ZEND_FETCH_OBJ_R:
case ZEND_FETCH_OBJ_W:
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index 70e58f5695..1a6d0b675a 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -126,6 +126,7 @@ void zend_optimizer_update_op1_const(zend_op_array *op_array,
case ZEND_CATCH:
case ZEND_FETCH_CONSTANT:
case ZEND_DEFINED:
+ case ZEND_NEW:
opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
zend_string_hash_val(Z_STR(ZEND_OP1_LITERAL(opline)));
Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->last_cache_slot++;
@@ -173,6 +174,7 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array,
case ZEND_ISSET_ISEMPTY_VAR:
case ZEND_ADD_INTERFACE:
case ZEND_ADD_TRAIT:
+ case ZEND_INSTANCEOF:
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot++;
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
zend_optimizer_add_literal(op_array, val TSRMLS_CC);
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 4650dc286b..6f37146a91 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -1130,10 +1130,6 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr
return new_persistent_script;
}
- if (!compact_persistent_script(new_persistent_script)) {
- return new_persistent_script;
- }
-
/* exclusive lock */
zend_shared_alloc_lock(TSRMLS_C);
diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c
index ee7be50619..22683245f6 100644
--- a/ext/opcache/zend_accelerator_util_funcs.c
+++ b/ext/opcache/zend_accelerator_util_funcs.c
@@ -88,64 +88,6 @@ zend_persistent_script* create_persistent_script(void)
return persistent_script;
}
-static int compact_hash_table(HashTable *ht)
-{
- uint i = 3;
- uint j;
- uint nSize;
- Bucket *d;
- Bucket *p;
-
- if (!ht->nNumOfElements || (ht->u.flags & HASH_FLAG_PACKED)) {
- /* Empty tables don't allocate space for Buckets */
- return 1;
- }
-
- if (ht->nNumOfElements >= 0x80000000) {
- /* prevent overflow */
- nSize = 0x80000000;
- } else {
- while ((1U << i) < ht->nNumOfElements) {
- i++;
- }
- nSize = 1 << i;
- }
-
- if (nSize >= ht->nTableSize) {
- /* Keep the size */
- return 1;
- }
-
- d = (Bucket *)pemalloc(nSize * (sizeof(Bucket) + sizeof(uint32_t)), ht->u.flags & HASH_FLAG_PERSISTENT);
- if (!d) {
- return 0;
- }
-
- for (i = 0, j = 0; i < ht->nNumUsed; i++) {
- p = ht->arData + i;
- if (Z_TYPE(p->val) != IS_UNDEF) {
- d[j++] = *p;
- }
- }
- ht->nNumUsed = j;
-
- pefree(ht->arData, ht->u.flags & HASH_FLAG_PERSISTENT);
-
- ht->arData = d;
- ht->arHash = (uint32_t *)(d + nSize);
- ht->nTableSize = nSize;
- ht->nTableMask = ht->nTableSize - 1;
- zend_hash_rehash(ht);
-
- return 1;
-}
-
-int compact_persistent_script(zend_persistent_script *persistent_script)
-{
- return compact_hash_table(&persistent_script->function_table) &&
- compact_hash_table(&persistent_script->class_table);
-}
-
void free_persistent_script(zend_persistent_script *persistent_script, int destroy_elements)
{
if (destroy_elements) {
diff --git a/ext/opcache/zend_accelerator_util_funcs.h b/ext/opcache/zend_accelerator_util_funcs.h
index 2f515d85cc..cbcb2ffa8e 100644
--- a/ext/opcache/zend_accelerator_util_funcs.h
+++ b/ext/opcache/zend_accelerator_util_funcs.h
@@ -28,7 +28,6 @@
void zend_accel_copy_internal_functions(TSRMLS_D);
zend_persistent_script* create_persistent_script(void);
-int compact_persistent_script(zend_persistent_script *script);
void free_persistent_script(zend_persistent_script *persistent_script, int destroy_elements);
void zend_accel_free_user_functions(HashTable *ht TSRMLS_DC);
diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c
index 40d4114879..323c805fca 100644
--- a/ext/pdo_dblib/dblib_driver.c
+++ b/ext/pdo_dblib/dblib_driver.c
@@ -61,7 +61,6 @@ static int dblib_fetch_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS
msg, einfo->dberr, einfo->severity, stmt ? stmt->active_query_string : "");
add_next_index_long(info, einfo->dberr);
- // TODO: avoid reallocation ???
add_next_index_string(info, message);
efree(message);
add_next_index_long(info, einfo->oserr);
@@ -145,10 +144,12 @@ static zend_long dblib_handle_doer(pdo_dbh_t *dbh, const char *sql, zend_long sq
static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC)
{
- pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
+
+ /* pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; */
+
char *q;
int l = 1;
-
+
*quoted = q = safe_emalloc(2, unquotedlen, 3);
*q++ = '\'';
@@ -174,7 +175,6 @@ static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquote
static int pdo_dblib_transaction_cmd(const char *cmd, pdo_dbh_t *dbh TSRMLS_DC)
{
pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
- RETCODE ret;
if (FAIL == dbcmd(H->link, cmd)) {
return 0;
@@ -246,6 +246,23 @@ char *dblib_handle_last_id(pdo_dbh_t *dbh, const char *name, unsigned int *len T
return id;
}
+static int dblib_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val TSRMLS_DC)
+{
+ switch(attr) {
+ case PDO_ATTR_TIMEOUT:
+ return 0;
+ default:
+ return 1;
+ }
+
+}
+
+static int dblib_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_value TSRMLS_DC)
+{
+ /* dblib_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; */
+ return 0;
+}
+
static struct pdo_dbh_methods dblib_methods = {
dblib_handle_closer,
dblib_handle_preparer,
@@ -254,10 +271,10 @@ static struct pdo_dbh_methods dblib_methods = {
dblib_handle_begin, /* begin */
dblib_handle_commit, /* commit */
dblib_handle_rollback, /* rollback */
- NULL, /*set attr */
+ dblib_set_attr, /*set attr */
dblib_handle_last_id, /* last insert id */
dblib_fetch_error, /* fetch error */
- NULL, /* get attr */
+ dblib_get_attribute, /* get attr */
NULL, /* check liveness */
NULL, /* get driver methods */
NULL, /* request shutdown */
@@ -303,6 +320,12 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, nvars);
+ if (driver_options) {
+ int timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30 TSRMLS_CC);
+ dbsetlogintime(timeout); /* Connection/Login Timeout */
+ dbsettime(timeout); /* Statement Timeout */
+ }
+
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
H->login = dblogin();
H->err.sqlstate = dbh->error_code;
@@ -311,8 +334,8 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
goto cleanup;
}
- DBERRHANDLE(H->login, (EHANDLEFUNC) error_handler);
- DBMSGHANDLE(H->login, (MHANDLEFUNC) msg_handler);
+ DBERRHANDLE(H->login, (EHANDLEFUNC) pdo_dblib_error_handler);
+ DBMSGHANDLE(H->login, (MHANDLEFUNC) pdo_dblib_msg_handler);
if(vars[5].optval) {
for(i=0;i<nvers;i++) {
diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c
index a29405b24e..bd79be3e9c 100644
--- a/ext/pdo_dblib/dblib_stmt.c
+++ b/ext/pdo_dblib/dblib_stmt.c
@@ -103,21 +103,15 @@ static int pdo_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
/* Cancel any pending results */
dbcancel(H->link);
- efree(stmt->columns);
- stmt->columns = NULL;
-
return 1;
}
static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
{
pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
-
- efree(stmt->columns);
- stmt->columns = NULL;
-
+
efree(S);
-
+
return 1;
}
@@ -128,16 +122,16 @@ static int pdo_dblib_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
RETCODE ret;
ret = dbresults(H->link);
-
+
if (FAIL == ret) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO_DBLIB: dbresults() returned FAIL" TSRMLS_CC);
return 0;
}
-
+
if(NO_MORE_RESULTS == ret) {
return 0;
}
-
+
stmt->row_count = DBCOUNT(H->link);
stmt->column_count = dbnumcols(H->link);
@@ -204,7 +198,7 @@ static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
struct pdo_column_data *col = &stmt->columns[colno];
- col->name = (char*)dbcolname(H->link, colno+1);
+ col->name = estrdup(dbcolname(H->link, colno+1));
col->maxlen = dbcollen(H->link, colno+1);
col->namelen = strlen(col->name);
col->param_type = PDO_PARAM_STR;
@@ -255,12 +249,11 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
break;
}
case SQLUNIQUE: {
- *len = 36+1;
+ *len = 37;
tmp_ptr = emalloc(*len + 1);
-
- /* uniqueidentifier is a 16-byte binary number, convert to 32 char hex string */
*len = dbconvert(NULL, SQLUNIQUE, *ptr, *len, SQLCHAR, tmp_ptr, *len);
php_strtoupper(tmp_ptr, *len);
+ tmp_ptr[36] = '\0';
*ptr = tmp_ptr;
break;
}
diff --git a/ext/pdo_dblib/pdo_dblib.c b/ext/pdo_dblib/pdo_dblib.c
index 3afd885df5..4cd0749cf8 100644
--- a/ext/pdo_dblib/pdo_dblib.c
+++ b/ext/pdo_dblib/pdo_dblib.c
@@ -86,7 +86,7 @@ ZEND_GET_MODULE(pdo_dblib)
#endif
#endif
-int error_handler(DBPROCESS *dbproc, int severity, int dberr,
+int pdo_dblib_error_handler(DBPROCESS *dbproc, int severity, int dberr,
int oserr, char *dberrstr, char *oserrstr)
{
pdo_dblib_err *einfo;
@@ -103,6 +103,7 @@ int error_handler(DBPROCESS *dbproc, int severity, int dberr,
einfo->severity = severity;
einfo->oserr = oserr;
einfo->dberr = dberr;
+
if (einfo->oserrstr) {
efree(einfo->oserrstr);
}
@@ -128,16 +129,10 @@ int error_handler(DBPROCESS *dbproc, int severity, int dberr,
}
strcpy(einfo->sqlstate, state);
-#if 0
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "dblib error: %d %s (severity %d)",
- dberr, dberrstr, severity);
-#endif
-
return INT_CANCEL;
}
-int msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate,
+int pdo_dblib_msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate,
int severity, char *msgtext, char *srvname, char *procname, DBUSMALLINT line)
{
pdo_dblib_err *einfo;
@@ -156,10 +151,6 @@ int msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate,
einfo->lastmsg = estrdup(msgtext);
}
-#if 0
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "dblib message: %s (severity %d)", msgtext, severity);
-#endif
-
return 0;
}
@@ -196,18 +187,9 @@ PHP_MINIT_FUNCTION(pdo_dblib)
return FAILURE;
}
- /* TODO:
-
- dbsetifile()
- dbsetmaxprocs()
- dbsetlogintime()
- dbsettime()
-
- */
-
#if !PHP_DBLIB_IS_MSSQL
- dberrhandle(error_handler);
- dbmsghandle(msg_handler);
+ dberrhandle((EHANDLEFUNC) pdo_dblib_error_handler);
+ dbmsghandle((MHANDLEFUNC) pdo_dblib_msg_handler);
#endif
return SUCCESS;
diff --git a/ext/pdo_dblib/php_pdo_dblib_int.h b/ext/pdo_dblib/php_pdo_dblib_int.h
index e247b5c19e..3b341478d7 100644
--- a/ext/pdo_dblib/php_pdo_dblib_int.h
+++ b/ext/pdo_dblib/php_pdo_dblib_int.h
@@ -37,7 +37,7 @@
# define DBSETOPT(a, b, c) dbsetopt(a, b, c)
# define SYBESMSG SQLESMSG
# define SYBESEOF SQLESEOF
-# define SYBEFCON SQLECONN // SQLEFCON does not exist in MS SQL Server.
+# define SYBEFCON SQLECONN /* SQLEFCON does not exist in MS SQL Server. */
# define SYBEMEM SQLEMEM
# define SYBEPWD SQLEPWD
@@ -89,10 +89,10 @@ typedef unsigned char *LPBYTE;
typedef float DBFLT4;
#endif
-int error_handler(DBPROCESS *dbproc, int severity, int dberr,
+int pdo_dblib_error_handler(DBPROCESS *dbproc, int severity, int dberr,
int oserr, char *dberrstr, char *oserrstr);
-int msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate,
+int pdo_dblib_msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate,
int severity, char *msgtext, char *srvname, char *procname, DBUSMALLINT line);
extern pdo_driver_t pdo_dblib_driver;
diff --git a/ext/phar/phar.c b/ext/phar/phar.c
index 5e0ccb57b3..ec64f09c09 100644
--- a/ext/phar/phar.c
+++ b/ext/phar/phar.c
@@ -3310,6 +3310,7 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
zend_try {
failed = 0;
+ CG(zend_lineno) = 0;
res = phar_orig_compile_file(file_handle, type TSRMLS_CC);
} zend_catch {
failed = 1;
diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
index ba70ecca9d..361b0824eb 100644
--- a/ext/simplexml/simplexml.c
+++ b/ext/simplexml/simplexml.c
@@ -267,10 +267,8 @@ static zval *sxe_prop_dim_read(zval *object, zval *member, zend_bool elements, z
name = NULL;
} else {
if (Z_TYPE_P(member) != IS_STRING) {
- tmp_zv = *member;
- zval_copy_ctor(&tmp_zv);
+ ZVAL_STR(&tmp_zv, zval_get_string(member));
member = &tmp_zv;
- convert_to_string(member);
}
name = Z_STRVAL_P(member);
}
@@ -476,9 +474,7 @@ static int sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_bool
}
} else {
if (Z_TYPE_P(member) != IS_STRING) {
- trim_zv = *member;
- zval_copy_ctor(&trim_zv);
- convert_to_string(&trim_zv);
+ ZVAL_STR(&trim_zv, zval_get_string(member));
php_trim(Z_STRVAL(trim_zv), Z_STRLEN(trim_zv), NULL, 0, &tmp_zv, 3 TSRMLS_CC);
zval_dtor(&trim_zv);
member = &tmp_zv;
@@ -736,10 +732,8 @@ static int sxe_prop_dim_exists(zval *object, zval *member, int check_empty, zend
zval tmp_zv;
if (Z_TYPE_P(member) != IS_STRING && Z_TYPE_P(member) != IS_LONG) {
- tmp_zv = *member;
- zval_copy_ctor(&tmp_zv);
+ ZVAL_STR(&tmp_zv, zval_get_string(member));
member = &tmp_zv;
- convert_to_string(member);
}
sxe = Z_SXEOBJ_P(object);
@@ -866,10 +860,8 @@ static void sxe_prop_dim_delete(zval *object, zval *member, zend_bool elements,
int test = 0;
if (Z_TYPE_P(member) != IS_STRING && Z_TYPE_P(member) != IS_LONG) {
- tmp_zv = *member;
- zval_copy_ctor(&tmp_zv);
+ ZVAL_STR(&tmp_zv, zval_get_string(member));
member = &tmp_zv;
- convert_to_string(member);
}
sxe = Z_SXEOBJ_P(object);
diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c
index b12303ee0e..97191652d6 100644
--- a/ext/soap/php_encoding.c
+++ b/ext/soap/php_encoding.c
@@ -834,13 +834,10 @@ static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNo
str = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data));
new_len = Z_STRLEN_P(data);
} else {
- zval tmp = *data;
-
- zval_copy_ctor(&tmp);
- convert_to_string(&tmp);
- str = estrndup(Z_STRVAL(tmp), Z_STRLEN(tmp));
- new_len = Z_STRLEN(tmp);
- zval_dtor(&tmp);
+ zend_string *tmp = zval_get_string(data);
+ str = estrndup(tmp->val, tmp->len);
+ new_len = tmp->len;
+ zend_string_release(tmp);
}
if (SOAP_GLOBAL(encoding) != NULL) {
@@ -953,9 +950,7 @@ static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNo
FIND_ZVAL_NULL(data, ret, style);
if (Z_TYPE_P(data) != IS_STRING) {
- tmp = *data;
- zval_copy_ctor(&tmp);
- convert_to_string(&tmp);
+ ZVAL_STR(&tmp, zval_get_string(data));
data = &tmp;
}
str = (unsigned char *) safe_emalloc(Z_STRLEN_P(data) * 2, sizeof(char), 1);
@@ -1063,9 +1058,9 @@ static xmlNodePtr to_xml_long(encodeTypePtr type, zval *data, int style, xmlNode
snprintf(s, sizeof(s), "%0.0F",floor(Z_DVAL_P(data)));
xmlNodeSetContent(ret, BAD_CAST(s));
} else {
- zval tmp = *data;
+ zval tmp;
- zval_copy_ctor(&tmp);
+ ZVAL_DUP(&tmp, data);
if (Z_TYPE(tmp) != IS_LONG) {
convert_to_long(&tmp);
}
@@ -1090,11 +1085,7 @@ static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNo
xmlAddChild(parent, ret);
FIND_ZVAL_NULL(data, ret, style);
- tmp = *data;
- if (Z_TYPE(tmp) != IS_DOUBLE) {
- zval_copy_ctor(&tmp);
- convert_to_double(&tmp);
- }
+ ZVAL_DOUBLE(&tmp, zval_get_double(data));
str = (char *) safe_emalloc(EG(precision), 1, MAX_LENGTH_OF_DOUBLE + 1);
php_gcvt(Z_DVAL(tmp), EG(precision), '.', 'E', str);
@@ -3032,13 +3023,12 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP
xmlNodeSetContentLen(ret, BAD_CAST(list.s->val), list.s->len);
smart_str_free(&list);
} else {
- zval tmp = *data;
+ zval tmp;
char *str, *start, *next;
smart_str list = {0};
if (Z_TYPE_P(data) != IS_STRING) {
- zval_copy_ctor(&tmp);
- convert_to_string(&tmp);
+ ZVAL_STR(&tmp, zval_get_string(data));
data = &tmp;
}
str = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data));
@@ -3144,10 +3134,9 @@ static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodeP
if (Z_TYPE_P(data) == IS_STRING) {
ret = xmlNewTextLen(BAD_CAST(Z_STRVAL_P(data)), Z_STRLEN_P(data));
} else {
- zval tmp = *data;
+ zval tmp;
- zval_copy_ctor(&tmp);
- convert_to_string(&tmp);
+ ZVAL_STR(&tmp, zval_get_string(data));
ret = xmlNewTextLen(BAD_CAST(Z_STRVAL(tmp)), Z_STRLEN(tmp));
zval_dtor(&tmp);
}
diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c
index 44078733d6..1de8e021dd 100644
--- a/ext/spl/php_spl.c
+++ b/ext/spl/php_spl.c
@@ -351,7 +351,9 @@ PHP_FUNCTION(spl_autoload)
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
ex = ex->prev_execute_data;
}
- if (ex && ex->opline->opcode != ZEND_FETCH_CLASS) {
+ if (ex &&
+ ex->opline->opcode != ZEND_FETCH_CLASS &&
+ ex->opline->opcode != ZEND_NEW) {
zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Class %s could not be loaded", class_name->val);
} else {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s could not be loaded", class_name->val);
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 98a1c21b3e..57d0065b25 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -728,7 +728,7 @@ static int php_array_user_key_compare(const void *a, const void *b TSRMLS_DC) /*
zval_ptr_dtor(&args[0]);
zval_ptr_dtor(&args[1]);
- return result;
+ return result < 0 ? -1 : result > 0 ? 1 : 0;
}
/* }}} */
@@ -1301,9 +1301,10 @@ PHP_FUNCTION(array_search)
}
/* }}} */
-static int php_valid_var_name(char *var_name, int var_name_len) /* {{{ */
+static int php_valid_var_name(char *var_name, size_t var_name_len) /* {{{ */
{
- int i, ch;
+ size_t i;
+ int ch;
if (!var_name || !var_name_len) {
return 0;
@@ -1337,7 +1338,7 @@ static int php_valid_var_name(char *var_name, int var_name_len) /* {{{ */
}
/* }}} */
-PHPAPI int php_prefix_varname(zval *result, zval *prefix, char *var_name, int var_name_len, zend_bool add_underscore TSRMLS_DC) /* {{{ */
+PHPAPI int php_prefix_varname(zval *result, zval *prefix, char *var_name, size_t var_name_len, zend_bool add_underscore TSRMLS_DC) /* {{{ */
{
ZVAL_NEW_STR(result, zend_string_alloc(Z_STRLEN_P(prefix) + (add_underscore ? 1 : 0) + var_name_len, 0));
memcpy(Z_STRVAL_P(result), Z_STRVAL_P(prefix), Z_STRLEN_P(prefix));
@@ -1569,7 +1570,7 @@ PHP_FUNCTION(array_fill)
}
/* allocate an array for return */
- array_init_size(return_value, num);
+ array_init_size(return_value, (uint32_t)num);
if (num == 0) {
return;
@@ -1786,10 +1787,10 @@ err:
static void php_array_data_shuffle(zval *array TSRMLS_DC) /* {{{ */
{
- uint idx;
+ uint32_t idx, j, n_elems;
Bucket *p, temp;
HashTable *hash;
- int j, n_elems, rnd_idx, n_left;
+ zend_long rnd_idx, n_left;
n_elems = zend_hash_num_elements(Z_ARRVAL_P(array));
@@ -2222,7 +2223,7 @@ PHP_FUNCTION(array_splice)
/* Don't create the array of removed elements if it's not going
* to be used; e.g. only removing and/or replacing elements */
if (USED_RET()) {
- int size = length;
+ zend_long size = length;
/* Clamp the offset.. */
if (offset > num_in) {
@@ -2234,17 +2235,17 @@ PHP_FUNCTION(array_splice)
/* ..and the length */
if (length < 0) {
size = num_in - offset + length;
- } else if (((zend_ulong) offset + (zend_ulong) length) > (unsigned) num_in) {
+ } else if (((zend_ulong) offset + (zend_ulong) length) > (uint32_t) num_in) {
size = num_in - offset;
}
/* Initialize return value */
- array_init_size(return_value, size > 0 ? size : 0);
+ array_init_size(return_value, size > 0 ? (uint32_t)size : 0);
rem_hash = Z_ARRVAL_P(return_value);
}
/* Perform splice */
- new_hash = php_splice(Z_ARRVAL_P(array), offset, length, repl, repl_num, rem_hash);
+ new_hash = php_splice(Z_ARRVAL_P(array), (int)offset, (int)length, repl, (int)repl_num, rem_hash);
/* Replace input array's hashtable with the new one */
old_hash = *Z_ARRVAL_P(array);
@@ -2314,7 +2315,7 @@ PHP_FUNCTION(array_slice)
}
/* Initialize returned array */
- array_init_size(return_value, length > 0 ? length : 0);
+ array_init_size(return_value, length > 0 ? (uint32_t)length : 0);
if (length <= 0) {
return;
@@ -2897,9 +2898,9 @@ PHP_FUNCTION(array_pad)
/* Pad on the right or on the left */
if (pad_size > 0) {
- new_hash = php_splice(Z_ARRVAL_P(return_value), input_size, 0, pads, num_pads, NULL);
+ new_hash = php_splice(Z_ARRVAL_P(return_value), (int)input_size, 0, pads, (int)num_pads, NULL);
} else {
- new_hash = php_splice(Z_ARRVAL_P(return_value), 0, 0, pads, num_pads, NULL);
+ new_hash = php_splice(Z_ARRVAL_P(return_value), 0, 0, pads, (int)num_pads, NULL);
}
/* Copy the result hash into return value */
@@ -3971,22 +3972,23 @@ PHPAPI int php_multisort_compare(const void *a, const void *b TSRMLS_DC) /* {{{
Bucket *ab = *(Bucket **)a;
Bucket *bb = *(Bucket **)b;
int r;
- int result = 0;
+ zend_long result;
zval temp;
r = 0;
do {
+
php_set_compare_func(ARRAYG(multisort_flags)[MULTISORT_TYPE][r] TSRMLS_CC);
ARRAYG(compare_func)(&temp, &ab[r].val, &bb[r].val TSRMLS_CC);
result = ARRAYG(multisort_flags)[MULTISORT_ORDER][r] * Z_LVAL(temp);
if (result != 0) {
- return result;
+ return result > 0 ? 1 : -1;
}
r++;
} while (Z_TYPE(ab[r].val) != IS_UNDEF);
- return result;
+ return 0;
}
/* }}} */
@@ -4077,7 +4079,7 @@ PHP_FUNCTION(array_multisort)
/* flag allowed here */
if (parse_state[MULTISORT_TYPE] == 1) {
/* Save the flag and make sure then next arg is not the current flag. */
- sort_type = Z_LVAL(args[i]);
+ sort_type = (int)Z_LVAL(args[i]);
parse_state[MULTISORT_TYPE] = 0;
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is expected to be an array or sorting flag that has not already been specified", i + 1);
@@ -4205,7 +4207,7 @@ PHP_FUNCTION(array_rand)
/* Make the return value an array only if we need to pass back more than one result. */
if (num_req > 1) {
- array_init_size(return_value, num_req);
+ array_init_size(return_value, (uint32_t)num_req);
}
/* We can't use zend_hash_index_find() because the array may have string keys or gaps. */
@@ -4690,14 +4692,14 @@ PHP_FUNCTION(array_chunk)
size = num_in > 0 ? num_in : 1;
}
- array_init_size(return_value, ((num_in - 1) / size) + 1);
+ array_init_size(return_value, (uint32_t)(((num_in - 1) / size) + 1));
ZVAL_UNDEF(&chunk);
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, str_key, entry) {
/* If new chunk, create and initialize it. */
if (Z_TYPE(chunk) == IS_UNDEF) {
- array_init_size(&chunk, size);
+ array_init_size(&chunk, (uint32_t)size);
}
/* Add entry to the chunk, preserving keys if necessary. */
diff --git a/ext/standard/assert.c b/ext/standard/assert.c
index efb708d4a9..9fa5a1178c 100644
--- a/ext/standard/assert.c
+++ b/ext/standard/assert.c
@@ -25,12 +25,12 @@
/* }}} */
ZEND_BEGIN_MODULE_GLOBALS(assert)
- zend_long active;
- zend_long bail;
- zend_long warning;
- zend_long quiet_eval;
zval callback;
char *cb;
+ zend_bool active;
+ zend_bool bail;
+ zend_bool warning;
+ zend_bool quiet_eval;
ZEND_END_MODULE_GLOBALS(assert)
ZEND_DECLARE_MODULE_GLOBALS(assert)
@@ -78,11 +78,11 @@ static PHP_INI_MH(OnChangeCallback) /* {{{ */
/* }}} */
PHP_INI_BEGIN()
- STD_PHP_INI_ENTRY("assert.active", "1", PHP_INI_ALL, OnUpdateLong, active, zend_assert_globals, assert_globals)
- STD_PHP_INI_ENTRY("assert.bail", "0", PHP_INI_ALL, OnUpdateLong, bail, zend_assert_globals, assert_globals)
- STD_PHP_INI_ENTRY("assert.warning", "1", PHP_INI_ALL, OnUpdateLong, warning, zend_assert_globals, assert_globals)
+ STD_PHP_INI_ENTRY("assert.active", "1", PHP_INI_ALL, OnUpdateBool, active, zend_assert_globals, assert_globals)
+ STD_PHP_INI_ENTRY("assert.bail", "0", PHP_INI_ALL, OnUpdateBool, bail, zend_assert_globals, assert_globals)
+ STD_PHP_INI_ENTRY("assert.warning", "1", PHP_INI_ALL, OnUpdateBool, warning, zend_assert_globals, assert_globals)
PHP_INI_ENTRY("assert.callback", NULL, PHP_INI_ALL, OnChangeCallback)
- STD_PHP_INI_ENTRY("assert.quiet_eval", "0", PHP_INI_ALL, OnUpdateLong, quiet_eval, zend_assert_globals, assert_globals)
+ STD_PHP_INI_ENTRY("assert.quiet_eval", "0", PHP_INI_ALL, OnUpdateBool, quiet_eval, zend_assert_globals, assert_globals)
PHP_INI_END()
static void php_assert_init_globals(zend_assert_globals *assert_globals_p TSRMLS_DC) /* {{{ */
@@ -258,7 +258,7 @@ PHP_FUNCTION(assert_options)
{
zval *value = NULL;
zend_long what;
- int oldint;
+ zend_bool oldint;
int ac = ZEND_NUM_ARGS();
zend_string *key;
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 5bcd3d3386..106bc54141 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -3952,7 +3952,7 @@ PHP_FUNCTION(long2ip)
/* "It's a long but it's not, PHP ints are signed */
char *ip;
size_t ip_len;
- zend_ulong n;
+ uint32_t n;
struct in_addr myaddr;
#ifdef HAVE_INET_PTON
char str[40];
@@ -4076,7 +4076,7 @@ PHP_FUNCTION(putenv)
#endif
}
- pe.key_len = strlen(pe.key);
+ pe.key_len = (int)strlen(pe.key);
#ifdef PHP_WIN32
if (equals) {
if (pe.key_len < setting_len - 1) {
@@ -4289,7 +4289,7 @@ PHP_FUNCTION(getopt)
opts->need_param = 0;
opts->opt_name = estrdup(arg_str->val);
- len = strlen(opts->opt_name);
+ len = (int)strlen(opts->opt_name);
if ((len > 0) && (opts->opt_name[len - 1] == ':')) {
opts->need_param++;
opts->opt_name[len - 1] = '\0';
@@ -4345,7 +4345,7 @@ PHP_FUNCTION(getopt)
}
/* Add this option / argument pair to the result hash. */
- optname_len = strlen(optname);
+ optname_len = (int)strlen(optname);
if (!(optname_len > 1 && optname[0] == '0') && is_numeric_string(optname, optname_len, NULL, NULL, 0) == IS_LONG) {
/* numeric string */
int optname_int = atoi(optname);
@@ -4400,9 +4400,9 @@ PHP_FUNCTION(sleep)
RETURN_FALSE;
}
#ifdef PHP_SLEEP_NON_VOID
- RETURN_LONG(php_sleep(num));
+ RETURN_LONG(php_sleep((unsigned int)num));
#else
- php_sleep(num);
+ php_sleep((unsigned int)num);
#endif
}
@@ -4422,7 +4422,7 @@ PHP_FUNCTION(usleep)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of microseconds must be greater than or equal to 0");
RETURN_FALSE;
}
- usleep(num);
+ usleep((unsigned int)num);
#endif
}
/* }}} */
@@ -4449,7 +4449,7 @@ PHP_FUNCTION(time_nanosleep)
}
php_req.tv_sec = (time_t) tv_sec;
- php_req.tv_nsec = tv_nsec;
+ php_req.tv_nsec = (long)tv_nsec;
if (!nanosleep(&php_req, &php_rem)) {
RETURN_TRUE;
} else if (errno == EINTR) {
@@ -4554,7 +4554,7 @@ PHP_FUNCTION(get_cfg_var)
return;
}
- retval = cfg_get_entry(varname, varname_len);
+ retval = cfg_get_entry(varname, (uint)varname_len);
if (retval) {
if (Z_TYPE_P(retval) == IS_ARRAY) {
@@ -4637,7 +4637,7 @@ PHP_FUNCTION(error_log)
}
if (argc > 1) {
- opt_err = erropt;
+ opt_err = (int)erropt;
}
if (_php_error_log_ex(opt_err, message, message_len, opt, headers TSRMLS_CC) == FAILURE) {
@@ -4655,7 +4655,7 @@ PHPAPI int _php_error_log(int opt_err, char *message, char *opt, char *headers T
}
/* }}} */
-PHPAPI int _php_error_log_ex(int opt_err, char *message, int message_len, char *opt, char *headers TSRMLS_DC) /* {{{ */
+PHPAPI int _php_error_log_ex(int opt_err, char *message, size_t message_len, char *opt, char *headers TSRMLS_DC) /* {{{ */
{
php_stream *stream = NULL;
@@ -5212,7 +5212,7 @@ PHP_FUNCTION(ini_get)
return;
}
- str = zend_ini_string(varname, varname_len, 0);
+ str = zend_ini_string(varname, (uint)varname_len, 0);
if (!str) {
RETURN_FALSE;
@@ -5322,7 +5322,7 @@ PHP_FUNCTION(ini_set)
return;
}
- old_value = zend_ini_string(varname->val, varname->len, 0);
+ old_value = zend_ini_string(varname->val, (int)varname->len, 0);
/* copy to return here, because alter might free it! */
if (old_value) {
@@ -5331,7 +5331,7 @@ PHP_FUNCTION(ini_set)
RETVAL_FALSE;
}
-#define _CHECK_PATH(var, var_len, ini) php_ini_check_path(var, var_len, ini, sizeof(ini))
+#define _CHECK_PATH(var, var_len, ini) php_ini_check_path(var, (int)var_len, ini, sizeof(ini))
/* open basedir check */
if (PG(open_basedir)) {
if (_CHECK_PATH(varname->val, varname->len, "error_log") ||
@@ -5592,7 +5592,7 @@ PHP_FUNCTION(getprotobynumber)
return;
}
- ent = getprotobynumber(proto);
+ ent = getprotobynumber((int)proto);
if (ent == NULL) {
RETURN_FALSE;
@@ -5790,7 +5790,7 @@ static void php_simple_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int cal
}
if (!(Z_STRLEN_P(arg1) > 1 && Z_STRVAL_P(arg1)[0] == '0') && is_numeric_string(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), NULL, NULL, 0) == IS_LONG) {
- zend_ulong key = (zend_ulong) zend_atol(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1));
+ zend_ulong key = (zend_ulong) zend_atol(Z_STRVAL_P(arg1), (int)Z_STRLEN_P(arg1));
if ((find_hash = zend_hash_index_find(Z_ARRVAL_P(arr), key)) == NULL) {
array_init(&hash);
find_hash = zend_hash_index_update(Z_ARRVAL_P(arr), key, &hash);
@@ -5878,7 +5878,7 @@ PHP_FUNCTION(parse_ini_file)
fh.type = ZEND_HANDLE_FILENAME;
array_init(return_value);
- if (zend_parse_ini_file(&fh, 0, scanner_mode, ini_parser_cb, return_value TSRMLS_CC) == FAILURE) {
+ if (zend_parse_ini_file(&fh, 0, (int)scanner_mode, ini_parser_cb, return_value TSRMLS_CC) == FAILURE) {
zval_dtor(return_value);
RETURN_FALSE;
}
@@ -5917,7 +5917,7 @@ PHP_FUNCTION(parse_ini_string)
memset(string + str_len, 0, ZEND_MMAP_AHEAD);
array_init(return_value);
- if (zend_parse_ini_string(string, 0, scanner_mode, ini_parser_cb, return_value TSRMLS_CC) == FAILURE) {
+ if (zend_parse_ini_string(string, 0, (int)scanner_mode, ini_parser_cb, return_value TSRMLS_CC) == FAILURE) {
zval_dtor(return_value);
RETVAL_FALSE;
}
diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h
index 1c142af842..815227118e 100644
--- a/ext/standard/basic_functions.h
+++ b/ext/standard/basic_functions.h
@@ -142,8 +142,8 @@ PHP_RSHUTDOWN_FUNCTION(browscap);
/* Left for BC (not binary safe!) */
PHPAPI int _php_error_log(int opt_err, char *message, char *opt, char *headers TSRMLS_DC);
-PHPAPI int _php_error_log_ex(int opt_err, char *message, int message_len, char *opt, char *headers TSRMLS_DC);
-PHPAPI int php_prefix_varname(zval *result, zval *prefix, char *var_name, int var_name_len, zend_bool add_underscore TSRMLS_DC);
+PHPAPI int _php_error_log_ex(int opt_err, char *message, size_t message_len, char *opt, char *headers TSRMLS_DC);
+PHPAPI int php_prefix_varname(zval *result, zval *prefix, char *var_name, size_t var_name_len, zend_bool add_underscore TSRMLS_DC);
#if SIZEOF_INT == 4
/* Most 32-bit and 64-bit systems have 32-bit ints */
diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c
index 9599e2f056..7fae04fcbf 100644
--- a/ext/standard/crypt.c
+++ b/ext/standard/crypt.c
@@ -295,7 +295,7 @@ PHP_FUNCTION(crypt)
}
salt[salt_in_len] = '\0';
- if ((result = php_crypt(str, str_len, salt, salt_in_len)) == NULL) {
+ if ((result = php_crypt(str, (int)str_len, salt, (int)salt_in_len)) == NULL) {
if (salt[0] == '*' && salt[1] == '0') {
RETURN_STRING("*1");
} else {
diff --git a/ext/standard/crypt_sha256.c b/ext/standard/crypt_sha256.c
index 5f28bd7b9f..d79d14510a 100644
--- a/ext/standard/crypt_sha256.c
+++ b/ext/standard/crypt_sha256.c
@@ -120,7 +120,7 @@ static void sha256_process_block (const void *buffer, size_t len, struct sha256_
/* First increment the byte count. FIPS 180-2 specifies the possible
length of the file up to 2^64 bits. Here we only compute the
number of bytes. Do a double word increment. */
- ctx->total[0] += len;
+ ctx->total[0] += (uint32_t)len;
if (ctx->total[0] < len) {
++ctx->total[1];
}
@@ -261,7 +261,7 @@ static void sha256_process_bytes(const void *buffer, size_t len, struct sha256_c
size_t add = 128 - left_over > len ? len : 128 - left_over;
memcpy(&ctx->buffer[left_over], buffer, add);
- ctx->buflen += add;
+ ctx->buflen += (uint32_t)add;
if (ctx->buflen > 64) {
sha256_process_block(ctx->buffer, ctx->buflen & ~63, ctx);
@@ -306,7 +306,7 @@ compilers don't. */
left_over -= 64;
memcpy(ctx->buffer, &ctx->buffer[64], left_over);
}
- ctx->buflen = left_over;
+ ctx->buflen = (uint32_t)left_over;
}
}
@@ -529,7 +529,7 @@ char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int b
}
cp = __php_stpncpy(cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
- buflen -= MIN((size_t) MAX (0, buflen), salt_len);
+ buflen -= MIN(MAX (0, buflen), (int)salt_len);
if (buflen > 0) {
*cp++ = '$';
@@ -600,7 +600,7 @@ char * php_sha256_crypt(const char *key, const char *salt)
static int buflen;
int needed = (sizeof(sha256_salt_prefix) - 1
+ sizeof(sha256_rounds_prefix) + 9 + 1
- + strlen(salt) + 1 + 43 + 1);
+ + (int)strlen(salt) + 1 + 43 + 1);
if (buflen < needed) {
char *new_buffer = (char *) realloc(buffer, needed);
diff --git a/ext/standard/dir.c b/ext/standard/dir.c
index 6f4c70ebba..b0be40ee35 100644
--- a/ext/standard/dir.c
+++ b/ext/standard/dir.c
@@ -87,7 +87,7 @@ static zend_class_entry *dir_class_entry_ptr;
} \
ZEND_FETCH_RESOURCE(dirp, php_stream *, tmp, -1, "Directory", php_file_le_stream()); \
} else { \
- ZEND_FETCH_RESOURCE(dirp, php_stream *, 0, DIRG(default_dir)->handle, "Directory", php_file_le_stream()); \
+ ZEND_FETCH_RESOURCE(dirp, php_stream *, 0, (int)DIRG(default_dir)->handle, "Directory", php_file_le_stream()); \
} \
} else { \
dirp = (php_stream *) zend_fetch_resource(id TSRMLS_CC, -1, "Directory", NULL, 1, php_file_le_stream()); \
@@ -463,7 +463,7 @@ PHP_FUNCTION(glob)
cwd[2] = '\0';
}
#endif
- cwd_skip = strlen(cwd)+1;
+ cwd_skip = (int)strlen(cwd)+1;
snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern);
pattern = work_pattern;
diff --git a/ext/standard/dl.c b/ext/standard/dl.c
index 6ea69e5b81..a9ca94c0ad 100644
--- a/ext/standard/dl.c
+++ b/ext/standard/dl.c
@@ -129,7 +129,7 @@ PHPAPI int php_load_extension(char *filename, int type, int start_now TSRMLS_DC)
}
libpath = estrdup(filename);
} else if (extension_dir && extension_dir[0]) {
- int extension_dir_len = strlen(extension_dir);
+ int extension_dir_len = (int)strlen(extension_dir);
if (IS_SLASH(extension_dir[extension_dir_len-1])) {
spprintf(&libpath, 0, "%s%s", extension_dir, filename); /* SAFE */
diff --git a/ext/standard/dns_win32.c b/ext/standard/dns_win32.c
index 865ad30b3e..963d1f7a54 100644
--- a/ext/standard/dns_win32.c
+++ b/ext/standard/dns_win32.c
@@ -208,7 +208,7 @@ static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, int raw,
DWORD count = data_txt->dwStringCount;
zend_string *txt;
char *txt_dst;
- long txt_len = 0;
+ size_t txt_len = 0;
zval entries;
add_assoc_string(subarray, "type", "TXT");
@@ -222,7 +222,7 @@ static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, int raw,
txt = zend_string_safe_alloc(txt_len, 2, 0, 0);
txt_dst = txt->val;
for (i = 0; i < count; i++) {
- int len = strlen(data_txt->pStringArray[i]);
+ size_t len = strlen(data_txt->pStringArray[i]);
memcpy(txt_dst, data_txt->pStringArray[i], len);
add_next_index_stringl(&entries, data_txt->pStringArray[i], len);
txt_dst += len;
diff --git a/ext/standard/exec.c b/ext/standard/exec.c
index 28f01b338f..6106fe2c86 100644
--- a/ext/standard/exec.c
+++ b/ext/standard/exec.c
@@ -61,7 +61,8 @@ PHPAPI int php_exec(int type, char *cmd, zval *array, zval *return_value TSRMLS_
{
FILE *fp;
char *buf;
- int l = 0, pclose_return;
+ size_t l = 0;
+ int pclose_return;
char *b, *d=NULL;
php_stream *stream;
size_t buflen, bufl = 0;
@@ -115,8 +116,8 @@ PHPAPI int php_exec(int type, char *cmd, zval *array, zval *return_value TSRMLS_
} else if (type == 2) {
/* strip trailing whitespaces */
l = bufl;
- while (l-- && isspace(((unsigned char *)buf)[l]));
- if (l != (int)(bufl - 1)) {
+ while (l >= 1 && l-- && isspace(((unsigned char *)buf)[l]));
+ if (l != (bufl - 1)) {
bufl = l + 1;
buf[bufl] = '\0';
}
@@ -128,8 +129,8 @@ PHPAPI int php_exec(int type, char *cmd, zval *array, zval *return_value TSRMLS_
/* strip trailing whitespaces if we have not done so already */
if ((type == 2 && buf != b) || type != 2) {
l = bufl;
- while (l-- && isspace(((unsigned char *)buf)[l]));
- if (l != (int)(bufl - 1)) {
+ while (l >= 1 && l-- && isspace(((unsigned char *)buf)[l]));
+ if (l != (bufl - 1)) {
bufl = l + 1;
buf[bufl] = '\0';
}
@@ -240,7 +241,7 @@ PHP_FUNCTION(passthru)
*/
PHPAPI zend_string *php_escape_shell_cmd(char *str)
{
- register int x, y, l = strlen(str);
+ register int x, y, l = (int)strlen(str);
char *p = NULL;
size_t estimate = (2 * l) + 1;
zend_string *cmd;
@@ -333,7 +334,7 @@ PHPAPI zend_string *php_escape_shell_cmd(char *str)
*/
PHPAPI zend_string *php_escape_shell_arg(char *str)
{
- int x, y = 0, l = strlen(str);
+ int x, y = 0, l = (int)strlen(str);
zend_string *cmd;
size_t estimate = (4 * l) + 3;
diff --git a/ext/standard/file.c b/ext/standard/file.c
index 446da20fb3..ff7c5433eb 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -1098,7 +1098,7 @@ PHPAPI PHP_FUNCTION(fgetss)
php_stream *stream;
zend_string *allowed = NULL;
char *allowed_tags=NULL;
- int allowed_tags_len=0;
+ size_t allowed_tags_len=0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lS", &fd, &bytes, &allowed) == FAILURE) {
RETURN_FALSE;
@@ -1196,8 +1196,8 @@ PHPAPI PHP_FUNCTION(fwrite)
zval *arg1;
char *arg2;
size_t arg2len;
- int ret;
- int num_bytes;
+ size_t ret;
+ size_t num_bytes;
zend_long arg3 = 0;
char *buffer = NULL;
php_stream *stream;
@@ -1309,7 +1309,7 @@ PHPAPI PHP_FUNCTION(fseek)
PHP_STREAM_TO_ZVAL(stream, arg1);
- RETURN_LONG(php_stream_seek(stream, arg2, whence));
+ RETURN_LONG(php_stream_seek(stream, arg2, (int)whence));
}
/* }}} */
@@ -1355,7 +1355,7 @@ PHP_FUNCTION(mkdir)
context = php_stream_context_from_zval(zcontext, 0);
- RETURN_BOOL(php_stream_mkdir(dir, mode, (recursive ? PHP_STREAM_MKDIR_RECURSIVE : 0) | REPORT_ERRORS, context));
+ RETURN_BOOL(php_stream_mkdir(dir, (int)mode, (recursive ? PHP_STREAM_MKDIR_RECURSIVE : 0) | REPORT_ERRORS, context));
}
/* }}} */
@@ -1384,7 +1384,7 @@ PHP_FUNCTION(readfile)
{
char *filename;
size_t filename_len;
- int size = 0;
+ size_t size = 0;
zend_bool use_include_path = 0;
zval *zcontext = NULL;
php_stream *stream;
@@ -1427,7 +1427,7 @@ PHP_FUNCTION(umask)
if (ZEND_NUM_ARGS() == 0) {
umask(oldumask);
} else {
- umask(arg1);
+ umask((int)arg1);
}
RETURN_LONG(oldumask);
@@ -1439,7 +1439,7 @@ PHP_FUNCTION(umask)
PHPAPI PHP_FUNCTION(fpassthru)
{
zval *arg1;
- int size;
+ size_t size;
php_stream *stream;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
@@ -1852,7 +1852,7 @@ PHP_FUNCTION(fputcsv)
char escape_char = '\\'; /* allow this to be set as parameter */
php_stream *stream;
zval *fp = NULL, *fields = NULL;
- int ret;
+ size_t ret;
char *delimiter_str = NULL, *enclosure_str = NULL, *escape_str = NULL;
size_t delimiter_str_len = 0, enclosure_str_len = 0, escape_str_len = 0;
@@ -1908,7 +1908,8 @@ PHP_FUNCTION(fputcsv)
/* {{{ PHPAPI size_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, char escape_char TSRMLS_DC) */
PHPAPI size_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, char escape_char TSRMLS_DC)
{
- int count, i = 0, ret;
+ int count, i = 0;
+ size_t ret;
zval *field_tmp;
smart_str csvline = {0};
@@ -2486,7 +2487,7 @@ PHP_FUNCTION(fnmatch)
RETURN_FALSE;
}
- RETURN_BOOL( ! fnmatch( pattern, filename, flags ));
+ RETURN_BOOL( ! fnmatch( pattern, filename, (int)flags ));
}
/* }}} */
#endif
diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c
index 6a06a55d94..53aede1469 100644
--- a/ext/standard/filestat.c
+++ b/ext/standard/filestat.c
@@ -835,7 +835,7 @@ PHP_FUNCTION(clearstatcache)
return;
}
- php_clear_stat_cache(clear_realpath_cache, filename, filename_len TSRMLS_CC);
+ php_clear_stat_cache(clear_realpath_cache, filename, (int)filename_len TSRMLS_CC);
}
/* }}} */
diff --git a/ext/standard/filters.c b/ext/standard/filters.c
index f0f49950bb..3fd27afa43 100644
--- a/ext/standard/filters.c
+++ b/ext/standard/filters.c
@@ -176,14 +176,14 @@ typedef struct _php_strip_tags_filter {
int persistent;
} php_strip_tags_filter;
-static int php_strip_tags_filter_ctor(php_strip_tags_filter *inst, const char *allowed_tags, int allowed_tags_len, int persistent)
+static int php_strip_tags_filter_ctor(php_strip_tags_filter *inst, const char *allowed_tags, size_t allowed_tags_len, int persistent)
{
if (allowed_tags != NULL) {
if (NULL == (inst->allowed_tags = pemalloc(allowed_tags_len, persistent))) {
return FAILURE;
}
memcpy((char *)inst->allowed_tags, allowed_tags, allowed_tags_len);
- inst->allowed_tags_len = allowed_tags_len;
+ inst->allowed_tags_len = (int)allowed_tags_len;
} else {
inst->allowed_tags = NULL;
}
@@ -861,7 +861,8 @@ static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *ins
/* Check to see if this is EOL whitespace. */
if (inst->lbchars != NULL) {
unsigned char *ps2;
- unsigned int j, lb_cnt2;
+ unsigned int lb_cnt2;
+ size_t j;
lb_cnt2 = 0;
ps2 = ps;
@@ -1265,7 +1266,7 @@ static php_conv_err_t php_conv_get_ulong_prop_ex(const HashTable *ht, zend_ulong
zval tmp;
if (Z_TYPE_P(tmpval) != IS_LONG) {
- ZVAL_DUP(&tmp, tmpval);;
+ ZVAL_DUP(&tmp, tmpval);
convert_to_long(&tmp);
tmpval = &tmp;
}
@@ -1318,6 +1319,7 @@ static int php_conv_get_int_prop_ex(const HashTable *ht, int *pretval, char *fie
}
#endif
+/* XXX this might need an additional fix so it uses size_t, whereby unsigned is quite big so leaving as is for now */
static int php_conv_get_uint_prop_ex(const HashTable *ht, unsigned int *pretval, char *field_name, size_t field_name_len)
{
zend_ulong l;
@@ -1326,7 +1328,7 @@ static int php_conv_get_uint_prop_ex(const HashTable *ht, unsigned int *pretval,
*pretval = 0;
if ((err = php_conv_get_ulong_prop_ex(ht, &l, field_name, field_name_len)) == PHP_CONV_ERR_SUCCESS) {
- *pretval = l;
+ *pretval = (unsigned int)l;
}
return err;
}
@@ -1931,12 +1933,12 @@ typedef struct _php_chunked_filter_data {
int persistent;
} php_chunked_filter_data;
-static int php_dechunk(char *buf, int len, php_chunked_filter_data *data)
+static size_t php_dechunk(char *buf, size_t len, php_chunked_filter_data *data)
{
char *p = buf;
char *end = p + len;
char *out = buf;
- int out_len = 0;
+ size_t out_len = 0;
while (p < end) {
switch (data->state) {
diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c
index 8f211d0236..f84075440b 100644
--- a/ext/standard/formatted_print.c
+++ b/ext/standard/formatted_print.c
@@ -376,7 +376,7 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC)
char *format, padding;
zend_string *result;
int always_sign;
- int format_len;
+ size_t format_len;
if (zend_parse_parameters(param_count TSRMLS_CC, "+", &args, &argc) == FAILURE) {
return NULL;
diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c
index 090d3f8f32..30a6fda5d6 100644
--- a/ext/standard/fsock.c
+++ b/ext/standard/fsock.c
@@ -35,14 +35,18 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
size_t host_len;
zend_long port = -1;
zval *zerrno = NULL, *zerrstr = NULL;
- double timeout = FG(default_socket_timeout);
- zend_ulong conv;
+ double timeout = (double)FG(default_socket_timeout);
+#ifndef PHP_WIN32
+ time_t conv;
+#else
+ long conv;
+#endif
struct timeval tv;
char *hashkey = NULL;
php_stream *stream = NULL;
int err;
char *hostname = NULL;
- zend_long hostname_len;
+ size_t hostname_len;
zend_string *errstr = NULL;
RETVAL_FALSE;
@@ -63,8 +67,13 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
}
/* prepare the timeout value for use */
- conv = (unsigned long) (timeout * 1000000.0);
+#ifndef PHP_WIN32
+ conv = (time_t) (timeout * 1000000.0);
tv.tv_sec = conv / 1000000;
+#else
+ conv = (long) (timeout * 1000000.0);
+ tv.tv_sec = conv / 1000000;
+#endif
tv.tv_usec = conv % 1000000;
if (zerrno) {
diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c
index 2bf4e02a41..ed93345bac 100644
--- a/ext/standard/ftp_fopen_wrapper.c
+++ b/ext/standard/ftp_fopen_wrapper.c
@@ -155,7 +155,7 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char
if (resource->port == 0)
resource->port = 21;
- transport_len = spprintf(&transport, 0, "tcp://%s:%d", resource->host, resource->port);
+ transport_len = (int)spprintf(&transport, 0, "tcp://%s:%d", resource->host, resource->port);
stream = php_stream_xport_create(transport, transport_len, REPORT_ERRORS, STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, NULL, NULL, context, NULL, NULL);
efree(transport);
if (stream == NULL) {
@@ -245,7 +245,7 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char
/* send the user name */
if (resource->user != NULL) {
- tmp_len = php_raw_url_decode(resource->user, strlen(resource->user));
+ tmp_len = (int)php_raw_url_decode(resource->user, (int)strlen(resource->user));
PHP_FTP_CNTRL_CHK(resource->user, tmp_len, "Invalid login %s")
@@ -262,7 +262,7 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char
php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_REQUIRED, tmp_line, 0);
if (resource->pass != NULL) {
- tmp_len = php_raw_url_decode(resource->pass, strlen(resource->pass));
+ tmp_len = (int)php_raw_url_decode(resource->pass, (int)strlen(resource->pass));
PHP_FTP_CNTRL_CHK(resource->pass, tmp_len, "Invalid password %s")
@@ -424,8 +424,8 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa
php_stream *reuseid=NULL;
size_t file_size = 0;
zval *tmpzval;
- int allow_overwrite = 0;
- int read_write = 0;
+ zend_bool allow_overwrite = 0;
+ int8_t read_write = 0;
char *transport;
int transport_len;
@@ -498,7 +498,7 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa
} else if (read_write == 2) {
/* when writing file (but not appending), it must NOT exist, unless a context option exists which allows it */
if (context && (tmpzval = php_stream_context_get_option(context, "ftp", "overwrite")) != NULL) {
- allow_overwrite = Z_LVAL_P(tmpzval);
+ allow_overwrite = Z_LVAL_P(tmpzval) ? 1 : 0;
}
if (result <= 299 && result >= 200) {
if (allow_overwrite) {
@@ -554,7 +554,7 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa
if (hoststart == NULL) {
hoststart = resource->host;
}
- transport_len = spprintf(&transport, 0, "tcp://%s:%d", hoststart, portno);
+ transport_len = (int)spprintf(&transport, 0, "tcp://%s:%d", hoststart, portno);
datastream = php_stream_xport_create(transport, transport_len, REPORT_ERRORS, STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, NULL, NULL, context, NULL, NULL);
efree(transport);
if (datastream == NULL) {
@@ -855,7 +855,7 @@ static int php_stream_ftp_url_stat(php_stream_wrapper *wrapper, const char *url,
gmt->tm_isdst = -1;
/* apply the GMT offset */
- tm.tm_sec += stamp - mktime(gmt);
+ tm.tm_sec += (long)(stamp - mktime(gmt));
tm.tm_isdst = gmt->tm_isdst;
ssb->sb.st_mtime = mktime(&tm);
diff --git a/ext/standard/head.c b/ext/standard/head.c
index 3dd18ee0fd..1417b52bc0 100644
--- a/ext/standard/head.c
+++ b/ext/standard/head.c
@@ -73,10 +73,10 @@ PHPAPI int php_header(TSRMLS_D)
}
-PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, time_t expires, char *path, int path_len, char *domain, int domain_len, int secure, int url_encode, int httponly TSRMLS_DC)
+PHPAPI int php_setcookie(char *name, size_t name_len, char *value, size_t value_len, time_t expires, char *path, size_t path_len, char *domain, size_t domain_len, int secure, int url_encode, int httponly TSRMLS_DC)
{
char *cookie;
- int len=sizeof("Set-Cookie: ");
+ size_t len=sizeof("Set-Cookie: ");
zend_string *dt;
sapi_header_line ctr = {0};
int result;
@@ -164,7 +164,7 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t
}
ctr.line = cookie;
- ctr.line_len = strlen(cookie);
+ ctr.line_len = (uint)strlen(cookie);
result = sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC);
efree(cookie);
@@ -300,7 +300,7 @@ PHP_FUNCTION(http_response_code)
zend_long old_response_code;
old_response_code = SG(sapi_headers).http_response_code;
- SG(sapi_headers).http_response_code = response_code;
+ SG(sapi_headers).http_response_code = (int)response_code;
if (old_response_code) {
RETURN_LONG(old_response_code);
diff --git a/ext/standard/head.h b/ext/standard/head.h
index e32810a6f3..850a71dc74 100644
--- a/ext/standard/head.h
+++ b/ext/standard/head.h
@@ -38,6 +38,6 @@ PHP_FUNCTION(headers_list);
PHP_FUNCTION(http_response_code);
PHPAPI int php_header(TSRMLS_D);
-PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, time_t expires, char *path, int path_len, char *domain, int domain_len, int secure, int url_encode, int httponly TSRMLS_DC);
+PHPAPI int php_setcookie(char *name, size_t name_len, char *value, size_t value_len, time_t expires, char *path, size_t path_len, char *domain, size_t domain_len, int secure, int url_encode, int httponly TSRMLS_DC);
#endif
diff --git a/ext/standard/html.c b/ext/standard/html.c
index dfe30d9b3e..516bcc4ef7 100644
--- a/ext/standard/html.c
+++ b/ext/standard/html.c
@@ -377,7 +377,7 @@ static enum entity_charset determine_charset(char *charset_hint TSRMLS_DC)
{
int i;
enum entity_charset charset = cs_utf_8;
- int len = 0;
+ size_t len = 0;
const zend_encoding *zenc;
/* Default is now UTF-8 */
@@ -1513,7 +1513,7 @@ PHP_FUNCTION(htmlspecialchars_decode)
return;
}
- replaced = php_unescape_html_entities((unsigned char*)str, str_len, 0 /*!all*/, quote_style, NULL TSRMLS_CC);
+ replaced = php_unescape_html_entities((unsigned char*)str, str_len, 0 /*!all*/, (int)quote_style, NULL TSRMLS_CC);
if (replaced) {
RETURN_STR(replaced);
}
@@ -1547,7 +1547,7 @@ PHP_FUNCTION(html_entity_decode)
if (!hint_charset) {
default_charset = get_default_charset(TSRMLS_C);
}
- replaced = php_unescape_html_entities((unsigned char*)str->val, str->len, 1 /*all*/, quote_style, (hint_charset ? hint_charset->val : default_charset) TSRMLS_CC);
+ replaced = php_unescape_html_entities((unsigned char*)str->val, str->len, 1 /*all*/, (int)quote_style, (hint_charset ? hint_charset->val : default_charset) TSRMLS_CC);
if (replaced) {
RETURN_STR(replaced);
@@ -1649,7 +1649,7 @@ PHP_FUNCTION(get_html_translation_table)
array_init(return_value);
- entity_table = determine_entity_table(all, doctype);
+ entity_table = determine_entity_table((int)all, doctype);
if (all && !CHARSET_UNICODE_COMPAT(charset)) {
to_uni_table = enc_to_uni_index[charset];
}
diff --git a/ext/standard/http.c b/ext/standard/http.c
index 9174163b7d..e5ba87d870 100644
--- a/ext/standard/http.c
+++ b/ext/standard/http.c
@@ -26,9 +26,9 @@
/* {{{ php_url_encode_hash */
PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
- const char *num_prefix, int num_prefix_len,
- const char *key_prefix, int key_prefix_len,
- const char *key_suffix, int key_suffix_len,
+ const char *num_prefix, size_t num_prefix_len,
+ const char *key_prefix, size_t key_prefix_len,
+ const char *key_suffix, size_t key_suffix_len,
zval *type, char *arg_sep, int enc_type TSRMLS_DC)
{
zend_string *key = NULL;
@@ -107,7 +107,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
*p = '\0';
} else {
char *ekey;
- int ekey_len;
+ size_t ekey_len;
/* Is an integer key */
ekey_len = spprintf(&ekey, 0, "%pd", idx);
newprefix_len = key_prefix_len + num_prefix_len + ekey_len + key_suffix_len + 3 /* %5B */;
@@ -194,7 +194,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
case IS_DOUBLE:
{
char *ekey;
- int ekey_len;
+ size_t ekey_len;
ekey_len = spprintf(&ekey, 0, "%.*G", (int) EG(precision), Z_DVAL_P(zdata));
smart_str_appendl(formstr, ekey, ekey_len);
efree(ekey);
@@ -242,7 +242,7 @@ PHP_FUNCTION(http_build_query)
RETURN_FALSE;
}
- if (php_url_encode_hash_ex(HASH_OF(formdata), &formstr, prefix, prefix_len, NULL, 0, NULL, 0, (Z_TYPE_P(formdata) == IS_OBJECT ? formdata : NULL), arg_sep, enc_type TSRMLS_CC) == FAILURE) {
+ if (php_url_encode_hash_ex(HASH_OF(formdata), &formstr, prefix, prefix_len, NULL, 0, NULL, 0, (Z_TYPE_P(formdata) == IS_OBJECT ? formdata : NULL), arg_sep, (int)enc_type TSRMLS_CC) == FAILURE) {
if (formstr.s) {
smart_str_free(&formstr);
}
diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c
index 27c6cf6248..e1f8653c8d 100644
--- a/ext/standard/http_fopen_wrapper.c
+++ b/ext/standard/http_fopen_wrapper.c
@@ -121,7 +121,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
char *tmp = NULL;
char *ua_str = NULL;
zval *ua_zval = NULL, *tmpzval = NULL, ssl_proxy_peer_name;
- int scratch_len = 0;
+ size_t scratch_len = 0;
int body = 0;
char location[HTTP_HEADER_BLOCK_SIZE];
zval *response_header = NULL;
@@ -132,14 +132,16 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
int eol_detect = 0;
char *transport_string;
zend_string *errstr = NULL;
- int transport_len, have_header = 0, request_fulluri = 0, ignore_errors = 0;
+ size_t transport_len;
+ int have_header = 0;
+ zend_bool request_fulluri = 0, ignore_errors = 0;
char *protocol_version = NULL;
int protocol_version_len = 3; /* Default: "1.0" */
struct timeval timeout;
char *user_headers = NULL;
int header_init = ((flags & HTTP_WRAPPER_HEADER_INIT) != 0);
int redirected = ((flags & HTTP_WRAPPER_REDIRECTED) != 0);
- int follow_location = 1;
+ zend_bool follow_location = 1;
php_stream_filter *transfer_encoding = NULL;
int response_code;
zend_array *symbol_table;
@@ -201,10 +203,19 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
if (context && (tmpzval = php_stream_context_get_option(context, wrapper->wops->label, "timeout")) != NULL) {
double d = zval_get_double(tmpzval);
+#ifndef PHP_WIN32
timeout.tv_sec = (time_t) d;
timeout.tv_usec = (size_t) ((d - timeout.tv_sec) * 1000000);
+#else
+ timeout.tv_sec = (long) d;
+ timeout.tv_usec = (long) ((d - timeout.tv_sec) * 1000000);
+#endif
} else {
+#ifndef PHP_WIN32
timeout.tv_sec = FG(default_socket_timeout);
+#else
+ timeout.tv_sec = (long)FG(default_socket_timeout);
+#endif
timeout.tv_usec = 0;
}
@@ -346,7 +357,7 @@ finish:
php_stream_notify_info(context, PHP_STREAM_NOTIFY_CONNECT, NULL, 0);
if (header_init && context && (tmpzval = php_stream_context_get_option(context, "http", "max_redirects")) != NULL) {
- redirect_max = zval_get_long(tmpzval);
+ redirect_max = (int)zval_get_long(tmpzval);
}
if (context && (tmpzval = php_stream_context_get_option(context, "http", "method")) != NULL) {
@@ -366,7 +377,7 @@ finish:
}
if (context && (tmpzval = php_stream_context_get_option(context, "http", "protocol_version")) != NULL) {
- protocol_version_len = spprintf(&protocol_version, 0, "%.1F", zval_get_double(tmpzval));
+ protocol_version_len = (int)spprintf(&protocol_version, 0, "%.1F", zval_get_double(tmpzval));
}
if (!scratch) {
@@ -378,7 +389,7 @@ finish:
/* Should we send the entire path in the request line, default to no. */
if (!request_fulluri && context &&
(tmpzval = php_stream_context_get_option(context, "http", "request_fulluri")) != NULL) {
- request_fulluri = zend_is_true(tmpzval TSRMLS_CC) ? 1 : 0;
+ request_fulluri = zend_is_true(tmpzval TSRMLS_CC);
}
if (request_fulluri) {
@@ -731,7 +742,7 @@ finish:
if (!strncasecmp(http_header_line, "Location: ", 10)) {
if (context && (tmpzval = php_stream_context_get_option(context, "http", "follow_location")) != NULL) {
- follow_location = zval_get_long(tmpzval);
+ follow_location = zval_is_true(tmpzval);
} else if (!(response_code >= 300 && response_code < 304 || 307 == response_code || 308 == response_code)) {
/* we shouldn't redirect automatically
if follow_location isn't set and response_code not in (300, 301, 302, 303 and 307)
@@ -843,7 +854,7 @@ finish:
#define CHECK_FOR_CNTRL_CHARS(val) { \
if (val) { \
unsigned char *s, *e; \
- int l; \
+ size_t l; \
l = php_url_decode(val, strlen(val)); \
s = (unsigned char*)val; e = s + l; \
while (s < e) { \
@@ -891,7 +902,7 @@ out:
/* Restore original chunk size now that we're done with headers */
if (options & STREAM_WILL_CAST)
- php_stream_set_chunk_size(stream, chunk_size);
+ php_stream_set_chunk_size(stream, (int)chunk_size);
/* restore the users auto-detect-line-endings setting */
stream->flags |= eol_detect;
diff --git a/ext/standard/info.c b/ext/standard/info.c
index bc0ddddcc0..7a118af7b4 100644
--- a/ext/standard/info.c
+++ b/ext/standard/info.c
@@ -61,9 +61,9 @@ PHPAPI extern char *php_ini_opened_path;
PHPAPI extern char *php_ini_scanned_path;
PHPAPI extern char *php_ini_scanned_files;
-static int php_info_print_html_esc(const char *str, int len) /* {{{ */
+static int php_info_print_html_esc(const char *str, size_t len) /* {{{ */
{
- int written;
+ size_t written;
zend_string *new_str;
TSRMLS_FETCH();
@@ -77,7 +77,7 @@ static int php_info_print_html_esc(const char *str, int len) /* {{{ */
static int php_info_printf(const char *fmt, ...) /* {{{ */
{
char *buf;
- int len, written;
+ size_t len, written;
va_list argv;
TSRMLS_FETCH();
@@ -1026,7 +1026,7 @@ PHPAPI void php_info_print_table_colspan_header(int num_cols, char *header) /* {
if (!sapi_module.phpinfo_as_text) {
php_info_printf("<tr class=\"h\"><th colspan=\"%d\">%s</th></tr>\n", num_cols, header );
} else {
- spaces = (74 - strlen(header));
+ spaces = (int)(74 - strlen(header));
php_info_printf("%*s%s%*s\n", (int)(spaces/2), " ", header, (int)(spaces/2), " ");
}
}
@@ -1176,7 +1176,7 @@ PHP_FUNCTION(phpinfo)
/* Andale! Andale! Yee-Hah! */
php_output_start_default(TSRMLS_C);
- php_print_info(flag TSRMLS_CC);
+ php_print_info((int)flag TSRMLS_CC);
php_output_end(TSRMLS_C);
RETURN_TRUE;
@@ -1218,7 +1218,7 @@ PHP_FUNCTION(phpcredits)
return;
}
- php_print_credits(flag TSRMLS_CC);
+ php_print_credits((int)flag TSRMLS_CC);
RETURN_TRUE;
}
/* }}} */
diff --git a/ext/standard/levenshtein.c b/ext/standard/levenshtein.c
index df822f45d4..e776934e1f 100644
--- a/ext/standard/levenshtein.c
+++ b/ext/standard/levenshtein.c
@@ -27,10 +27,11 @@
/* {{{ reference_levdist
* reference implementation, only optimized for memory usage, not speed */
-static int reference_levdist(const char *s1, int l1, const char *s2, int l2, int cost_ins, int cost_rep, int cost_del )
+static zend_long reference_levdist(const char *s1, size_t l1, const char *s2, size_t l2, zend_long cost_ins, zend_long cost_rep, zend_long cost_del )
{
- int *p1, *p2, *tmp;
- int i1, i2, c0, c1, c2;
+ zend_long *p1, *p2, *tmp;
+ zend_long c0, c1, c2;
+ size_t i1, i2;
if (l1 == 0) {
return l2 * cost_ins;
@@ -42,8 +43,8 @@ static int reference_levdist(const char *s1, int l1, const char *s2, int l2, int
if ((l1 > LEVENSHTEIN_MAX_LENGTH) || (l2 > LEVENSHTEIN_MAX_LENGTH)) {
return -1;
}
- p1 = safe_emalloc((l2 + 1), sizeof(int), 0);
- p2 = safe_emalloc((l2 + 1), sizeof(int), 0);
+ p1 = safe_emalloc((l2 + 1), sizeof(zend_long), 0);
+ p2 = safe_emalloc((l2 + 1), sizeof(zend_long), 0);
for (i2 = 0; i2 <= l2; i2++) {
p1[i2] = i2 * cost_ins;
@@ -96,7 +97,7 @@ PHP_FUNCTION(levenshtein)
char *callback_name;
size_t str1_len, str2_len, callback_len;
zend_long cost_ins, cost_rep, cost_del;
- int distance = -1;
+ zend_long distance = -1;
switch (argc) {
case 2: /* just two strings: use maximum performance version */
diff --git a/ext/standard/mail.c b/ext/standard/mail.c
index 96363f4cb9..5d2b576c7e 100644
--- a/ext/standard/mail.c
+++ b/ext/standard/mail.c
@@ -251,7 +251,7 @@ PHPAPI int php_mail(char *to, char *subject, char *message, char *headers, char
if (mail_log && *mail_log) {
char *tmp;
time_t curtime;
- int l;
+ size_t l;
zend_string *date_str;
time(&curtime);
diff --git a/ext/standard/math.c b/ext/standard/math.c
index 7014e6c938..31eb259829 100644
--- a/ext/standard/math.c
+++ b/ext/standard/math.c
@@ -382,7 +382,7 @@ PHP_FUNCTION(round)
case IS_DOUBLE:
return_val = (Z_TYPE_P(value) == IS_LONG) ? (double)Z_LVAL_P(value) : Z_DVAL_P(value);
- return_val = _php_math_round(return_val, places, mode);
+ return_val = _php_math_round(return_val, (int)places, (int)mode);
RETURN_DOUBLE(return_val);
break;
@@ -946,7 +946,7 @@ PHP_FUNCTION(rad2deg)
PHPAPI zend_long _php_math_basetolong(zval *arg, int base)
{
zend_long num = 0, digit, onum;
- int i;
+ zend_long i;
char c, *s;
if (Z_TYPE_P(arg) != IS_STRING || base < 2 || base > 36) {
@@ -992,7 +992,7 @@ PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret)
{
zend_long num = 0;
double fnum = 0;
- int i;
+ zend_long i;
int mode = 0;
char c, *s;
zend_long cutoff;
@@ -1029,7 +1029,7 @@ PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret)
num = num * base + c;
break;
} else {
- fnum = num;
+ fnum = (double)num;
mode = 1;
}
/* fall-through */
@@ -1234,10 +1234,10 @@ PHP_FUNCTION(base_convert)
RETURN_FALSE;
}
- if(_php_math_basetozval(number, frombase, &temp) == FAILURE) {
+ if(_php_math_basetozval(number, (int)frombase, &temp) == FAILURE) {
RETURN_FALSE;
}
- result = _php_math_zvaltobase(&temp, tobase TSRMLS_CC);
+ result = _php_math_zvaltobase(&temp, (int)tobase TSRMLS_CC);
RETVAL_STR(result);
}
/* }}} */
@@ -1284,15 +1284,15 @@ PHPAPI zend_string *_php_math_number_format_ex(double d, int dec, char *dec_poin
/* calculate the length of the return buffer */
if (dp) {
- integral = dp - tmpbuf->val;
+ integral = (int)(dp - tmpbuf->val);
} else {
/* no decimal point was found */
- integral = tmpbuf->len;
+ integral = (int)tmpbuf->len;
}
/* allow for thousand separators */
if (thousand_sep) {
- integral += thousand_sep_len * ((integral-1) / 3);
+ integral += (int)(thousand_sep_len * ((integral-1) / 3));
}
reslen = integral;
@@ -1301,7 +1301,7 @@ PHPAPI zend_string *_php_math_number_format_ex(double d, int dec, char *dec_poin
reslen += dec;
if (dec_point) {
- reslen += dec_point_len;
+ reslen += (int)dec_point_len;
}
}
@@ -1319,7 +1319,7 @@ PHPAPI zend_string *_php_math_number_format_ex(double d, int dec, char *dec_poin
* Take care, as the sprintf implementation may return less places than
* we requested due to internal buffer limitations */
if (dec) {
- int declen = dp ? s - dp : 0;
+ int declen = (int)(dp ? s - dp : 0);
int topad = dec > declen ? dec - declen : 0;
/* pad with '0's */
@@ -1391,7 +1391,7 @@ PHP_FUNCTION(number_format)
RETURN_STR(_php_math_number_format(num, 0, dec_point_chr, thousand_sep_chr));
break;
case 2:
- RETURN_STR(_php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr));
+ RETURN_STR(_php_math_number_format(num, (int)dec, dec_point_chr, thousand_sep_chr));
break;
case 4:
if (dec_point == NULL) {
@@ -1404,7 +1404,7 @@ PHP_FUNCTION(number_format)
thousand_sep_len = 1;
}
- RETVAL_STR(_php_math_number_format_ex(num, dec,
+ RETVAL_STR(_php_math_number_format_ex(num, (int)dec,
dec_point, dec_point_len, thousand_sep, thousand_sep_len));
break;
default:
diff --git a/ext/standard/pack.c b/ext/standard/pack.c
index 07206c8b7b..4af72c34b8 100644
--- a/ext/standard/pack.c
+++ b/ext/standard/pack.c
@@ -912,7 +912,7 @@ PHP_FUNCTION(unpack)
case 'P': {
int issigned = 0;
int *map = machine_endian_longlong_map;
- long v = 0;
+ zend_long v = 0;
if (type == 'q' || type == 'Q') {
issigned = input[inputpos + (machine_little_endian ? 7 : 0)] & 0x80;
@@ -927,9 +927,9 @@ PHP_FUNCTION(unpack)
v = php_unpack(&input[inputpos], 8, issigned, map);
if (type == 'q') {
- v = (signed long int) v;
+ v = (zend_long) v;
} else {
- v = (unsigned long int) v;
+ v = (zend_ulong) v;
}
add_assoc_long(return_value, n, v);
diff --git a/ext/standard/password.c b/ext/standard/password.c
index 0f75272d0e..c58c28ab3c 100644
--- a/ext/standard/password.c
+++ b/ext/standard/password.c
@@ -268,7 +268,7 @@ PHP_FUNCTION(password_verify)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &password, &password_len, &hash, &hash_len) == FAILURE) {
RETURN_FALSE;
}
- if ((ret = php_crypt(password, password_len, hash, hash_len)) == NULL) {
+ if ((ret = php_crypt(password, (int)password_len, hash, (int)hash_len)) == NULL) {
RETURN_FALSE;
}
@@ -298,7 +298,8 @@ PHP_FUNCTION(password_hash)
{
char *hash_format, *hash, *salt, *password;
zend_long algo = 0;
- size_t password_len = 0, hash_len;
+ size_t password_len = 0;
+ int hash_len;
size_t salt_len = 0, required_salt_len = 0, hash_format_len;
HashTable *options = 0;
zval *option_buffer;
@@ -344,7 +345,7 @@ PHP_FUNCTION(password_hash)
if (options && (option_buffer = zend_symtable_str_find(options, "salt", sizeof("salt")-1)) != NULL) {
char *buffer;
- int buffer_len_int = 0;
+ size_t buffer_len_int = 0;
size_t buffer_len;
switch (Z_TYPE_P(option_buffer)) {
case IS_STRING:
@@ -425,7 +426,7 @@ PHP_FUNCTION(password_hash)
/* This cast is safe, since both values are defined here in code and cannot overflow */
hash_len = (int) (hash_format_len + salt_len);
- if ((result = php_crypt(password, password_len, hash, hash_len)) == NULL) {
+ if ((result = php_crypt(password, (int)password_len, hash, hash_len)) == NULL) {
efree(hash);
RETURN_FALSE;
}
diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c
index 575e8fff98..1989a2eabc 100644
--- a/ext/standard/php_fopen_wrapper.c
+++ b/ext/standard/php_fopen_wrapper.c
@@ -80,7 +80,7 @@ static size_t php_stream_input_read(php_stream *stream, char *buf, size_t count
php_stream_input_t *input = stream->abstract;
size_t read;
- if (!SG(post_read) && SG(read_post_bytes) < input->position + count) {
+ if (!SG(post_read) && SG(read_post_bytes) < (int64_t)(input->position + count)) {
/* read requested data from SAPI */
int read_bytes = sapi_read_post_block(buf, count TSRMLS_CC);
@@ -323,7 +323,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa
return NULL;
}
- fd = dup(fildes_ori);
+ fd = dup((int)fildes_ori);
if (fd == -1) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
"Error duping file descriptor " ZEND_LONG_FMT "; possibly it doesn't exist: "
diff --git a/ext/standard/php_http.h b/ext/standard/php_http.h
index 0979348314..712e297fe3 100644
--- a/ext/standard/php_http.h
+++ b/ext/standard/php_http.h
@@ -25,9 +25,9 @@
#include "zend_smart_str.h"
PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
- const char *num_prefix, int num_prefix_len,
- const char *key_prefix, int key_prefix_len,
- const char *key_suffix, int key_suffix_len,
+ const char *num_prefix, size_t num_prefix_len,
+ const char *key_prefix, size_t key_prefix_len,
+ const char *key_suffix, size_t key_suffix_len,
zval *type, char *arg_sep, int enc_type TSRMLS_DC);
#define php_url_encode_hash(ht, formstr) php_url_encode_hash_ex((ht), (formstr), NULL, 0, NULL, 0, NULL, 0, NULL TSRMLS_CC)
diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c
index 66c0c2e7e3..d6a6f2be50 100644
--- a/ext/standard/proc_open.c
+++ b/ext/standard/proc_open.c
@@ -82,7 +82,7 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent
char **ep;
#endif
char *p;
- uint cnt, l, sizeenv=0;
+ size_t cnt, l, sizeenv=0;
HashTable *target_hash;
memset(&env, 0, sizeof(env));
@@ -109,7 +109,7 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent
/* first, we have to get the size of all the elements in the hash */
ZEND_HASH_FOREACH_STR_KEY_VAL(target_hash, string_key, element) {
zend_string *str = zval_get_string(element);
- uint el_len = str->len;
+ size_t el_len = str->len;
zend_string_release(str);
if (el_len == 0) {
@@ -512,7 +512,7 @@ PHP_FUNCTION(proc_open)
goto exit_fail;
}
- descriptors[ndesc].index = nindex;
+ descriptors[ndesc].index = (int)nindex;
if (Z_TYPE_P(descitem) == IS_RESOURCE) {
/* should be a stream - try and dup the descriptor */
@@ -526,7 +526,7 @@ PHP_FUNCTION(proc_open)
}
#ifdef PHP_WIN32
- descriptors[ndesc].childend = dup_fd_as_handle(fd);
+ descriptors[ndesc].childend = dup_fd_as_handle((int)fd);
if (descriptors[ndesc].childend == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to dup File-Handle for descriptor %d", nindex);
goto exit_fail;
@@ -621,8 +621,8 @@ PHP_FUNCTION(proc_open)
}
#ifdef PHP_WIN32
- descriptors[ndesc].childend = dup_fd_as_handle(fd);
- _close(fd);
+ descriptors[ndesc].childend = dup_fd_as_handle((int)fd);
+ _close((int)fd);
/* simulate the append mode by fseeking to the end of the file
this introduces a potential race-condition, but it is the best we can do, though */
diff --git a/ext/standard/quot_print.c b/ext/standard/quot_print.c
index c7eddc576b..441b65288c 100644
--- a/ext/standard/quot_print.c
+++ b/ext/standard/quot_print.c
@@ -53,7 +53,7 @@ static char php_hex2int(int c) /* {{{ */
PHPAPI zend_string *php_quot_print_decode(const unsigned char *str, size_t length, int replace_us_by_ws) /* {{{ */
{
- register unsigned int i;
+ register size_t i;
register unsigned const char *p1;
register unsigned char *p2;
register unsigned int h_nbl, l_nbl;
diff --git a/ext/standard/soundex.c b/ext/standard/soundex.c
index feb9a6780e..d882f5cab6 100644
--- a/ext/standard/soundex.c
+++ b/ext/standard/soundex.c
@@ -78,7 +78,7 @@ PHP_FUNCTION(soundex)
if (code >= 'A' && code <= 'Z') {
if (_small == 0) {
/* remember first valid char */
- soundex[_small++] = code;
+ soundex[_small++] = (char)code;
last = soundex_table[code - 'A'];
}
else {
@@ -88,7 +88,7 @@ PHP_FUNCTION(soundex)
code = soundex_table[code - 'A'];
if (code != last) {
if (code != 0) {
- soundex[_small++] = code;
+ soundex[_small++] = (char)code;
}
last = code;
}
diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c
index f864994d28..51e3c14e7a 100644
--- a/ext/standard/streamsfuncs.c
+++ b/ext/standard/streamsfuncs.c
@@ -60,7 +60,7 @@ PHP_FUNCTION(stream_socket_pair)
RETURN_FALSE;
}
- if (0 != socketpair(domain, type, protocol, pair)) {
+ if (0 != socketpair((int)domain, (int)type, (int)protocol, pair)) {
char errbuf[256];
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to create sockets: [%d]: %s",
php_socket_errno(), php_socket_strerror(php_socket_errno(), errbuf, sizeof(errbuf)));
@@ -90,7 +90,7 @@ PHP_FUNCTION(stream_socket_client)
char *host;
size_t host_len;
zval *zerrno = NULL, *zerrstr = NULL, *zcontext = NULL;
- double timeout = FG(default_socket_timeout);
+ double timeout = (double)FG(default_socket_timeout);
php_timeout_ull conv;
struct timeval tv;
char *hashkey = NULL;
@@ -206,7 +206,7 @@ PHP_FUNCTION(stream_socket_server)
}
stream = php_stream_xport_create(host, host_len, REPORT_ERRORS,
- STREAM_XPORT_SERVER | flags,
+ STREAM_XPORT_SERVER | (int)flags,
NULL, NULL, context, &errstr, &err);
if (stream == NULL) {
@@ -239,7 +239,7 @@ PHP_FUNCTION(stream_socket_server)
Accept a client connection from a server socket */
PHP_FUNCTION(stream_socket_accept)
{
- double timeout = FG(default_socket_timeout);
+ double timeout = (double)FG(default_socket_timeout);
zval *zpeername = NULL;
zend_string *peername = NULL;
php_timeout_ull conv;
@@ -340,7 +340,7 @@ PHP_FUNCTION(stream_socket_sendto)
}
}
- RETURN_LONG(php_stream_xport_sendto(stream, data, datalen, flags, target_addr ? &sa : NULL, sl TSRMLS_CC));
+ RETURN_LONG(php_stream_xport_sendto(stream, data, datalen, (int)flags, target_addr ? &sa : NULL, sl TSRMLS_CC));
}
/* }}} */
@@ -374,7 +374,7 @@ PHP_FUNCTION(stream_socket_recvfrom)
read_buf = zend_string_alloc(to_read, 0);
- recvd = php_stream_xport_recvfrom(stream, read_buf->val, to_read, flags, NULL, NULL,
+ recvd = php_stream_xport_recvfrom(stream, read_buf->val, to_read, (int)flags, NULL, NULL,
zremote ? &remote_addr : NULL
TSRMLS_CC);
@@ -410,7 +410,7 @@ PHP_FUNCTION(stream_get_contents)
if (desiredpos >= 0) {
int seek_res = 0;
- off_t position;
+ zend_off_t position;
position = php_stream_tell(stream);
if (position >= 0 && desiredpos > position) {
@@ -773,6 +773,10 @@ PHP_FUNCTION(stream_select)
RETURN_FALSE;
}
+#ifdef PHP_WIN32
+ tv.tv_sec = (long)(Z_LVAL_P(sec) + (usec / 1000000));
+ tv.tv_usec = (long)(usec % 1000000);
+#else
/* Solaris + BSD do not like microsecond values which are >= 1 sec */
if (usec > 999999) {
tv.tv_sec = Z_LVAL_P(sec) + (usec / 1000000);
@@ -781,7 +785,7 @@ PHP_FUNCTION(stream_select)
tv.tv_sec = Z_LVAL_P(sec);
tv.tv_usec = usec;
}
-
+#endif
tv_p = &tv;
}
@@ -1275,19 +1279,16 @@ PHP_FUNCTION(stream_get_line)
PHP_FUNCTION(stream_set_blocking)
{
zval *arg1;
- int block;
- zend_long arg2;
+ zend_long block;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &arg1, &arg2) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &arg1, &block) == FAILURE) {
return;
}
php_stream_from_zval(stream, arg1);
- block = arg2;
-
- if (php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block == 0 ? 0 : 1, NULL) == -1) {
+ if (php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block ? 1 : 0, NULL) == -1) {
RETURN_FALSE;
}
@@ -1313,6 +1314,16 @@ PHP_FUNCTION(stream_set_timeout)
php_stream_from_zval(stream, socket);
+#ifdef PHP_WIN32
+ t.tv_sec = (long)seconds;
+
+ if (argc == 3) {
+ t.tv_usec = (long)(microseconds % 1000000);
+ t.tv_sec +=(long)(microseconds / 1000000);
+ } else {
+ t.tv_usec = 0;
+ }
+#else
t.tv_sec = seconds;
if (argc == 3) {
@@ -1321,6 +1332,7 @@ PHP_FUNCTION(stream_set_timeout)
} else {
t.tv_usec = 0;
}
+#endif
if (PHP_STREAM_OPTION_RETURN_OK == php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &t)) {
RETURN_TRUE;
@@ -1485,7 +1497,7 @@ PHP_FUNCTION(stream_resolve_include_path)
return;
}
- resolved_path = zend_resolve_path(filename, filename_len TSRMLS_CC);
+ resolved_path = zend_resolve_path(filename, (int)filename_len TSRMLS_CC);
if (resolved_path) {
// TODO: avoid reallocation ???
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 706a3eb075..1d9948dcad 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -1663,12 +1663,10 @@ static int php_needle_char(zval *needle, char *target TSRMLS_DC)
return SUCCESS;
case IS_OBJECT:
{
- zval holder = *needle;
- zval_copy_ctor(&(holder));
- convert_to_long(&(holder));
- if(Z_TYPE(holder) != IS_LONG) {
- return FAILURE;
- }
+ zval holder;
+
+ ZVAL_LONG(&holder, zval_get_long(needle));
+
*target = (char)Z_LVAL(holder);
return SUCCESS;
}
@@ -2766,20 +2764,20 @@ PHP_FUNCTION(ucwords)
PHPAPI char *php_strtr(char *str, size_t len, char *str_from, char *str_to, size_t trlen)
{
size_t i;
- unsigned char xlat[256];
+ unsigned char xlat[256], j;
if ((trlen < 1) || (len < 1)) {
return str;
}
- for (i = 0; i < 256; xlat[i] = i, i++);
+ for (j = 0; j < 256; xlat[j] = j, j++);
for (i = 0; i < trlen; i++) {
- xlat[(unsigned char) str_from[i]] = str_to[i];
+ xlat[(size_t) str_from[i]] = str_to[i];
}
for (i = 0; i < len; i++) {
- str[i] = xlat[(unsigned char) str[i]];
+ str[i] = xlat[(size_t) str[i]];
}
return str;
@@ -4185,7 +4183,7 @@ PHP_FUNCTION(setlocale)
#ifdef HAVE_SETLOCALE
if (Z_TYPE_P(pcategory) == IS_LONG) {
- cat = Z_LVAL_P(pcategory);
+ cat = (int)Z_LVAL_P(pcategory);
} else {
/* FIXME: The following behaviour should be removed. */
char *category;
@@ -4896,14 +4894,14 @@ PHP_FUNCTION(localeconv)
localeconv_r( &currlocdata );
/* Grab the grouping data out of the array */
- len = strlen(currlocdata.grouping);
+ len = (int)strlen(currlocdata.grouping);
for (i = 0; i < len; i++) {
add_index_long(&grouping, i, currlocdata.grouping[i]);
}
/* Grab the monetary grouping data out of the array */
- len = strlen(currlocdata.mon_grouping);
+ len = (int)strlen(currlocdata.mon_grouping);
for (i = 0; i < len; i++) {
add_index_long(&mon_grouping, i, currlocdata.mon_grouping[i]);
@@ -5346,7 +5344,7 @@ PHP_FUNCTION(str_split)
return;
}
- array_init_size(return_value, ((str->len - 1) / split_length) + 1);
+ array_init_size(return_value, (uint32_t)(((str->len - 1) / split_length) + 1));
n_reg_segments = str->len / split_length;
p = str->val;
diff --git a/ext/standard/tests/serialize/bug68044.phpt b/ext/standard/tests/serialize/bug68044.phpt
index 031e44e149..f8ef937b1e 100644
--- a/ext/standard/tests/serialize/bug68044.phpt
+++ b/ext/standard/tests/serialize/bug68044.phpt
@@ -6,7 +6,7 @@ Bug #68044 Integer overflow in unserialize() (32-bits only)
?>
===DONE==
--EXPECTF--
-Warning: Insufficient data for unserializing - %d required, 1 present in %s/bug68044.php on line 2
+Warning: Insufficient data for unserializing - %d required, 1 present in %s%ebug68044.php on line 2
-Notice: unserialize(): Error at offset 32 of 33 bytes in %s/bug68044.php on line 2
+Notice: unserialize(): Error at offset 32 of 33 bytes in %s%ebug68044.php on line 2
===DONE==
diff --git a/ext/standard/type.c b/ext/standard/type.c
index 67d5ed1e75..a773e6c53c 100644
--- a/ext/standard/type.c
+++ b/ext/standard/type.c
@@ -156,7 +156,7 @@ PHP_FUNCTION(intval)
#endif
RETVAL_ZVAL(num, 1, 0);
- convert_to_long_base(return_value, base);
+ convert_to_long_base(return_value, (int)base);
}
/* }}} */
diff --git a/ext/standard/url.c b/ext/standard/url.c
index 4fb2c73edb..7d408ef88a 100644
--- a/ext/standard/url.c
+++ b/ext/standard/url.c
@@ -61,7 +61,7 @@ PHPAPI void php_url_free(php_url *theurl)
/* {{{ php_replace_controlchars
*/
-PHPAPI char *php_replace_controlchars_ex(char *str, int len)
+PHPAPI char *php_replace_controlchars_ex(char *str, size_t len)
{
unsigned char *s = (unsigned char *)str;
unsigned char *e = (unsigned char *)str + len;
@@ -94,7 +94,7 @@ PHPAPI php_url *php_url_parse(char const *str)
/* {{{ php_url_parse
*/
-PHPAPI php_url *php_url_parse_ex(char const *str, int length)
+PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
{
char port_buf[6];
php_url *ret = ecalloc(1, sizeof(php_url));
@@ -481,7 +481,7 @@ static unsigned char hexchars[] = "0123456789ABCDEF";
/* {{{ php_url_encode
*/
-PHPAPI zend_string *php_url_encode(char const *s, int len)
+PHPAPI zend_string *php_url_encode(char const *s, size_t len)
{
register unsigned char c;
unsigned char *to;
@@ -572,7 +572,7 @@ PHP_FUNCTION(urldecode)
/* {{{ php_url_decode
*/
-PHPAPI int php_url_decode(char *str, int len)
+PHPAPI size_t php_url_decode(char *str, size_t len)
{
char *dest = str;
char *data = str;
@@ -603,7 +603,7 @@ PHPAPI int php_url_decode(char *str, int len)
/* {{{ php_raw_url_encode
*/
-PHPAPI zend_string *php_raw_url_encode(char const *s, int len)
+PHPAPI zend_string *php_raw_url_encode(char const *s, size_t len)
{
register int x, y;
zend_string *str;
@@ -679,7 +679,7 @@ PHP_FUNCTION(rawurldecode)
/* {{{ php_raw_url_decode
*/
-PHPAPI int php_raw_url_decode(char *str, int len)
+PHPAPI size_t php_raw_url_decode(char *str, size_t len)
{
char *dest = str;
char *data = str;
diff --git a/ext/standard/url.h b/ext/standard/url.h
index 4d7a1f5b56..ec2676eaee 100644
--- a/ext/standard/url.h
+++ b/ext/standard/url.h
@@ -33,11 +33,12 @@ typedef struct php_url {
PHPAPI void php_url_free(php_url *theurl);
PHPAPI php_url *php_url_parse(char const *str);
-PHPAPI php_url *php_url_parse_ex(char const *str, int length);
-PHPAPI int php_url_decode(char *str, int len); /* return value: length of decoded string */
-PHPAPI int php_raw_url_decode(char *str, int len); /* return value: length of decoded string */
-PHPAPI zend_string *php_url_encode(char const *s, int len);
-PHPAPI zend_string *php_raw_url_encode(char const *s, int len);
+PHPAPI php_url *php_url_parse_ex(char const *str, size_t length);
+PHPAPI size_t php_url_decode(char *str, size_t len); /* return value: length of decoded string */
+PHPAPI size_t php_raw_url_decode(char *str, size_t len); /* return value: length of decoded string */
+PHPAPI zend_string *php_url_encode(char const *s, size_t len);
+PHPAPI zend_string *php_raw_url_encode(char const *s, size_t len);
+PHPAPI char *php_replace_controlchars_ex(char *str, size_t len);
PHP_FUNCTION(parse_url);
PHP_FUNCTION(urlencode);
diff --git a/ext/standard/uuencode.c b/ext/standard/uuencode.c
index 6582e7de65..ea171a658a 100644
--- a/ext/standard/uuencode.c
+++ b/ext/standard/uuencode.c
@@ -83,7 +83,7 @@ PHPAPI zend_string *php_uuencode(char *src, size_t src_len) /* {{{ */
ee = e;
len = ee - s;
if (len % 3) {
- ee = s + (int) (floor(len / 3) * 3);
+ ee = s + (int) (floor((double)len / 3) * 3);
}
}
*p++ = PHP_UU_ENC(len);
@@ -173,7 +173,8 @@ PHPAPI zend_string *php_uudecode(char *src, size_t src_len) /* {{{ */
s++;
}
- if ((len = total_len > (p - dest->val))) {
+ assert(p >= dest->val);
+ if ((len = total_len > (size_t)(p - dest->val))) {
*p++ = PHP_UU_DEC(*s) << 2 | PHP_UU_DEC(*(s + 1)) >> 4;
if (len > 1) {
*p++ = PHP_UU_DEC(*(s + 1)) << 4 | PHP_UU_DEC(*(s + 2)) >> 2;
diff --git a/ext/standard/var.c b/ext/standard/var.c
index 6e5bd703d3..4f0bd24bdc 100644
--- a/ext/standard/var.c
+++ b/ext/standard/var.c
@@ -389,7 +389,7 @@ PHP_FUNCTION(debug_zval_dump)
#define buffer_append_spaces(buf, num_spaces) \
do { \
char *tmp_spaces; \
- int tmp_spaces_len; \
+ size_t tmp_spaces_len; \
tmp_spaces_len = spprintf(&tmp_spaces, 0,"%*c", num_spaces, ' '); \
smart_str_appendl(buf, tmp_spaces, tmp_spaces_len); \
efree(tmp_spaces); \
@@ -594,7 +594,7 @@ PHP_FUNCTION(var_export)
static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_data_t var_hash TSRMLS_DC);
-static inline uint32_t php_add_var_hash(php_serialize_data_t data, zval *var TSRMLS_DC) /* {{{ */
+static inline zend_long php_add_var_hash(php_serialize_data_t data, zval *var TSRMLS_DC) /* {{{ */
{
zval *zv;
zend_ulong key;
@@ -772,7 +772,7 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt
static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_data_t var_hash TSRMLS_DC) /* {{{ */
{
- uint32_t var_already;
+ zend_long var_already;
HashTable *myht;
if (EG(exception)) {
@@ -816,7 +816,7 @@ again:
smart_str_appendl(buf, "d:", 2);
s = (char *) safe_emalloc(PG(serialize_precision), 1, MAX_LENGTH_OF_DOUBLE + 1);
- php_gcvt(Z_DVAL_P(struc), PG(serialize_precision), '.', 'E', s);
+ php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', s);
smart_str_appends(buf, s);
smart_str_appendc(buf, ';');
efree(s);
diff --git a/ext/tidy/tidy.c b/ext/tidy/tidy.c
index c8f1ec665e..5d334069a1 100644
--- a/ext/tidy/tidy.c
+++ b/ext/tidy/tidy.c
@@ -497,7 +497,9 @@ static void TIDY_CALL php_tidy_panic(ctmbstr msg)
static int _php_tidy_set_tidy_opt(TidyDoc doc, char *optname, zval *value TSRMLS_DC)
{
TidyOption opt = tidyGetOptionByName(doc, optname);
- zval conv = *value;
+ zval conv;
+
+ ZVAL_COPY_VALUE(&conv, value);
if (!opt) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown Tidy Configuration Option '%s'", optname);
diff --git a/main/snprintf.c b/main/snprintf.c
index 062ccc4eee..b9f781346c 100644
--- a/main/snprintf.c
+++ b/main/snprintf.c
@@ -311,7 +311,7 @@ PHPAPI char *php_gcvt(double value, int ndigit, char dec_point, char exponent, c
* is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
*/
/* char * ap_php_conv_10() {{{ */
-char * ap_php_conv_10(register wide_int num, register bool_int is_unsigned,
+PHPAPI char * ap_php_conv_10(register wide_int num, register bool_int is_unsigned,
register bool_int * is_negative, char *buf_end, register size_t *len)
{
register char *p = buf_end;
@@ -474,7 +474,7 @@ PHPAPI char * php_conv_fp(register char format, register double num,
* which is a pointer to the END of the buffer + 1 (i.e. if the buffer
* is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
*/
-char * ap_php_conv_p2(register u_wide_int num, register int nbits, char format, char *buf_end, register size_t *len) /* {{{ */
+PHPAPI char * ap_php_conv_p2(register u_wide_int num, register int nbits, char format, char *buf_end, register size_t *len) /* {{{ */
{
register int mask = (1 << nbits) - 1;
register char *p = buf_end;
diff --git a/main/snprintf.h b/main/snprintf.h
index d133ad7aaa..789ab7d41a 100644
--- a/main/snprintf.h
+++ b/main/snprintf.h
@@ -153,10 +153,10 @@ typedef enum {
typedef WIDE_INT wide_int;
typedef unsigned WIDE_INT u_wide_int;
-extern char * ap_php_conv_10(register wide_int num, register bool_int is_unsigned,
+PHPAPI char * ap_php_conv_10(register wide_int num, register bool_int is_unsigned,
register bool_int * is_negative, char *buf_end, register size_t *len);
-extern char * ap_php_conv_p2(register u_wide_int num, register int nbits,
+PHPAPI char * ap_php_conv_p2(register u_wide_int num, register int nbits,
char format, char *buf_end, register size_t *len);
/* The maximum precision that's allowed for float conversion. Does not include
diff --git a/main/streams/php_stream_transport.h b/main/streams/php_stream_transport.h
index 9674314c49..2d076064cf 100644
--- a/main/streams/php_stream_transport.h
+++ b/main/streams/php_stream_transport.h
@@ -101,13 +101,13 @@ enum php_stream_xport_send_recv_flags {
/* Similar to recv() system call; read data from the stream, optionally
* peeking, optionally retrieving OOB data */
PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t buflen,
- long flags, void **addr, socklen_t *addrlen,
+ int flags, void **addr, socklen_t *addrlen,
zend_string **textaddr TSRMLS_DC);
/* Similar to send() system call; send data to the stream, optionally
* sending it as OOB data */
PHPAPI int php_stream_xport_sendto(php_stream *stream, const char *buf, size_t buflen,
- long flags, void *addr, socklen_t addrlen TSRMLS_DC);
+ int flags, void *addr, socklen_t addrlen TSRMLS_DC);
typedef enum {
STREAM_SHUT_RD,
@@ -146,9 +146,9 @@ typedef struct _php_stream_xport_param {
struct sockaddr *addr;
char *buf;
size_t buflen;
- zend_long flags;
socklen_t addrlen;
int backlog;
+ int flags;
} inputs;
struct {
php_stream *client;
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c
index 28328c3cd5..7432b7c49e 100644
--- a/main/streams/plain_wrapper.c
+++ b/main/streams/plain_wrapper.c
@@ -41,6 +41,7 @@
#include "php_streams_int.h"
#ifdef PHP_WIN32
# include "win32/winutil.h"
+# include "win32/time.h"
#endif
#define php_stream_fopen_from_fd_int(fd, mode, persistent_id) _php_stream_fopen_from_fd_int((fd), (mode), (persistent_id) STREAMS_CC TSRMLS_CC)
diff --git a/main/streams/transports.c b/main/streams/transports.c
index a75f77c5bd..8fd0b91d35 100644
--- a/main/streams/transports.c
+++ b/main/streams/transports.c
@@ -393,7 +393,7 @@ PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate TSRML
/* Similar to recv() system call; read data from the stream, optionally
* peeking, optionally retrieving OOB data */
PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t buflen,
- long flags, void **addr, socklen_t *addrlen, zend_string **textaddr
+ int flags, void **addr, socklen_t *addrlen, zend_string **textaddr
TSRMLS_DC)
{
php_stream_xport_param param;
@@ -462,7 +462,7 @@ PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t bufle
/* Similar to send() system call; send data to the stream, optionally
* sending it as OOB data */
PHPAPI int php_stream_xport_sendto(php_stream *stream, const char *buf, size_t buflen,
- long flags, void *addr, socklen_t addrlen TSRMLS_DC)
+ int flags, void *addr, socklen_t addrlen TSRMLS_DC)
{
php_stream_xport_param param;
int ret = 0;
diff --git a/sapi/phpdbg/config.m4 b/sapi/phpdbg/config.m4
index d78a439af0..528abb5822 100644
--- a/sapi/phpdbg/config.m4
+++ b/sapi/phpdbg/config.m4
@@ -3,12 +3,15 @@ dnl $Id$
dnl
PHP_ARG_ENABLE(phpdbg, for phpdbg support,
-[ --enable-phpdbg Build phpdbg], no, no)
+[ --enable-phpdbg Build phpdbg], no, no)
+
+PHP_ARG_ENABLE(phpdbg-webhelper, for phpdbg web SAPI support,
+[ --enable-phpdbg-webhelper Build phpdbg web SAPI support], yes, yes)
PHP_ARG_ENABLE(phpdbg-debug, for phpdbg debug build,
-[ --enable-phpdbg-debug Build phpdbg in debug mode], no, no)
+[ --enable-phpdbg-debug Build phpdbg in debug mode], no, no)
-if test "$PHP_PHPDBG" != "no"; then
+if test "$BUILD_PHPDBG" == "" && test "$PHP_PHPDBG" != "no"; then
AC_HEADER_TIOCGWINSZ
AC_DEFINE(HAVE_PHPDBG, 1, [ ])
@@ -18,8 +21,19 @@ if test "$PHP_PHPDBG" != "no"; then
AC_DEFINE(PHPDBG_DEBUG, 0, [ ])
fi
+ if test "$PHP_PHPDBG_WEBHELPER" != "no"; then
+ if ! test -d ext/phpdbg_webhelper; then
+ ln -s ../sapi/phpdbg ext/phpdbg_webhelper
+ fi
+ if test "$PHP_JSON" != "no"; then
+ PHP_NEW_EXTENSION(phpdbg_webhelper, phpdbg_rinit_hook.c phpdbg_webdata_transfer.c, $ext_shared)
+ else
+ AC_MSG_ERROR(Webhelper extension of phpdbg needs json enabled)
+ fi
+ fi
+
PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE"
- PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c"
+ PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c phpdbg_eol.c phpdbg_out.c"
if test "$PHP_READLINE" != "no" -o "$PHP_LIBEDIT" != "no"; then
PHPDBG_EXTRA_LIBS="$PHP_READLINE_LIBS"
diff --git a/sapi/phpdbg/config.w32 b/sapi/phpdbg/config.w32
index 17e15b6ced..6f0bd8f811 100644
--- a/sapi/phpdbg/config.w32
+++ b/sapi/phpdbg/config.w32
@@ -1,7 +1,11 @@
ARG_ENABLE('phpdbg', 'Build phpdbg', 'no');
ARG_ENABLE('phpdbgs', 'Build phpdbg shared', 'no');
-PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_win.c phpdbg_btree.c phpdbg_parser.c phpdbg_lexer.c';
+PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c ' +
+ 'phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c ' +
+ 'phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_win.c phpdbg_btree.c '+
+ 'phpdbg_parser.c phpdbg_lexer.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c ' +
+ 'phpdbg_sigio_win32.c phpdbg_eol.c phpdbg_out.c';
PHPDBG_DLL='php' + PHP_VERSION + 'phpdbg.dll';
PHPDBG_EXE='phpdbg.exe';
@@ -9,6 +13,7 @@ if (PHP_PHPDBG == "yes") {
SAPI('phpdbg', PHPDBG_SOURCES, PHPDBG_EXE);
ADD_FLAG("LIBS_PHPDBG", "ws2_32.lib user32.lib");
ADD_FLAG("CFLAGS_PHPDBG", "/D YY_NO_UNISTD_H");
+ ADD_FLAG("LDFLAGS_PHPDBG", "/stack:8388608");
}
if (PHP_PHPDBGS == "yes") {
diff --git a/sapi/phpdbg/phpdbg.1 b/sapi/phpdbg/phpdbg.1
index b6c26df565..5e4d144c83 100644
--- a/sapi/phpdbg/phpdbg.1
+++ b/sapi/phpdbg/phpdbg.1
@@ -7,7 +7,7 @@ phpdbg \- The interactive PHP debugger
[\fB\-e\fIFILE\fR]
.SH DESCRIPTION
.B phpdbg
-a lightweight, powerful, easy to use debugging platform for PHP7.
+a lightweight, powerful, easy to use debugging platform for PHP5.
.SH OPTIONS
The following switches are implemented (just like cli SAPI):
.TP
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c
index 4388b4f86d..d70e512751 100644
--- a/sapi/phpdbg/phpdbg.c
+++ b/sapi/phpdbg/phpdbg.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -28,7 +28,9 @@
#include "phpdbg_list.h"
#include "phpdbg_utils.h"
#include "phpdbg_set.h"
+#include "phpdbg_io.h"
#include "zend_alloc.h"
+#include "phpdbg_eol.h"
/* {{{ remote console headers */
#ifndef _WIN32
@@ -36,6 +38,7 @@
# include <sys/select.h>
# include <sys/time.h>
# include <sys/types.h>
+# include <sys/poll.h>
# include <netinet/in.h>
# include <unistd.h>
# include <arpa/inet.h>
@@ -43,6 +46,20 @@
ZEND_DECLARE_MODULE_GLOBALS(phpdbg);
+static PHP_INI_MH(OnUpdateEol)
+{
+ if (!new_value) {
+ return FAILURE;
+ }
+
+ return phpdbg_eol_global_update(new_value->val TSRMLS_CC);
+}
+
+PHP_INI_BEGIN()
+ STD_PHP_INI_ENTRY("phpdbg.path", "", PHP_INI_SYSTEM | PHP_INI_PERDIR, OnUpdateString, socket_path, zend_phpdbg_globals, phpdbg_globals)
+ STD_PHP_INI_ENTRY("phpdbg.eol", "2", PHP_INI_ALL, OnUpdateEol, socket_path, zend_phpdbg_globals, phpdbg_globals)
+PHP_INI_END()
+
static zend_bool phpdbg_booted = 0;
#if PHP_VERSION_ID >= 50500
@@ -63,20 +80,40 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
pg->exec = NULL;
pg->exec_len = 0;
pg->buffer = NULL;
+ pg->last_was_newline = 1;
pg->ops = NULL;
pg->vmret = 0;
+ pg->in_execution = 0;
pg->bp_count = 0;
pg->flags = PHPDBG_DEFAULT_FLAGS;
pg->oplog = NULL;
- pg->io[PHPDBG_STDIN] = NULL;
- pg->io[PHPDBG_STDOUT] = NULL;
- pg->io[PHPDBG_STDERR] = NULL;
+ memset(pg->io, 0, sizeof(pg->io));
pg->frame.num = 0;
+ pg->sapi_name_ptr = NULL;
+ pg->socket_fd = -1;
+ pg->socket_server_fd = -1;
+
+ pg->req_id = 0;
+ pg->err_buf.active = 0;
+ pg->err_buf.type = 0;
+
+ pg->input_buflen = 0;
+ pg->sigsafe_mem.mem = NULL;
+ pg->sigsegv_bailout = NULL;
+
+#ifdef PHP_WIN32
+ pg->sigio_watcher_thread = INVALID_HANDLE_VALUE;
+ memset(&pg->swd, 0, sizeof(struct win32_sigio_watcher_data));
+#endif
+
+ pg->eol = PHPDBG_EOL_LF;
} /* }}} */
static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
{
ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL);
+ REGISTER_INI_ENTRIES();
+
#if PHP_VERSION_ID >= 50500
zend_execute_old = zend_execute_ex;
zend_execute_ex = phpdbg_execute_ex;
@@ -86,7 +123,7 @@ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
#endif
REGISTER_STRINGL_CONSTANT("PHPDBG_VERSION", PHPDBG_VERSION, sizeof(PHPDBG_VERSION)-1, CONST_CS|CONST_PERSISTENT);
-
+
REGISTER_LONG_CONSTANT("PHPDBG_FILE", FILE_PARAM, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PHPDBG_METHOD", METHOD_PARAM, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PHPDBG_LINENO", NUMERIC_PARAM, CONST_CS|CONST_PERSISTENT);
@@ -99,50 +136,49 @@ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
return SUCCESS;
} /* }}} */
-static void php_phpdbg_destroy_bp_file(void *brake) /* {{{ */
+static void php_phpdbg_destroy_bp_file(zval *brake) /* {{{ */
{
- zend_hash_destroy((HashTable*)brake);
+ zend_hash_destroy(Z_ARRVAL_P(brake));
} /* }}} */
-static void php_phpdbg_destroy_bp_symbol(void *brake) /* {{{ */
+static void php_phpdbg_destroy_bp_symbol(zval *brake) /* {{{ */
{
- efree((char*)((phpdbg_breaksymbol_t*)brake)->symbol);
+ efree((char *) ((phpdbg_breaksymbol_t *) Z_PTR_P(brake))->symbol);
} /* }}} */
-static void php_phpdbg_destroy_bp_opcode(void *brake) /* {{{ */
+static void php_phpdbg_destroy_bp_opcode(zval *brake) /* {{{ */
{
- efree((char*)((phpdbg_breakop_t*)brake)->name);
+ efree((char *) ((phpdbg_breakop_t *) Z_PTR_P(brake))->name);
} /* }}} */
-static void php_phpdbg_destroy_bp_methods(void *brake) /* {{{ */
+static void php_phpdbg_destroy_bp_methods(zval *brake) /* {{{ */
{
- zend_hash_destroy((HashTable*)brake);
+ zend_hash_destroy(Z_ARRVAL_P(brake));
} /* }}} */
-static void php_phpdbg_destroy_bp_condition(void *data) /* {{{ */
+static void php_phpdbg_destroy_bp_condition(zval *data) /* {{{ */
{
- phpdbg_breakcond_t *brake = (phpdbg_breakcond_t*) data;
+ phpdbg_breakcond_t *brake = (phpdbg_breakcond_t *) Z_PTR_P(data);
if (brake) {
if (brake->ops) {
TSRMLS_FETCH();
- destroy_op_array(
- brake->ops TSRMLS_CC);
+ destroy_op_array(brake->ops TSRMLS_CC);
efree(brake->ops);
}
- efree((char*)brake->code);
+ efree((char*) brake->code);
}
} /* }}} */
-static void php_phpdbg_destroy_registered(void *data) /* {{{ */
+static void php_phpdbg_destroy_registered(zval *data) /* {{{ */
{
- zend_function *function = (zend_function*) data;
+ zend_function *function = (zend_function *) Z_PTR_P(data);
+
TSRMLS_FETCH();
- destroy_zend_function(
- function TSRMLS_CC);
+ destroy_zend_function(function TSRMLS_CC);
} /* }}} */
@@ -179,6 +215,7 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]);
zend_hash_destroy(&PHPDBG_G(seek));
zend_hash_destroy(&PHPDBG_G(registered));
+ zend_hash_destroy(&PHPDBG_G(file_sources));
zend_hash_destroy(&PHPDBG_G(watchpoints));
zend_llist_destroy(&PHPDBG_G(watchlist_mem));
@@ -186,7 +223,7 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
efree(PHPDBG_G(buffer));
PHPDBG_G(buffer) = NULL;
}
-
+
if (PHPDBG_G(exec)) {
efree(PHPDBG_G(exec));
PHPDBG_G(exec) = NULL;
@@ -224,10 +261,9 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
If the request to set the context fails, boolean false is returned, and an E_WARNING raised */
static PHP_FUNCTION(phpdbg_exec)
{
- char *exec = NULL;
- int exec_len = 0;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &exec, &exec_len) == FAILURE) {
+ zend_string *exec;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &exec) == FAILURE) {
return;
}
@@ -235,27 +271,26 @@ static PHP_FUNCTION(phpdbg_exec)
struct stat sb;
zend_bool result = 1;
- if (VCWD_STAT(exec, &sb) != FAILURE) {
+ if (VCWD_STAT(exec->val, &sb) != FAILURE) {
if (sb.st_mode & (S_IFREG|S_IFLNK)) {
if (PHPDBG_G(exec)) {
- ZVAL_STRINGL(return_value, PHPDBG_G(exec), PHPDBG_G(exec_len), 1);
+ ZVAL_STRINGL(return_value, PHPDBG_G(exec), PHPDBG_G(exec_len));
efree(PHPDBG_G(exec));
result = 0;
}
- PHPDBG_G(exec) = estrndup(exec, exec_len);
- PHPDBG_G(exec_len) = exec_len;
+ PHPDBG_G(exec) = estrndup(exec->val, exec->len);
+ PHPDBG_G(exec_len) = exec->len;
- if (result)
+ if (result) {
ZVAL_BOOL(return_value, 1);
+ }
} else {
- zend_error(
- E_WARNING, "Failed to set execution context (%s), not a regular file or symlink", exec);
+ zend_error(E_WARNING, "Failed to set execution context (%s), not a regular file or symlink", exec);
ZVAL_BOOL(return_value, 0);
}
} else {
- zend_error(
- E_WARNING, "Failed to set execution context (%s) the file does not exist", exec);
+ zend_error(E_WARNING, "Failed to set execution context (%s) the file does not exist", exec);
ZVAL_BOOL(return_value, 0);
}
@@ -279,13 +314,8 @@ static PHP_FUNCTION(phpdbg_break)
phpdbg_parse_param(expr, expr_len, &param TSRMLS_CC);
phpdbg_do_break(&param TSRMLS_CC);
phpdbg_clear_param(&param TSRMLS_CC);
-
- } else if (EG(current_execute_data) && EG(active_op_array)) {
- zend_ulong opline_num = (EG(current_execute_data)->opline -
- EG(active_op_array)->opcodes);
-
- phpdbg_set_breakpoint_opline_ex(
- &EG(active_op_array)->opcodes[opline_num+1] TSRMLS_CC);
+ } else if (EG(current_execute_data) && EG(current_execute_data)->func->type != ZEND_INTERNAL_FUNCTION) {
+ phpdbg_set_breakpoint_opline_ex((phpdbg_opline_ptr_t) EG(current_execute_data)->opline + 1 TSRMLS_CC);
}
} /* }}} */
@@ -426,7 +456,12 @@ static void php_sapi_phpdbg_log_message(char *message TSRMLS_DC) /* {{{ */
* We must not request TSRM before being boot
*/
if (phpdbg_booted) {
- phpdbg_error("%s", message);
+ if (PHPDBG_G(flags) & PHPDBG_IN_EVAL) {
+ phpdbg_error("eval", "msg=\"%s\"", "%s", message);
+ return;
+ }
+
+ phpdbg_error("php", "msg=\"%s\"", "%s", message);
switch (PG(last_error_type)) {
case E_ERROR:
@@ -436,17 +471,14 @@ static void php_sapi_phpdbg_log_message(char *message TSRMLS_DC) /* {{{ */
case E_PARSE:
case E_RECOVERABLE_ERROR:
if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) {
- phpdbg_list_file(
- zend_get_executed_filename(TSRMLS_C),
- 3,
- zend_get_executed_lineno(TSRMLS_C)-1,
- zend_get_executed_lineno(TSRMLS_C)
- TSRMLS_CC
- );
+ const char *file_char = zend_get_executed_filename(TSRMLS_C);
+ zend_string *file = zend_string_init(file_char, strlen(file_char), 0);
+ phpdbg_list_file(file, 3, zend_get_executed_lineno(TSRMLS_C) - 1, zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC);
+ efree(file);
}
do {
- switch (phpdbg_interactive(TSRMLS_C)) {
+ switch (phpdbg_interactive(1 TSRMLS_CC)) {
case PHPDBG_LEAVE:
case PHPDBG_FINISH:
case PHPDBG_UNTIL:
@@ -473,8 +505,8 @@ static int php_sapi_phpdbg_deactivate(TSRMLS_D) /* {{{ */
static void php_sapi_phpdbg_register_vars(zval *track_vars_array TSRMLS_DC) /* {{{ */
{
- unsigned int len;
- char *docroot = "";
+ size_t len;
+ char *docroot = "";
/* In phpdbg mode, we consider the environment to be a part of the server variables
*/
@@ -482,43 +514,67 @@ static void php_sapi_phpdbg_register_vars(zval *track_vars_array TSRMLS_DC) /* {
if (PHPDBG_G(exec)) {
len = PHPDBG_G(exec_len);
- if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF",
- &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
- php_register_variable("PHP_SELF", PHPDBG_G(exec),
- track_vars_array TSRMLS_CC);
+ if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
+ php_register_variable("PHP_SELF", PHPDBG_G(exec), track_vars_array TSRMLS_CC);
}
- if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_NAME",
- &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
- php_register_variable("SCRIPT_NAME", PHPDBG_G(exec),
- track_vars_array TSRMLS_CC);
+ if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_NAME", &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
+ php_register_variable("SCRIPT_NAME", PHPDBG_G(exec), track_vars_array TSRMLS_CC);
}
- if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_FILENAME",
- &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
- php_register_variable("SCRIPT_FILENAME", PHPDBG_G(exec),
- track_vars_array TSRMLS_CC);
+ if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_FILENAME", &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
+ php_register_variable("SCRIPT_FILENAME", PHPDBG_G(exec), track_vars_array TSRMLS_CC);
}
- if (sapi_module.input_filter(PARSE_SERVER, "PATH_TRANSLATED",
- &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
- php_register_variable("PATH_TRANSLATED", PHPDBG_G(exec),
- track_vars_array TSRMLS_CC);
+ if (sapi_module.input_filter(PARSE_SERVER, "PATH_TRANSLATED", &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
+ php_register_variable("PATH_TRANSLATED", PHPDBG_G(exec), track_vars_array TSRMLS_CC);
}
}
- /* any old docroot will doo */
- len = 0U;
- if (sapi_module.input_filter(PARSE_SERVER, "DOCUMENT_ROOT",
- &docroot, len, &len TSRMLS_CC)) {
+ /* any old docroot will do */
+ len = 0;
+ if (sapi_module.input_filter(PARSE_SERVER, "DOCUMENT_ROOT", &docroot, len, &len TSRMLS_CC)) {
php_register_variable("DOCUMENT_ROOT", docroot, track_vars_array TSRMLS_CC);
}
}
/* }}} */
-static inline int php_sapi_phpdbg_ub_write(const char *message, unsigned int length TSRMLS_DC) /* {{{ */
+static inline size_t php_sapi_phpdbg_ub_write(const char *message, size_t length TSRMLS_DC) /* {{{ */
{
- return phpdbg_write("%s", message);
+ if (PHPDBG_G(socket_fd) != -1 && !(PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE)) {
+ send(PHPDBG_G(socket_fd), message, length, 0);
+ }
+ return phpdbg_script(P_STDOUT, "%.*s", length, message);
} /* }}} */
+/* beginning of struct, see main/streams/plain_wrapper.c line 111 */
+typedef struct {
+ FILE *file;
+ int fd;
+} php_stdio_stream_data;
+
+static size_t phpdbg_stdiop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) {
+ php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract;
+
+ while (data->fd >= 0) {
+ struct stat stat[3];
+ memset(stat, 0, sizeof(stat));
+ if (((fstat(fileno(stderr), &stat[2]) < 0) & (fstat(fileno(stdout), &stat[0]) < 0)) | (fstat(data->fd, &stat[1]) < 0)) {
+ break;
+ }
+
+ if (stat[0].st_dev == stat[1].st_dev && stat[0].st_ino == stat[1].st_ino) {
+ phpdbg_script(P_STDOUT, "%.*s", (int) count, buf);
+ return count;
+ }
+ if (stat[2].st_dev == stat[1].st_dev && stat[2].st_ino == stat[1].st_ino) {
+ phpdbg_script(P_STDERR, "%.*s", (int) count, buf);
+ return count;
+ }
+ break;
+ }
+
+ return PHPDBG_G(php_stdiop_write)(stream, buf, count TSRMLS_CC);
+}
+
#if PHP_VERSION_ID >= 50700
static inline void php_sapi_phpdbg_flush(void *context TSRMLS_DC) /* {{{ */
{
@@ -528,29 +584,24 @@ static inline void php_sapi_phpdbg_flush(void *context) /* {{{ */
TSRMLS_FETCH();
#endif
- fflush(PHPDBG_G(io)[PHPDBG_STDOUT]);
+ if (!phpdbg_active_sigsafe_mem(TSRMLS_C)) {
+ fflush(PHPDBG_G(io)[PHPDBG_STDOUT].ptr);
+ }
} /* }}} */
/* copied from sapi/cli/php_cli.c cli_register_file_handles */
static void phpdbg_register_file_handles(TSRMLS_D) /* {{{ */
{
- zval *zin, *zout, *zerr;
+ zval zin, zout, zerr;
php_stream *s_in, *s_out, *s_err;
php_stream_context *sc_in=NULL, *sc_out=NULL, *sc_err=NULL;
zend_constant ic, oc, ec;
- MAKE_STD_ZVAL(zin);
- MAKE_STD_ZVAL(zout);
- MAKE_STD_ZVAL(zerr);
-
s_in = php_stream_open_wrapper_ex("php://stdin", "rb", 0, NULL, sc_in);
s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out);
s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err);
if (s_in==NULL || s_out==NULL || s_err==NULL) {
- FREE_ZVAL(zin);
- FREE_ZVAL(zout);
- FREE_ZVAL(zerr);
if (s_in) php_stream_close(s_in);
if (s_out) php_stream_close(s_out);
if (s_err) php_stream_close(s_err);
@@ -563,34 +614,27 @@ static void phpdbg_register_file_handles(TSRMLS_D) /* {{{ */
s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
#endif
- php_stream_to_zval(s_in, zin);
- php_stream_to_zval(s_out, zout);
- php_stream_to_zval(s_err, zerr);
+ php_stream_to_zval(s_in, &zin);
+ php_stream_to_zval(s_out, &zout);
+ php_stream_to_zval(s_err, &zerr);
- ic.value = *zin;
+ ic.value = zin;
ic.flags = CONST_CS;
- ic.name = zend_strndup(ZEND_STRL("STDIN"));
- ic.name_len = sizeof("STDIN");
+ ic.name = zend_string_init(ZEND_STRL("STDIN"), 0);
ic.module_number = 0;
zend_register_constant(&ic TSRMLS_CC);
- oc.value = *zout;
+ oc.value = zout;
oc.flags = CONST_CS;
- oc.name = zend_strndup(ZEND_STRL("STDOUT"));
- oc.name_len = sizeof("STDOUT");
+ oc.name = zend_string_init(ZEND_STRL("STDOUT"), 0);
oc.module_number = 0;
zend_register_constant(&oc TSRMLS_CC);
- ec.value = *zerr;
+ ec.value = zerr;
ec.flags = CONST_CS;
- ec.name = zend_strndup(ZEND_STRL("STDERR"));
- ec.name_len = sizeof("STDERR");
+ ec.name = zend_string_init(ZEND_STRL("STDERR"), 0);
ec.module_number = 0;
zend_register_constant(&ec TSRMLS_CC);
-
- FREE_ZVAL(zin);
- FREE_ZVAL(zout);
- FREE_ZVAL(zerr);
}
/* }}} */
@@ -648,6 +692,7 @@ const opt_struct OPTIONS[] = { /* {{{ */
{'l', 1, "listen"},
{'a', 1, "address-or-any"},
#endif
+ {'x', 0, "xml output"},
{'V', 0, "version"},
{'-', 0, NULL}
}; /* }}} */
@@ -664,10 +709,9 @@ const char phpdbg_ini_hardcoded[] =
/* overwriteable ini defaults must be set in phpdbg_ini_defaults() */
#define INI_DEFAULT(name, value) \
+ ZVAL_STRINGL(&tmp, value, sizeof(value) - 1); \
Z_SET_REFCOUNT(tmp, 0); \
- Z_UNSET_ISREF(tmp); \
- ZVAL_STRINGL(&tmp, zend_strndup(value, sizeof(value)-1), sizeof(value)-1, 0); \
- zend_hash_update(configuration_hash, name, sizeof(name), &tmp, sizeof(zval), NULL);
+ zend_hash_str_update(configuration_hash, name, sizeof(name) - 1, &tmp);
void phpdbg_ini_defaults(HashTable *configuration_hash) /* {{{ */
{
@@ -679,17 +723,25 @@ static void phpdbg_welcome(zend_bool cleaning TSRMLS_DC) /* {{{ */
{
/* print blurb */
if (!cleaning) {
- phpdbg_notice("Welcome to phpdbg, the interactive PHP debugger, v%s",
- PHPDBG_VERSION);
- phpdbg_writeln("To get help using phpdbg type \"help\" and press enter");
- phpdbg_notice("Please report bugs to <%s>", PHPDBG_ISSUES);
+ phpdbg_xml("<intros>");
+ phpdbg_notice("intro", "version=\"%s\"", "Welcome to phpdbg, the interactive PHP debugger, v%s", PHPDBG_VERSION);
+ phpdbg_writeln("intro", "help=\"help\"", "To get help using phpdbg type \"help\" and press enter");
+ phpdbg_notice("intro", "report=\"%s\"", "Please report bugs to <%s>", PHPDBG_ISSUES);
+ phpdbg_xml("</intros>");
} else {
- phpdbg_notice("Clean Execution Environment");
+ if (!(PHPDBG_G(flags) & PHPDBG_WRITE_XML)) {
+ phpdbg_notice(NULL, NULL, "Clean Execution Environment");
+ }
- phpdbg_writeln("Classes\t\t\t%d", zend_hash_num_elements(EG(class_table)));
- phpdbg_writeln("Functions\t\t%d", zend_hash_num_elements(EG(function_table)));
- phpdbg_writeln("Constants\t\t%d", zend_hash_num_elements(EG(zend_constants)));
- phpdbg_writeln("Includes\t\t%d", zend_hash_num_elements(&EG(included_files)));
+ phpdbg_write("cleaninfo", "classes=\"%d\" functions=\"%d\" constants=\"%d\" includes=\"%d\"",
+ "Classes %d\n"
+ "Functions %d\n"
+ "Constants %d\n"
+ "Includes %d\n",
+ zend_hash_num_elements(EG(class_table)),
+ zend_hash_num_elements(EG(function_table)),
+ zend_hash_num_elements(EG(zend_constants)),
+ zend_hash_num_elements(&EG(included_files)));
}
} /* }}} */
@@ -697,163 +749,129 @@ static inline void phpdbg_sigint_handler(int signo) /* {{{ */
{
TSRMLS_FETCH();
- if (EG(in_execution)) {
- /* set signalled only when not interactive */
- if (!(PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE)) {
- PHPDBG_G(flags) |= PHPDBG_IS_SIGNALED;
- }
- } else {
+ if (PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE) {
/* we quit remote consoles on recv SIGINT */
if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) {
PHPDBG_G(flags) |= PHPDBG_IS_QUITTING;
zend_bailout();
}
- }
-} /* }}} */
-
-#ifndef _WIN32
-int phpdbg_open_socket(const char *interface, short port) /* {{{ */
-{
- int fd = socket(AF_INET, SOCK_STREAM, 0);
-
- switch (fd) {
- case -1:
- return -1;
-
- default: {
- int reuse = 1;
-
- switch (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse))) {
- case -1:
- close(fd);
- return -2;
-
- default: {
- struct sockaddr_in address;
-
- memset(&address, 0, sizeof(address));
-
- address.sin_port = htons(port);
- address.sin_family = AF_INET;
-
- if ((*interface == '*')) {
- address.sin_addr.s_addr = htonl(INADDR_ANY);
- } else if (!inet_pton(AF_INET, interface, &address.sin_addr)) {
- close(fd);
- return -3;
- }
-
- switch (bind(fd, (struct sockaddr *)&address, sizeof(address))) {
- case -1:
- close(fd);
- return -4;
-
- default: {
- listen(fd, 5);
- }
- }
- }
+ } else {
+ /* set signalled only when not interactive */
+ if (!(PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE)) {
+ if (PHPDBG_G(flags) & PHPDBG_IS_SIGNALED) {
+ char mem[PHPDBG_SIGSAFE_MEM_SIZE + 1];
+
+ phpdbg_set_sigsafe_mem(mem TSRMLS_CC);
+ zend_try {
+ phpdbg_force_interruption(TSRMLS_C);
+ } zend_end_try()
+ phpdbg_clear_sigsafe_mem(TSRMLS_C);
+ return;
}
+ PHPDBG_G(flags) |= PHPDBG_IS_SIGNALED;
}
}
-
- return fd;
} /* }}} */
-static inline void phpdbg_close_sockets(int (*socket)[2], FILE *streams[2]) /* {{{ */
-{
- if ((*socket)[0] >= 0) {
- shutdown(
- (*socket)[0], SHUT_RDWR);
- close((*socket)[0]);
+static void phpdbg_remote_close(int socket, FILE *stream) {
+ if (socket >= 0) {
+ phpdbg_close_socket(socket);
}
- if (streams[0]) {
- fclose(streams[0]);
+ if (stream) {
+ fclose(stream);
}
+}
- if ((*socket)[1] >= 0) {
- shutdown(
- (*socket)[1], SHUT_RDWR);
- close((*socket)[1]);
- }
+/* don't inline this, want to debug it easily, will inline when done */
+static int phpdbg_remote_init(const char* address, unsigned short port, int server, int *socket, FILE **stream TSRMLS_DC) {
+ phpdbg_remote_close(*socket, *stream);
+
+ if (server < 0) {
+ phpdbg_rlog(fileno(stderr), "Initializing connection on %s:%u failed", address, port);
- if (streams[1]) {
- fclose(streams[1]);
+ return FAILURE;
}
-} /* }}} */
-/* don't inline this, want to debug it easily, will inline when done */
+ phpdbg_rlog(fileno(stderr), "accepting connections on %s:%u", address, port);
+ {
+ struct sockaddr_storage address;
+ socklen_t size = sizeof(address);
+ char buffer[20] = {0};
+ /* XXX error checks */
+ memset(&address, 0, size);
+ *socket = accept(server, (struct sockaddr *) &address, &size);
+ inet_ntop(AF_INET, &(((struct sockaddr_in *)&address)->sin_addr), buffer, sizeof(buffer));
-int phpdbg_open_sockets(char *address, int port[2], int (*listen)[2], int (*socket)[2], FILE* streams[2]) /* {{{ */
-{
- if (((*listen)[0]) < 0 && ((*listen)[1]) < 0) {
- ((*listen)[0]) = phpdbg_open_socket(address, (short)port[0]);
- ((*listen)[1]) = phpdbg_open_socket(address, (short)port[1]);
+ phpdbg_rlog(fileno(stderr), "connection established from %s", buffer);
}
- streams[0] = NULL;
- streams[1] = NULL;
-
- if ((*listen)[0] < 0 || (*listen)[1] < 0) {
- if ((*listen)[0] < 0) {
- phpdbg_rlog(stderr,
- "console failed to initialize (stdin) on %s:%d", address, port[0]);
- }
+#ifndef _WIN32
+ dup2(*socket, fileno(stdout));
+ dup2(*socket, fileno(stdin));
- if ((*listen)[1] < 0) {
- phpdbg_rlog(stderr,
- "console failed to initialize (stdout) on %s:%d", address, port[1]);
- }
+ setbuf(stdout, NULL);
- if ((*listen)[0] >= 0) {
- close((*listen)[0]);
- }
+ *stream = fdopen(*socket, "r+");
- if ((*listen)[1] >= 0) {
- close((*listen)[1]);
- }
+ phpdbg_set_async_io(*socket);
+#endif
+ return SUCCESS;
+}
- return FAILURE;
- }
+#ifndef _WIN32
+/* This function *strictly* assumes that SIGIO is *only* used on the remote connection stream */
+void phpdbg_sigio_handler(int sig, siginfo_t *info, void *context) /* {{{ */
+{
+ int flags;
+ size_t newlen;
+ size_t i/*, last_nl*/;
+ TSRMLS_FETCH();
- phpdbg_close_sockets(socket, streams);
+// if (!(info->si_band & POLLIN)) {
+// return; /* Not interested in writeablility etc., just interested in incoming data */
+// }
- phpdbg_rlog(stderr,
- "accepting connections on %s:%d/%d", address, port[0], port[1]);
- {
- struct sockaddr_in address;
- socklen_t size = sizeof(address);
- char buffer[20] = {0};
+ /* only non-blocking reading, avoid non-blocking writing */
+ flags = fcntl(PHPDBG_G(io)[PHPDBG_STDIN].fd, F_GETFL, 0);
+ fcntl(PHPDBG_G(io)[PHPDBG_STDIN].fd, F_SETFL, flags | O_NONBLOCK);
- {
- memset(&address, 0, size);
- (*socket)[0] = accept(
- (*listen)[0], (struct sockaddr *) &address, &size);
- inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer));
+ do {
+ char mem[PHPDBG_SIGSAFE_MEM_SIZE + 1];
+ size_t off = 0;
- phpdbg_rlog(stderr, "connection (stdin) from %s", buffer);
+ if ((newlen = recv(PHPDBG_G(io)[PHPDBG_STDIN].fd, mem, PHPDBG_SIGSAFE_MEM_SIZE, MSG_PEEK)) == (size_t) -1) {
+ break;
}
-
- {
- memset(&address, 0, size);
- (*socket)[1] = accept(
- (*listen)[1], (struct sockaddr *) &address, &size);
- inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer));
-
- phpdbg_rlog(stderr, "connection (stdout) from %s", buffer);
+ for (i = 0; i < newlen; i++) {
+ switch (mem[off + i]) {
+ case '\x03': /* ^C char */
+ if (PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE) {
+ break; /* or quit ??? */
+ }
+ if (PHPDBG_G(flags) & PHPDBG_IS_SIGNALED) {
+ phpdbg_set_sigsafe_mem(mem TSRMLS_CC);
+ zend_try {
+ phpdbg_force_interruption(TSRMLS_C);
+ } zend_end_try();
+ phpdbg_clear_sigsafe_mem(TSRMLS_C);
+ break;
+ }
+ if (!(PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE)) {
+ PHPDBG_G(flags) |= PHPDBG_IS_SIGNALED;
+ }
+ break;
+/* case '\n':
+ zend_llist_add_element(PHPDBG_G(stdin), strndup()
+ last_nl = PHPDBG_G(stdin_buf).len + i;
+ break;
+*/ }
}
- }
+ off += i;
+ } while (0);
- dup2((*socket)[0], fileno(stdin));
- dup2((*socket)[1], fileno(stdout));
-
- setbuf(stdout, NULL);
- streams[0] = fdopen((*socket)[0], "r");
- streams[1] = fdopen((*socket)[1], "w");
-
- return SUCCESS;
+ fcntl(PHPDBG_G(io)[PHPDBG_STDIN].fd, F_SETFL, flags);
} /* }}} */
void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */
@@ -864,6 +882,9 @@ void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */
switch (sig) {
case SIGBUS:
case SIGSEGV:
+ if (PHPDBG_G(sigsegv_bailout)) {
+ LONGJMP(*PHPDBG_G(sigsegv_bailout), FAILURE);
+ }
is_handled = phpdbg_watchpoint_segfault_handler(info, context TSRMLS_CC);
if (is_handled == FAILURE) {
#ifdef ZEND_SIGNALS
@@ -938,10 +959,10 @@ int main(int argc, char **argv) /* {{{ */
#ifndef _WIN32
char *address;
- int listen[2];
- int server[2];
- int socket[2];
- FILE* streams[2] = {NULL, NULL};
+ int listen = -1;
+ int server = -1;
+ int socket = -1;
+ FILE* stream = NULL;
#endif
#ifdef ZTS
@@ -949,19 +970,15 @@ int main(int argc, char **argv) /* {{{ */
#endif
#ifndef _WIN32
+ struct sigaction sigio_struct;
struct sigaction signal_struct;
signal_struct.sa_sigaction = phpdbg_signal_handler;
signal_struct.sa_flags = SA_SIGINFO | SA_NODEFER;
+ sigio_struct.sa_sigaction = phpdbg_sigio_handler;
+ sigio_struct.sa_flags = SA_SIGINFO;
+
address = strdup("127.0.0.1");
- socket[0] = -1;
- socket[1] = -1;
- listen[0] = -1;
- listen[1] = -1;
- server[0] = -1;
- server[1] = -1;
- streams[0] = NULL;
- streams[1] = NULL;
#endif
#ifdef PHP_WIN32
@@ -991,7 +1008,7 @@ phpdbg_main:
}
if (!bp_tmp_file) {
- phpdbg_error("Unable to create temporary file");
+ phpdbg_error("tmpfile", "", "Unable to create temporary file");
return 1;
}
#else
@@ -1126,20 +1143,12 @@ phpdbg_main:
break;
#ifndef _WIN32
- /* if you pass a listen port, we will accept input on listen port */
- /* and write output to listen port * 2 */
-
- case 'l': { /* set listen ports */
- if (sscanf(php_optarg, "%d/%d", &listen[0], &listen[1]) != 2) {
- if (sscanf(php_optarg, "%d", &listen[0]) != 1) {
- /* default to hardcoded ports */
- listen[0] = 4000;
- listen[1] = 8000;
- } else {
- listen[1] = (listen[0] * 2);
- }
+ /* if you pass a listen port, we will read and write on listen port */
+ case 'l': /* set listen ports */
+ if (sscanf(php_optarg, "%d", &listen) != 1) {
+ listen = 8000;
}
- } break;
+ break;
case 'a': { /* set bind address */
free(address);
@@ -1149,6 +1158,10 @@ phpdbg_main:
} break;
#endif
+ case 'x':
+ flags |= PHPDBG_WRITE_XML;
+ break;
+
case 'V': {
sapi_startup(phpdbg);
phpdbg->startup(phpdbg);
@@ -1180,19 +1193,6 @@ phpdbg_main:
php_optind++;
}
-#ifndef _WIN32
- /* setup remote server if necessary */
- if (!cleaning &&
- (listen[0] > 0 && listen[1] > 0)) {
- if (phpdbg_open_sockets(address, listen, &server, &socket, streams) == FAILURE) {
- remote = 0;
- exit(0);
- }
- /* set remote flag to stop service shutting down upon quit */
- remote = 1;
- }
-#endif
-
if (sapi_name) {
phpdbg->name = sapi_name;
}
@@ -1247,19 +1247,47 @@ phpdbg_main:
EXCEPTION_POINTERS *xp;
__try {
#endif
- zend_mm_heap *mm_heap = phpdbg_mm_get_heap();
+ zend_mm_heap *mm_heap;
+ void* (*_malloc)(size_t);
+ void (*_free)(void*);
+ void* (*_realloc)(void*, size_t);
- if (mm_heap->use_zend_alloc) {
- mm_heap->_malloc = phpdbg_malloc_wrapper;
- mm_heap->_realloc = phpdbg_realloc_wrapper;
- mm_heap->_free = phpdbg_free_wrapper;
- mm_heap->use_zend_alloc = 0;
+#ifndef _WIN32
+ /* setup remote server if necessary */
+ if (!cleaning && listen > 0) {
+ server = phpdbg_open_socket(address, listen TSRMLS_CC);
+ if (-1 > server || phpdbg_remote_init(address, listen, server, &socket, &stream TSRMLS_CC) == FAILURE) {
+ exit(0);
+ }
+
+ sigaction(SIGIO, &sigio_struct, NULL);
+
+ /* set remote flag to stop service shutting down upon quit */
+ remote = 1;
+ }
+#endif
+
+ mm_heap = phpdbg_mm_get_heap();
+ zend_mm_get_custom_handlers(mm_heap, &_malloc, &_free, &_realloc);
+
+ if (!_malloc) {
+ _malloc = phpdbg_malloc_wrapper;
+ }
+ if (!_realloc) {
+ _realloc = phpdbg_realloc_wrapper;
+ }
+ if (!_free) {
+ _free = phpdbg_free_wrapper;
}
zend_activate(TSRMLS_C);
- PHPDBG_G(original_free_function) = mm_heap->_free;
- mm_heap->_free = phpdbg_watch_efree;
+ phpdbg_init_list(TSRMLS_C);
+
+ PHPDBG_G(original_free_function) = _free;
+ _free = phpdbg_watch_efree;
+
+ zend_mm_set_custom_handlers(mm_heap, _malloc, _free, _realloc);
phpdbg_setup_watchpoints(TSRMLS_C);
@@ -1277,10 +1305,17 @@ phpdbg_main:
sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal));
#endif
+ PHPDBG_G(sapi_name_ptr) = sapi_name;
+
+ php_output_activate(TSRMLS_C);
+ php_output_deactivate(TSRMLS_C);
+
+ php_output_activate(TSRMLS_C);
+
if (php_request_startup(TSRMLS_C) == SUCCESS) {
int i;
-
- SG(request_info).argc = argc - php_optind + 1;
+
+ SG(request_info).argc = argc - php_optind + 1;
SG(request_info).argv = emalloc(SG(request_info).argc * sizeof(char *));
for (i = SG(request_info).argc; --i;) {
SG(request_info).argv[i] = estrdup(argv[php_optind - 1 + i]);
@@ -1290,14 +1325,10 @@ phpdbg_main:
php_hash_environment(TSRMLS_C);
}
- /* make sure to turn off buffer for ev command */
- php_output_activate(TSRMLS_C);
- php_output_deactivate(TSRMLS_C);
-
/* do not install sigint handlers for remote consoles */
/* sending SIGINT then provides a decent way of shutting down the server */
#ifndef _WIN32
- if (listen[0] < 0) {
+ if (listen < 0) {
#endif
#if defined(ZEND_SIGNALS) && !defined(_WIN32)
zend_try { zend_signal(SIGINT, phpdbg_sigint_handler TSRMLS_CC); } zend_end_try();
@@ -1315,16 +1346,43 @@ phpdbg_main:
#ifndef _WIN32
/* setup io here */
- if (streams[0] && streams[1]) {
+ if (remote) {
PHPDBG_G(flags) |= PHPDBG_IS_REMOTE;
signal(SIGPIPE, SIG_IGN);
}
#endif
- PHPDBG_G(io)[PHPDBG_STDIN] = stdin;
- PHPDBG_G(io)[PHPDBG_STDOUT] = stdout;
- PHPDBG_G(io)[PHPDBG_STDERR] = stderr;
+#ifndef _WIN32
+ PHPDBG_G(io)[PHPDBG_STDIN].ptr = stdin;
+ PHPDBG_G(io)[PHPDBG_STDIN].fd = fileno(stdin);
+ PHPDBG_G(io)[PHPDBG_STDOUT].ptr = stdout;
+ PHPDBG_G(io)[PHPDBG_STDOUT].fd = fileno(stdout);
+#else
+ /* XXX this is a complete mess here with FILE/fd/SOCKET,
+ we should let only one to survive probably. Need
+ a clean separation whether it's a remote or local
+ prompt. And what is supposed to go as user interaction,
+ error log, etc. */
+ if (remote) {
+ PHPDBG_G(io)[PHPDBG_STDIN].ptr = stdin;
+ PHPDBG_G(io)[PHPDBG_STDIN].fd = socket;
+ PHPDBG_G(io)[PHPDBG_STDOUT].ptr = stdout;
+ PHPDBG_G(io)[PHPDBG_STDOUT].fd = socket;
+ } else {
+ PHPDBG_G(io)[PHPDBG_STDIN].ptr = stdin;
+ PHPDBG_G(io)[PHPDBG_STDIN].fd = fileno(stdin);
+ PHPDBG_G(io)[PHPDBG_STDOUT].ptr = stdout;
+ PHPDBG_G(io)[PHPDBG_STDOUT].fd = fileno(stdout);
+ }
+#endif
+ PHPDBG_G(io)[PHPDBG_STDERR].ptr = stderr;
+ PHPDBG_G(io)[PHPDBG_STDERR].fd = fileno(stderr);
+
+#ifndef _WIN32
+ PHPDBG_G(php_stdiop_write) = php_stream_stdio_ops.write;
+ php_stream_stdio_ops.write = phpdbg_stdiop_write;
+#endif
if (exec) { /* set execution context */
PHPDBG_G(exec) = phpdbg_resolve_path(exec TSRMLS_CC);
@@ -1336,8 +1394,7 @@ phpdbg_main:
if (oplog_file) { /* open oplog */
PHPDBG_G(oplog) = fopen(oplog_file, "w+");
if (!PHPDBG_G(oplog)) {
- phpdbg_error(
- "Failed to open oplog %s", oplog_file);
+ phpdbg_error("oplog", "path=\"%s\"", "Failed to open oplog %s", oplog_file);
}
free(oplog_file);
}
@@ -1348,7 +1405,7 @@ phpdbg_main:
phpdbg_set_color_ex(PHPDBG_COLOR_NOTICE, PHPDBG_STRL("green") TSRMLS_CC);
/* set default prompt */
- phpdbg_set_prompt(PROMPT TSRMLS_CC);
+ phpdbg_set_prompt(PHPDBG_DEFAULT_PROMPT TSRMLS_CC);
/* Make stdin, stdout and stderr accessible from PHP scripts */
phpdbg_register_file_handles(TSRMLS_C);
@@ -1397,7 +1454,7 @@ phpdbg_interact:
/* phpdbg main() */
do {
zend_try {
- phpdbg_interactive(TSRMLS_C);
+ phpdbg_interactive(1 TSRMLS_CC);
} zend_catch {
if ((PHPDBG_G(flags) & PHPDBG_IS_CLEANING)) {
FILE *bp_tmp_fp = fopen(bp_tmp_file, "w");
@@ -1415,11 +1472,10 @@ phpdbg_interact:
if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) {
/* renegociate connections */
- phpdbg_open_sockets(
- address, listen, &server, &socket, streams);
+ phpdbg_remote_init(address, listen, server, &socket, &stream TSRMLS_CC);
/* set streams */
- if (streams[0] && streams[1]) {
+ if (stream) {
PHPDBG_G(flags) &= ~PHPDBG_IS_QUITTING;
}
@@ -1451,11 +1507,11 @@ phpdbg_out:
#ifdef _WIN32
} __except(phpdbg_exception_handler_win32(xp = GetExceptionInformation())) {
- phpdbg_error("Access violation (Segementation fault) encountered\ntrying to abort cleanly...");
+ phpdbg_error("segfault", "", "Access violation (Segementation fault) encountered\ntrying to abort cleanly...");
}
phpdbg_out:
#endif
-
+
{
int i;
/* free argv */
@@ -1468,8 +1524,7 @@ phpdbg_out:
#ifndef ZTS
/* force cleanup of auto and core globals */
zend_hash_clean(CG(auto_globals));
- memset(
- &core_globals, 0, sizeof(php_core_globals));
+ memset( &core_globals, 0, sizeof(php_core_globals));
#endif
if (ini_entries) {
free(ini_entries);
@@ -1478,15 +1533,17 @@ phpdbg_out:
if (ini_override) {
free(ini_override);
}
-
+
/* this must be forced */
CG(unclean_shutdown) = 0;
-
+
/* this is just helpful */
PG(report_memleaks) = 0;
php_request_shutdown((void*)0);
+ php_output_deactivate(TSRMLS_C);
+
zend_try {
php_module_shutdown(TSRMLS_C);
} zend_end_try();
@@ -1498,7 +1555,7 @@ phpdbg_out:
if (cleaning || remote) {
goto phpdbg_main;
}
-
+
#ifdef ZTS
/* bugggy */
/* tsrm_shutdown(); */
@@ -1510,10 +1567,10 @@ phpdbg_out:
}
#endif
- if (sapi_name) {
- free(sapi_name);
+ if (PHPDBG_G(sapi_name_ptr)) {
+ free(PHPDBG_G(sapi_name_ptr));
}
-
+
#ifdef _WIN32
free(bp_tmp_file);
#else
diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h
index 364ef7d176..f3e8ba3107 100644
--- a/sapi/phpdbg/phpdbg.h
+++ b/sapi/phpdbg/phpdbg.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -29,6 +29,8 @@
# define PHPDBG_API
#endif
+#include <stdint.h>
+#include <stddef.h>
#include "php.h"
#include "php_globals.h"
#include "php_variables.h"
@@ -40,20 +42,21 @@
#include "zend_ini_scanner.h"
#include "zend_stream.h"
#ifndef _WIN32
-# include "zend_signal.h"
+# include "zend_signal.h"
#endif
#include "SAPI.h"
#include <fcntl.h>
#include <sys/types.h>
#if defined(_WIN32) && !defined(__MINGW32__)
-# include <windows.h>
-# include "config.w32.h"
-# undef strcasecmp
-# undef strncasecmp
-# define strcasecmp _stricmp
-# define strncasecmp _strnicmp
+# include <windows.h>
+# include "config.w32.h"
+# include "win32/php_stdint.h"
+# undef strcasecmp
+# undef strncasecmp
+# define strcasecmp _stricmp
+# define strncasecmp _strnicmp
#else
-# include "php_config.h"
+# include "php_config.h"
#endif
#ifndef O_BINARY
# define O_BINARY 0
@@ -64,21 +67,64 @@
# include "TSRM.h"
#endif
-#ifdef LIBREADLINE
-# include <readline/readline.h>
-# include <readline/history.h>
+#define ZEND_HASH_FOREACH_NUM_KEY_PTR(ht, _h, _ptr) \
+ ZEND_HASH_FOREACH(ht, 0); \
+ _h = _p->h; \
+ _ptr = Z_PTR_P(_z);
+
+#undef zend_hash_str_add
+#define zend_hash_str_add_tmp(ht, key, len, pData) \
+ _zend_hash_str_add(ht, key, len, pData ZEND_FILE_LINE_CC)
+#define zend_hash_str_add(...) zend_hash_str_add_tmp(__VA_ARGS__)
+
+static zend_always_inline void *zend_hash_index_add_mem(HashTable *ht, zend_ulong h, void *pData, size_t size)
+{
+ zval tmp, *zv;
+
+ ZVAL_PTR(&tmp, NULL);
+ if ((zv = zend_hash_index_add(ht, h, &tmp))) {
+ Z_PTR_P(zv) = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
+ memcpy(Z_PTR_P(zv), pData, size);
+ return Z_PTR_P(zv);
+ }
+ return NULL;
+}
+
+#ifdef HAVE_LIBREADLINE
+# include <readline/readline.h>
+# include <readline/history.h>
#endif
#ifdef HAVE_LIBEDIT
-# include <editline/readline.h>
+# include <editline/readline.h>
#endif
-#include "phpdbg_lexer.h"
-#include "phpdbg_cmd.h"
-#include "phpdbg_utils.h"
-#include "phpdbg_btree.h"
-#include "phpdbg_watch.h"
+/* {{{ remote console headers */
+#ifndef _WIN32
+# include <sys/socket.h>
+# include <sys/un.h>
+# include <sys/select.h>
+# include <sys/types.h>
+# include <netdb.h>
+#endif /* }}} */
-int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC);
+/* {{{ strings */
+#define PHPDBG_NAME "phpdbg"
+#define PHPDBG_AUTHORS "Felipe Pena, Joe Watkins and Bob Weinand" /* Ordered by last name */
+#define PHPDBG_URL "http://phpdbg.com"
+#define PHPDBG_ISSUES "http://github.com/krakjoe/phpdbg/issues"
+#define PHPDBG_VERSION "0.4.0"
+#define PHPDBG_INIT_FILENAME ".phpdbginit"
+#define PHPDBG_DEFAULT_PROMPT "prompt>"
+/* }}} */
+
+/* Hey, apple. One shouldn't define *functions* from the standard C library as marcos. */
+#ifdef memcpy
+#define memcpy_tmp(...) memcpy(__VA_ARGS__)
+#undef memcpy
+#define memcpy(...) memcpy_tmp(__VA_ARGS__)
+#endif
+
+#if !defined(PHPDBG_WEBDATA_TRANSFER_H) && !defined(PHPDBG_WEBHELPER_H)
#ifdef ZTS
# define PHPDBG_G(v) TSRMG(phpdbg_globals_id, zend_phpdbg_globals *, v)
@@ -86,6 +132,19 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC);
# define PHPDBG_G(v) (phpdbg_globals.v)
#endif
+#include "phpdbg_sigsafe.h"
+#include "phpdbg_out.h"
+#include "phpdbg_lexer.h"
+#include "phpdbg_cmd.h"
+#include "phpdbg_utils.h"
+#include "phpdbg_btree.h"
+#include "phpdbg_watch.h"
+#ifdef PHP_WIN32
+# include "phpdbg_sigio_win32.h"
+#endif
+
+int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC);
+
#define PHPDBG_NEXT 2
#define PHPDBG_UNTIL 3
#define PHPDBG_FINISH 4
@@ -145,11 +204,14 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC);
#define PHPDBG_IS_BP_ENABLED (1<<26)
#define PHPDBG_IS_REMOTE (1<<27)
#define PHPDBG_IS_DISCONNECTED (1<<28)
+#define PHPDBG_WRITE_XML (1<<29)
+
+#define PHPDBG_SHOW_REFCOUNTS (1<<30)
-#define PHPDBG_SHOW_REFCOUNTS (1<<29)
+#define PHPDBG_IN_SIGNAL_HANDLER (1<<30)
#define PHPDBG_SEEK_MASK (PHPDBG_IN_UNTIL|PHPDBG_IN_FINISH|PHPDBG_IN_LEAVE)
-#define PHPDBG_BP_RESOLVE_MASK (PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP)
+#define PHPDBG_BP_RESOLVE_MASK (PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP)
#define PHPDBG_BP_MASK (PHPDBG_HAS_FILE_BP|PHPDBG_HAS_SYM_BP|PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_OPLINE_BP|PHPDBG_HAS_COND_BP|PHPDBG_HAS_OPCODE_BP|PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP)
#ifndef _WIN32
@@ -158,21 +220,27 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC);
# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_BP_ENABLED)
#endif /* }}} */
-/* {{{ strings */
-#define PHPDBG_NAME "phpdbg"
-#define PHPDBG_AUTHORS "Felipe Pena, Joe Watkins and Bob Weinand" /* Ordered by last name */
-#define PHPDBG_URL "http://phpdbg.com"
-#define PHPDBG_ISSUES "http://github.com/krakjoe/phpdbg/issues"
-#define PHPDBG_VERSION "0.4.0"
-#define PHPDBG_INIT_FILENAME ".phpdbginit"
-/* }}} */
-
/* {{{ output descriptors */
#define PHPDBG_STDIN 0
#define PHPDBG_STDOUT 1
#define PHPDBG_STDERR 2
#define PHPDBG_IO_FDS 3 /* }}} */
+#define phpdbg_try_access \
+ { \
+ JMP_BUF *__orig_bailout = PHPDBG_G(sigsegv_bailout); \
+ JMP_BUF __bailout; \
+ \
+ PHPDBG_G(sigsegv_bailout) = &__bailout; \
+ if (SETJMP(__bailout) == 0) {
+#define phpdbg_catch_access \
+ } else { \
+ PHPDBG_G(sigsegv_bailout) = __orig_bailout;
+#define phpdbg_end_try_access() \
+ } \
+ PHPDBG_G(sigsegv_bailout) = __orig_bailout; \
+ }
+
/* {{{ structs */
ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
@@ -180,7 +248,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
HashTable registered; /* registered */
HashTable seek; /* seek oplines */
phpdbg_frame_t frame; /* frame */
- uint32_t last_line; /* last executed line */
+ uint32_t last_line; /* last executed line */
phpdbg_lexer_data lexer; /* lexer data */
phpdbg_param_t *parser_stack; /* param stack during lexer / parser phase */
@@ -191,6 +259,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
phpdbg_btree watchpoint_tree; /* tree with watchpoints */
phpdbg_btree watch_HashTables; /* tree with original dtors of watchpoints */
HashTable watchpoints; /* watchpoints */
+ HashTable watch_collisions; /* collision table to check if multiple watches share the same recursive watchpoint */
zend_llist watchlist_mem; /* triggered watchpoints */
zend_bool watchpoint_hit; /* a watchpoint was hit */
void (*original_free_function)(void *); /* the original AG(mm_heap)->_free function */
@@ -198,33 +267,57 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
char *exec; /* file to execute */
size_t exec_len; /* size of exec */
zend_op_array *ops; /* op_array */
- zval *retval; /* return value */
+ zval retval; /* return value */
int bp_count; /* breakpoint count */
int vmret; /* return from last opcode handler execution */
+ zend_bool in_execution; /* in execution? */
+
+ zend_op_array *(*compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
+ HashTable file_sources;
FILE *oplog; /* opline log */
- FILE *io[PHPDBG_IO_FDS]; /* io */
+ struct {
+ FILE *ptr;
+ int fd;
+ } io[PHPDBG_IO_FDS]; /* io */
+ size_t (*php_stdiop_write)(php_stream *, const char *, size_t TSRMLS_DC);
+ int in_script_xml; /* in <stream> output mode */
+ struct {
+ zend_bool active;
+ int type;
+ int fd;
+ char *tag;
+ char *msg;
+ int msglen;
+ char *xml;
+ int xmllen;
+ } err_buf; /* error buffer */
+ zend_ulong req_id; /* "request id" to keep track of commands */
char *prompt[2]; /* prompt */
const phpdbg_color_t *colors[PHPDBG_COLORS]; /* colors */
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 */
+
+ 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!) */
+
+ JMP_BUF *sigsegv_bailout; /* bailout address for accesibility probing */
zend_ulong flags; /* phpdbg flags */
+
+ char *socket_path; /* phpdbg.path ini setting */
+ char *sapi_name_ptr; /* store sapi name to free it if necessary to not leak memory */
+ int socket_fd; /* file descriptor to socket (wait command) (-1 if unused) */
+ int socket_server_fd; /* file descriptor to master socket (wait command) (-1 if unused) */
+#ifdef PHP_WIN32
+ HANDLE sigio_watcher_thread; /* sigio watcher thread handle */
+ struct win32_sigio_watcher_data swd;
+#endif
+ int8_t eol;
ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */
-/* the beginning (= the important part) of the _zend_mm_heap struct defined in Zend/zend_alloc.c
- Needed for realizing watchpoints */
-struct _zend_mm_heap {
- int use_zend_alloc;
- void *(*_malloc)(size_t);
- void (*_free)(void *);
- void *(*_realloc)(void *, size_t);
- size_t free_bitmap;
- size_t large_free_bitmap;
- size_t block_size;
- size_t compact_size;
- zend_mm_segment *segments_list;
- zend_mm_storage *storage;
-};
+#endif
#endif /* PHPDBG_H */
diff --git a/sapi/phpdbg/phpdbg_bp.c b/sapi/phpdbg/phpdbg_bp.c
index e30b87c313..aaeaee13fd 100644
--- a/sapi/phpdbg/phpdbg_bp.c
+++ b/sapi/phpdbg/phpdbg_bp.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -43,8 +43,7 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut
*/
static inline void _phpdbg_break_mapping(int id, HashTable *table TSRMLS_DC)
{
- zend_hash_index_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (id), (void**) &table, sizeof(void*), NULL);
+ zend_hash_index_update_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id, table);
}
#define PHPDBG_BREAK_MAPPING(id, table) _phpdbg_break_mapping(id, table TSRMLS_CC)
@@ -58,29 +57,29 @@ static inline void _phpdbg_break_mapping(int id, HashTable *table TSRMLS_DC)
b.hits = 0; \
} while(0)
-static void phpdbg_file_breaks_dtor(void *data) /* {{{ */
+static void phpdbg_file_breaks_dtor(zval *data) /* {{{ */
{
- phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*) data;
+ phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*) Z_PTR_P(data);
efree((char*)bp->filename);
} /* }}} */
-static void phpdbg_class_breaks_dtor(void *data) /* {{{ */
+static void phpdbg_class_breaks_dtor(zval *data) /* {{{ */
{
- phpdbg_breakmethod_t *bp = (phpdbg_breakmethod_t*) data;
+ phpdbg_breakmethod_t *bp = (phpdbg_breakmethod_t *) Z_PTR_P(data);
efree((char*)bp->class_name);
efree((char*)bp->func_name);
} /* }}} */
-static void phpdbg_opline_class_breaks_dtor(void *data) /* {{{ */
+static void phpdbg_opline_class_breaks_dtor(zval *data) /* {{{ */
{
- zend_hash_destroy((HashTable *)data);
+ zend_hash_destroy((HashTable *) Z_PTR_P(data));
} /* }}} */
-static void phpdbg_opline_breaks_dtor(void *data) /* {{{ */
+static void phpdbg_opline_breaks_dtor(zval *data) /* {{{ */
{
- phpdbg_breakopline_t *bp = (phpdbg_breakopline_t *) data;
+ phpdbg_breakopline_t *bp = (phpdbg_breakopline_t *) Z_PTR_P(data);
if (bp->class_name) {
efree((char*)bp->class_name);
@@ -92,45 +91,30 @@ static void phpdbg_opline_breaks_dtor(void *data) /* {{{ */
PHPDBG_API void phpdbg_reset_breakpoints(TSRMLS_D) /* {{{ */
{
- if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) {
- HashPosition position[2];
- HashTable **table = NULL;
+ HashTable *table;
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (void**)&table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0])) {
- phpdbg_breakbase_t *brake;
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], table) {
+ phpdbg_breakbase_t *brake;
- for (zend_hash_internal_pointer_reset_ex((*table), &position[1]);
- zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex((*table), &position[1])) {
- brake->hits = 0;
- }
- }
- }
+ ZEND_HASH_FOREACH_PTR(table, brake) {
+ brake->hits = 0;
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
} /* }}} */
PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
{
- HashPosition position[2];
- HashTable **table = NULL;
+ HashTable *table;
zend_ulong id = 0L;
if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) {
- phpdbg_notice(
- "Exporting %d breakpoints",
- zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]));
+ phpdbg_notice("exportbreakpoint", "count=\"%d\"", "Exporting %d breakpoints", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]));
+
/* this only looks like magic, it isn't */
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (void**)&table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0])) {
+ ZEND_HASH_FOREACH_NUM_KEY_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id, table) {
phpdbg_breakbase_t *brake;
- zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], NULL, NULL, &id, 0, &position[0]);
-
- for (zend_hash_internal_pointer_reset_ex((*table), &position[1]);
- zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex((*table), &position[1])) {
+ ZEND_HASH_FOREACH_PTR(table, brake) {
if (brake->id == id) {
switch (brake->type) {
case PHPDBG_BREAK_FILE: {
@@ -155,7 +139,7 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
case PHPDBG_BREAK_METHOD_OPLINE: {
fprintf(handle,
- "break %s::%s#%ld\n",
+ "break %s::%s#%llu\n",
((phpdbg_breakopline_t*)brake)->class_name,
((phpdbg_breakopline_t*)brake)->func_name,
((phpdbg_breakopline_t*)brake)->opline_num);
@@ -163,14 +147,14 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
case PHPDBG_BREAK_FUNCTION_OPLINE: {
fprintf(handle,
- "break %s#%ld\n",
+ "break %s#%llu\n",
((phpdbg_breakopline_t*)brake)->func_name,
((phpdbg_breakopline_t*)brake)->opline_num);
} break;
case PHPDBG_BREAK_FILE_OPLINE: {
fprintf(handle,
- "break %s:#%ld\n",
+ "break %s:#%llu\n",
((phpdbg_breakopline_t*)brake)->class_name,
((phpdbg_breakopline_t*)brake)->opline_num);
} break;
@@ -214,8 +198,8 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
} break;
}
}
- }
- }
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
}
} /* }}} */
@@ -223,27 +207,24 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML
{
php_stream_statbuf ssb;
char realpath[MAXPATHLEN];
-
+
if (php_stream_stat_path(path, &ssb) != FAILURE) {
if (ssb.sb.st_mode & (S_IFREG|S_IFLNK)) {
HashTable *broken;
phpdbg_breakfile_t new_break;
size_t path_len = 0L;
-
+
if (VCWD_REALPATH(path, realpath)) {
path = realpath;
}
path_len = strlen(path);
-
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
- path, path_len, (void**)&broken) == FAILURE) {
+
+ if (!(broken = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], path, path_len))) {
HashTable breaks;
zend_hash_init(&breaks, 8, NULL, phpdbg_file_breaks_dtor, 0);
- zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
- path, path_len, &breaks, sizeof(HashTable),
- (void**)&broken);
+ broken = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], path, path_len, &breaks, sizeof(HashTable));
}
if (!zend_hash_index_exists(broken, line_num)) {
@@ -253,28 +234,26 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML
new_break.filename = estrndup(path, path_len);
new_break.line = line_num;
- zend_hash_index_update(
- broken, line_num, (void**)&new_break, sizeof(phpdbg_breakfile_t), NULL);
+ zend_hash_index_update_mem(broken, line_num, &new_break, sizeof(phpdbg_breakfile_t));
- phpdbg_notice("Breakpoint #%d added at %s:%ld",
- new_break.id, new_break.filename, new_break.line);
+ phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" file=\"%s\" line=\"%ld\"", "Breakpoint #%d added at %s:%ld", new_break.id, new_break.filename, new_break.line);
PHPDBG_BREAK_MAPPING(new_break.id, broken);
} else {
- phpdbg_error("Breakpoint at %s:%ld exists", path, line_num);
+ phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" file=\"%s\" line=\"%ld\"", "Breakpoint at %s:%ld exists", path, line_num);
}
} else {
- phpdbg_error("Cannot set breakpoint in %s, it is not a regular file", path);
+ phpdbg_error("breakpoint", "type=\"notregular\" add=\"fail\" file=\"%s\"", "Cannot set breakpoint in %s, it is not a regular file", path);
}
} else {
- phpdbg_error("Cannot stat %s, it does not exist", path);
+ phpdbg_error("breakpoint", "type=\"nofile\" add=\"fail\" file=\"%s\"", "Cannot stat %s, it does not exist", path);
}
} /* }}} */
PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len TSRMLS_DC) /* {{{ */
{
- if (!zend_hash_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], name, name_len)) {
+ if (!zend_hash_str_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], name, name_len)) {
phpdbg_breaksymbol_t new_break;
PHPDBG_G(flags) |= PHPDBG_HAS_SYM_BP;
@@ -282,15 +261,13 @@ PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len T
PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_SYM);
new_break.symbol = estrndup(name, name_len);
- zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], new_break.symbol,
- name_len, &new_break, sizeof(phpdbg_breaksymbol_t), NULL);
+ zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], new_break.symbol, name_len, &new_break, sizeof(phpdbg_breaksymbol_t));
- phpdbg_notice("Breakpoint #%d added at %s",
- new_break.id, new_break.symbol);
+ phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" function=\"%s\"", "Breakpoint #%d added at %s", new_break.id, new_break.symbol);
PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_SYM]);
} else {
- phpdbg_notice("Breakpoint exists at %s", name);
+ phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" function=\"%s\"", "Breakpoint exists at %s", name);
}
} /* }}} */
@@ -301,16 +278,12 @@ PHPDBG_API void phpdbg_set_breakpoint_method(const char *class_name, const char
size_t func_len = strlen(func_name);
char *lcname = zend_str_tolower_dup(func_name, func_len);
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_name,
- class_len, (void**)&class_table) != SUCCESS) {
+ if (!(class_table = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_name, class_len))) {
zend_hash_init(&class_breaks, 8, NULL, phpdbg_class_breaks_dtor, 0);
- zend_hash_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_METHOD],
- class_name, class_len,
- (void**)&class_breaks, sizeof(HashTable), (void**)&class_table);
+ class_table = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_name, class_len, &class_breaks, sizeof(HashTable));
}
- if (!zend_hash_exists(class_table, lcname, func_len)) {
+ if (!zend_hash_str_exists(class_table, lcname, func_len)) {
phpdbg_breakmethod_t new_break;
PHPDBG_G(flags) |= PHPDBG_HAS_METHOD_BP;
@@ -321,15 +294,13 @@ PHPDBG_API void phpdbg_set_breakpoint_method(const char *class_name, const char
new_break.func_name = estrndup(func_name, func_len);
new_break.func_len = func_len;
- zend_hash_update(class_table, lcname, func_len,
- &new_break, sizeof(phpdbg_breakmethod_t), NULL);
+ zend_hash_str_update_mem(class_table, lcname, func_len, &new_break, sizeof(phpdbg_breakmethod_t));
- phpdbg_notice("Breakpoint #%d added at %s::%s",
- new_break.id, class_name, func_name);
+ phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" method=\"%s::%s\"", "Breakpoint #%d added at %s::%s", new_break.id, class_name, func_name);
PHPDBG_BREAK_MAPPING(new_break.id, class_table);
} else {
- phpdbg_notice("Breakpoint exists at %s::%s", class_name, func_name);
+ phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" method=\"%s::%s\"", "Breakpoint exists at %s::%s", class_name, func_name);
}
efree(lcname);
@@ -347,14 +318,12 @@ PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{
new_break.opline = opline;
new_break.base = NULL;
- zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline,
- &new_break, sizeof(phpdbg_breakline_t), NULL);
+ zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline, &new_break, sizeof(phpdbg_breakline_t));
- phpdbg_notice("Breakpoint #%d added at %#lx",
- new_break.id, new_break.opline);
+ phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" opline=\"%#lx\"", "Breakpoint #%d added at %#lx", new_break.id, new_break.opline);
PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
} else {
- phpdbg_notice("Breakpoint exists at %#lx", opline);
+ phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" opline=\"%#lx\"", "Breakpoint exists at %#lx", opline);
}
} /* }}} */
@@ -363,11 +332,11 @@ PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_o
phpdbg_breakline_t opline_break;
if (op_array->last <= brake->opline_num) {
if (brake->class_name == NULL) {
- phpdbg_error("There are only %d oplines in function %s (breaking at opline %ld impossible)", op_array->last, brake->func_name, brake->opline_num);
+ phpdbg_error("breakpoint", "type=\"maxoplines\" add=\"fail\" maxoplinenum=\"%d\" function=\"%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in function %s (breaking at opline %ld impossible)", op_array->last, brake->func_name, brake->opline_num);
} else if (brake->func_name == NULL) {
- phpdbg_error("There are only %d oplines in file %s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->opline_num);
+ phpdbg_error("breakpoint", "type=\"maxoplines\" add=\"fail\" maxoplinenum=\"%d\" file=\"%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in file %s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->opline_num);
} else {
- phpdbg_error("There are only %d oplines in method %s::%s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->func_name, brake->opline_num);
+ phpdbg_error("breakpoint", "type=\"maxoplines\" add=\"fail\" maxoplinenum=\"%d\" method=\"%s::%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in method %s::%s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->func_name, brake->opline_num);
}
return FAILURE;
@@ -389,7 +358,7 @@ PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_o
PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP;
- zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline_break.opline, &opline_break, sizeof(phpdbg_breakline_t), NULL);
+ zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline_break.opline, &opline_break, sizeof(phpdbg_breakline_t));
return SUCCESS;
} /* }}} */
@@ -398,40 +367,36 @@ PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC
{
HashTable *func_table = &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE];
HashTable *oplines_table;
- HashPosition position;
phpdbg_breakopline_t *brake;
- if (op_array->scope != NULL &&
- zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], op_array->scope->name, op_array->scope->name_length, (void **)&func_table) == FAILURE) {
+ if (op_array->scope != NULL && !(func_table = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], op_array->scope->name))) {
return;
}
if (op_array->function_name == NULL) {
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], op_array->filename, strlen(op_array->filename), (void **)&oplines_table) == FAILURE) {
+ if (!(oplines_table = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], op_array->filename))) {
return;
}
- } else if (zend_hash_find(func_table, op_array->function_name?op_array->function_name:"", op_array->function_name?strlen(op_array->function_name):0, (void **)&oplines_table) == FAILURE) {
+ } else if (!op_array->function_name || !(oplines_table = zend_hash_find_ptr(func_table, op_array->function_name))) {
return;
}
- for (zend_hash_internal_pointer_reset_ex(oplines_table, &position);
- zend_hash_get_current_data_ex(oplines_table, (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(oplines_table, &position)) {
+ ZEND_HASH_FOREACH_PTR(oplines_table, brake) {
if (phpdbg_resolve_op_array_break(brake, op_array TSRMLS_CC) == SUCCESS) {
phpdbg_breakline_t *opline_break;
zend_hash_internal_pointer_end(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
- zend_hash_get_current_data(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void **)&opline_break);
+ opline_break = zend_hash_get_current_data_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
- phpdbg_notice("Breakpoint #%d resolved at %s%s%s#%ld (opline %#lx)",
+ phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" symbol=\"%s\" num=\"%ld\" opline=\"%#lx\"", "Breakpoint #%d resolved at %s%s%s#%ld (opline %#lx)",
brake->id,
- brake->class_name?brake->class_name:"",
- brake->class_name&&brake->func_name?"::":"",
- brake->func_name?brake->func_name:"",
+ brake->class_name ? brake->class_name : "",
+ brake->class_name && brake->func_name ? "::" : "",
+ brake->func_name ? brake->func_name : "",
brake->opline_num,
brake->opline);
}
- }
+ } ZEND_HASH_FOREACH_END();
} /* }}} */
PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRMLS_DC) /* {{{ */
@@ -452,8 +417,9 @@ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRML
} else {
zend_execute_data *execute_data = EG(current_execute_data);
do {
- if (execute_data->op_array->function_name == NULL && execute_data->op_array->scope == NULL && !memcmp(execute_data->op_array->filename, new_break->class_name, new_break->class_len)) {
- if (phpdbg_resolve_op_array_break(new_break, execute_data->op_array TSRMLS_CC) == SUCCESS) {
+ zend_op_array *op_array = &execute_data->func->op_array;
+ if (op_array->function_name == NULL && op_array->scope == NULL && new_break->class_len == op_array->filename->len && !memcmp(op_array->filename->val, new_break->class_name, new_break->class_len)) {
+ if (phpdbg_resolve_op_array_break(new_break, op_array TSRMLS_CC) == SUCCESS) {
return SUCCESS;
} else {
return 2;
@@ -465,16 +431,16 @@ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRML
}
if (new_break->class_name != NULL) {
- zend_class_entry **ce;
- if (zend_hash_find(EG(class_table), zend_str_tolower_dup(new_break->class_name, new_break->class_len), new_break->class_len + 1, (void **)&ce) == FAILURE) {
+ zend_class_entry *ce;
+ if (!(ce = zend_hash_str_find_ptr(EG(class_table), zend_str_tolower_dup(new_break->class_name, new_break->class_len), new_break->class_len))) {
return FAILURE;
}
- func_table = &(*ce)->function_table;
+ func_table = &ce->function_table;
}
- if (zend_hash_find(func_table, zend_str_tolower_dup(new_break->func_name, new_break->func_len), new_break->func_len + 1, (void **)&func) == FAILURE) {
+ if (!(func = zend_hash_str_find_ptr(func_table, zend_str_tolower_dup(new_break->func_name, new_break->func_len), new_break->func_len))) {
if (new_break->class_name != NULL && new_break->func_name != NULL) {
- phpdbg_error("Method %s doesn't exist in class %s", new_break->func_name, new_break->class_name);
+ phpdbg_error("breakpoint", "type=\"nomethod\" method=\"%s::%s\"", "Method %s doesn't exist in class %s", new_break->func_name, new_break->class_name);
return 2;
}
return FAILURE;
@@ -482,9 +448,9 @@ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRML
if (func->type != ZEND_USER_FUNCTION) {
if (new_break->class_name == NULL) {
- phpdbg_error("%s is not an user defined function, no oplines exist", new_break->func_name);
+ phpdbg_error("breakpoint", "type=\"internalfunction\" function=\"%s\"", "%s is not an user defined function, no oplines exist", new_break->func_name);
} else {
- phpdbg_error("%s::%s is not an user defined method, no oplines exist", new_break->class_name, new_break->func_name);
+ phpdbg_error("breakpoint", "type=\"internalfunction\" method=\"%s::%s\"", "%s::%s is not an user defined method, no oplines exist", new_break->class_name, new_break->func_name);
}
return 2;
}
@@ -512,37 +478,29 @@ PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const cha
switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) {
case FAILURE:
- phpdbg_notice("Pending breakpoint #%d at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline);
+ phpdbg_notice("breakpoint", "pending=\"pending\" id=\"%d\" method=\"%::%s\" num=\"%ld\"", "Pending breakpoint #%d at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline);
break;
case SUCCESS:
- phpdbg_notice("Breakpoint #%d added at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline);
+ phpdbg_notice("breakpoint", "id=\"%d\" method=\"%::%s\" num=\"%ld\"", "Breakpoint #%d added at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline);
break;
case 2:
return;
}
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], new_break.class_name, new_break.class_len, (void **)&class_table) == FAILURE) {
+ if (!(class_table = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], new_break.class_name, new_break.class_len))) {
zend_hash_init(&class_breaks, 8, NULL, phpdbg_opline_class_breaks_dtor, 0);
- zend_hash_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE],
- new_break.class_name,
- new_break.class_len,
- (void **)&class_breaks, sizeof(HashTable), (void **)&class_table);
+ class_table = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], new_break.class_name, new_break.class_len, &class_breaks, sizeof(HashTable));
}
- if (zend_hash_find(class_table, new_break.func_name, new_break.func_len, (void **)&method_table) == FAILURE) {
+ if (!(method_table = zend_hash_str_find_ptr(class_table, new_break.func_name, new_break.func_len))) {
zend_hash_init(&method_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0);
- zend_hash_update(
- class_table,
- new_break.func_name,
- new_break.func_len,
- (void **)&method_breaks, sizeof(HashTable), (void **)&method_table);
+ method_table = zend_hash_str_update_mem(class_table, new_break.func_name, new_break.func_len, &method_breaks, sizeof(HashTable));
}
if (zend_hash_index_exists(method_table, opline)) {
- phpdbg_notice("Breakpoint already exists for %s::%s#%ld", new_break.class_name, new_break.func_name, opline);
+ phpdbg_error("breakpoint", "type=\"exists\" method=\"%s\" num=\"%ld\"", "Breakpoint already exists for %s::%s#%ld", new_break.class_name, new_break.func_name, opline);
efree((char*)new_break.func_name);
efree((char*)new_break.class_name);
PHPDBG_G(bp_count)--;
@@ -553,7 +511,7 @@ PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const cha
PHPDBG_BREAK_MAPPING(new_break.id, method_table);
- zend_hash_index_update(method_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL);
+ zend_hash_index_update_mem(method_table, opline, &new_break, sizeof(phpdbg_breakopline_t));
}
PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend_ulong opline TSRMLS_DC) /* {{{ */
@@ -571,28 +529,24 @@ PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend
switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) {
case FAILURE:
- phpdbg_notice("Pending breakpoint #%d at %s#%ld", new_break.id, new_break.func_name, opline);
+ phpdbg_notice("breakpoint", "pending=\"pending\" id=\"%d\" function=\"%s\" num=\"%ld\"", "Pending breakpoint #%d at %s#%ld", new_break.id, new_break.func_name, opline);
break;
case SUCCESS:
- phpdbg_notice("Breakpoint #%d added at %s#%ld", new_break.id, new_break.func_name, opline);
+ phpdbg_notice("breakpoint", "id=\"%d\" function=\"%s\" num=\"%ld\"", "Breakpoint #%d added at %s#%ld", new_break.id, new_break.func_name, opline);
break;
case 2:
return;
}
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], new_break.func_name, new_break.func_len, (void **)&func_table) == FAILURE) {
+ if (!(func_table = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], new_break.func_name, new_break.func_len))) {
zend_hash_init(&func_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0);
- zend_hash_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE],
- new_break.func_name,
- new_break.func_len,
- (void **)&func_breaks, sizeof(HashTable), (void **)&func_table);
+ func_table = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], new_break.func_name, new_break.func_len, &func_breaks, sizeof(HashTable));
}
if (zend_hash_index_exists(func_table, opline)) {
- phpdbg_notice("Breakpoint already exists for %s#%ld", new_break.func_name, opline);
+ phpdbg_error("breakpoint", "type=\"exists\" function=\"%s\" num=\"%ld\"", "Breakpoint already exists for %s#%ld", new_break.func_name, opline);
efree((char*)new_break.func_name);
PHPDBG_G(bp_count)--;
return;
@@ -602,7 +556,7 @@ PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend
PHPDBG_G(flags) |= PHPDBG_HAS_FUNCTION_OPLINE_BP;
- zend_hash_index_update(func_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL);
+ zend_hash_index_update_mem(func_table, opline, &new_break, sizeof(phpdbg_breakopline_t));
}
PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong opline TSRMLS_DC) /* {{{ */
@@ -620,28 +574,24 @@ PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong o
switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) {
case FAILURE:
- phpdbg_notice("Pending breakpoint #%d at %s:%ld", new_break.id, new_break.class_name, opline);
+ phpdbg_notice("breakpoint", "pending=\"pending\" id=\"%d\" file=\"%s\" num=\"%ld\"", "Pending breakpoint #%d at %s:%ld", new_break.id, new_break.class_name, opline);
break;
case SUCCESS:
- phpdbg_notice("Breakpoint #%d added at %s:%ld", new_break.id, new_break.class_name, opline);
+ phpdbg_notice("breakpoint", "id=\"%d\" file=\"%s\" num=\"%ld\"", "Breakpoint #%d added at %s:%ld", new_break.id, new_break.class_name, opline);
break;
case 2:
return;
}
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], new_break.class_name, new_break.class_len, (void **)&file_table) == FAILURE) {
+ if (!(file_table = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], new_break.class_name, new_break.class_len))) {
zend_hash_init(&file_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0);
- zend_hash_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE],
- new_break.class_name,
- new_break.class_len,
- (void **)&file_breaks, sizeof(HashTable), (void **)&file_table);
+ file_table = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], new_break.class_name, new_break.class_len, &file_breaks, sizeof(HashTable));
}
if (zend_hash_index_exists(file_table, opline)) {
- phpdbg_notice("Breakpoint already exists for %s:%ld", new_break.class_name, opline);
+ phpdbg_error("breakpoint", "type=\"exists\" file=\"%s\" num=\"%d\"", "Breakpoint already exists for %s:%ld", new_break.class_name, opline);
efree((char*)new_break.class_name);
PHPDBG_G(bp_count)--;
return;
@@ -651,7 +601,7 @@ PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong o
PHPDBG_G(flags) |= PHPDBG_HAS_FILE_OPLINE_BP;
- zend_hash_index_update(file_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL);
+ zend_hash_index_update_mem(file_table, opline, &new_break, sizeof(phpdbg_breakopline_t));
}
PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len TSRMLS_DC) /* {{{ */
@@ -660,8 +610,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len T
zend_ulong hash = zend_hash_func(name, name_len);
if (zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash)) {
- phpdbg_notice(
- "Breakpoint exists for %s", name);
+ phpdbg_error("breakpoint", "type=\"exists\" opcode=\"%s\"", "Breakpoint exists for %s", name);
return;
}
@@ -669,12 +618,11 @@ PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len T
new_break.hash = hash;
new_break.name = estrndup(name, name_len);
- zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash,
- &new_break, sizeof(phpdbg_breakop_t), NULL);
+ zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash, &new_break, sizeof(phpdbg_breakop_t));
PHPDBG_G(flags) |= PHPDBG_HAS_OPCODE_BP;
- phpdbg_notice("Breakpoint #%d added at %s", new_break.id, name);
+ phpdbg_notice("breakpoint", "id=\"%d\" opcode=\"%s\"", "Breakpoint #%d added at %s", new_break.id, name);
PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]);
} /* }}} */
@@ -688,12 +636,12 @@ PHPDBG_API void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t opline TSRML
PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_OPLINE);
new_break.opline = (zend_ulong) opline;
- zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE],
- (zend_ulong) opline, &new_break, sizeof(phpdbg_breakline_t), NULL);
+ zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (zend_ulong) opline, &new_break, sizeof(phpdbg_breakline_t));
- phpdbg_notice("Breakpoint #%d added at %#lx",
- new_break.id, new_break.opline);
+ phpdbg_notice("breakpoint", "id=\"%d\" opline=\"%#lx\"", "Breakpoint #%d added at %#lx", new_break.id, new_break.opline);
PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
+ } else {
+ phpdbg_error("breakpoint", "type=\"exists\" opline=\"%#lx\"", "Breakpoint exists for opline %#lx", (zend_ulong) opline);
}
} /* }}} */
@@ -721,35 +669,30 @@ static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, co
new_break.code = estrndup(expr, expr_len);
new_break.code_len = expr_len;
- Z_STRLEN(pv) = expr_len + sizeof("return ;") - 1;
- Z_STRVAL(pv) = emalloc(Z_STRLEN(pv) + 1);
+ Z_STR(pv) = zend_string_alloc(expr_len + sizeof("return ;") - 1, 0);
memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1);
memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, expr, expr_len);
Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';';
Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0';
- Z_TYPE(pv) = IS_STRING;
+ Z_TYPE_INFO(pv) = IS_STRING;
- new_break.ops = zend_compile_string(
- &pv, "Conditional Breakpoint Code" TSRMLS_CC);
+ new_break.ops = zend_compile_string(&pv, "Conditional Breakpoint Code" TSRMLS_CC);
zval_dtor(&pv);
if (new_break.ops) {
- zend_hash_index_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash, &new_break,
- sizeof(phpdbg_breakcond_t), (void**)&brake);
+ brake = zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash, &new_break, sizeof(phpdbg_breakcond_t));
- phpdbg_notice("Conditional breakpoint #%d added %s/%p",
- brake->id, brake->code, brake->ops);
+ phpdbg_notice("breakpoint", "id=\"%d\" expression=\"%s\" ptr=\"%p\"", "Conditional breakpoint #%d added %s/%p", brake->id, brake->code, brake->ops);
PHPDBG_G(flags) |= PHPDBG_HAS_COND_BP;
PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
} else {
- phpdbg_error(
- "Failed to compile code for expression %s", expr);
+ phpdbg_error("compile", "expression=\"%s\"", "Failed to compile code for expression %s", expr);
efree((char*)new_break.code);
PHPDBG_G(bp_count)--;
}
+
CG(compiler_options) = cops;
} /* }}} */
@@ -762,7 +705,7 @@ PHPDBG_API void phpdbg_set_breakpoint_expression(const char *expr, size_t expr_l
phpdbg_create_conditional_break(
&new_break, NULL, expr, expr_len, expr_hash TSRMLS_CC);
} else {
- phpdbg_notice("Conditional break %s exists", expr);
+ phpdbg_error("breakpoint", "type=\"exists\" expression=\"%s\"", "Conditional break %s exists", expr);
}
} /* }}} */
@@ -771,35 +714,30 @@ PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param TSRMLS_DC)
phpdbg_breakcond_t new_break;
phpdbg_param_t *condition;
zend_ulong hash = 0L;
-
+
if (param->next) {
condition = param->next;
hash = zend_inline_hash_func(condition->str, condition->len);
-
+
if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash)) {
- phpdbg_create_conditional_break(
- &new_break, param,
- condition->str, condition->len, hash TSRMLS_CC);
+ phpdbg_create_conditional_break(&new_break, param, condition->str, condition->len, hash TSRMLS_CC);
} else {
- phpdbg_notice(
- "Conditional break %s exists at the specified location", condition->str);
- }
+ phpdbg_notice("breakpoint", "type=\"exists\" arg=\"%s\"", "Conditional break %s exists at the specified location", condition->str);
+ }
}
-
+
} /* }}} */
static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_array TSRMLS_DC) /* {{{ */
{
HashTable *breaks;
phpdbg_breakbase_t *brake;
- size_t name_len = strlen(op_array->filename);
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], op_array->filename,
- name_len, (void**)&breaks) == FAILURE) {
+ if (!(breaks = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], op_array->filename))) {
return NULL;
}
- if (zend_hash_index_find(breaks, (*EG(opline_ptr))->lineno, (void**)&brake) == SUCCESS) {
+ if (EG(current_execute_data) && (brake = zend_hash_index_find_ptr(breaks, EG(current_execute_data)->opline->lineno))) {
return brake;
}
@@ -809,88 +747,73 @@ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_
static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_symbol(zend_function *fbc TSRMLS_DC) /* {{{ */
{
const char *fname;
+ size_t flen;
zend_op_array *ops;
- phpdbg_breakbase_t *brake;
if (fbc->type != ZEND_USER_FUNCTION) {
return NULL;
}
- ops = (zend_op_array*)fbc;
+ ops = (zend_op_array *) fbc;
if (ops->scope) {
/* find method breaks here */
return phpdbg_find_breakpoint_method(ops TSRMLS_CC);
}
- fname = ops->function_name;
-
- if (!fname) {
+ if (ops->function_name) {
+ fname = ops->function_name->val;
+ flen = ops->function_name->len;
+ } else {
fname = "main";
+ flen = 4;
}
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], fname, strlen(fname), (void**)&brake) == SUCCESS) {
- return brake;
- }
-
- return NULL;
+ return zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], fname, flen);
} /* }}} */
static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_method(zend_op_array *ops TSRMLS_DC) /* {{{ */
{
HashTable *class_table;
- phpdbg_breakbase_t *brake;
+ phpdbg_breakbase_t *brake = NULL;
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], ops->scope->name,
- ops->scope->name_length, (void**)&class_table) == SUCCESS) {
- char *lcname = zend_str_tolower_dup(ops->function_name, strlen(ops->function_name));
- size_t lcname_len = strlen(lcname);
-
- if (zend_hash_find(
- class_table,
- lcname,
- lcname_len, (void**)&brake) == SUCCESS) {
- efree(lcname);
- return brake;
- }
+ if ((class_table = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], ops->scope->name))) {
+ size_t lcname_len = ops->function_name->len;
+ char *lcname = zend_str_tolower_dup(ops->function_name->val, lcname_len);
+
+ brake = zend_hash_str_find_ptr(class_table, lcname, lcname_len);
efree(lcname);
}
- return NULL;
+ return brake;
} /* }}} */
static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opline(phpdbg_opline_ptr_t opline TSRMLS_DC) /* {{{ */
{
phpdbg_breakline_t *brake;
- if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE],
- (zend_ulong) opline, (void**)&brake) == SUCCESS) {
- return (brake->base?(phpdbg_breakbase_t *)brake->base:(phpdbg_breakbase_t *)brake);
+ if ((brake = zend_hash_index_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (zend_ulong) opline)) && brake->base) {
+ return (phpdbg_breakbase_t *)brake->base;
}
- return NULL;
+ return (phpdbg_breakbase_t *) brake;
} /* }}} */
static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opcode(zend_uchar opcode TSRMLS_DC) /* {{{ */
{
- phpdbg_breakbase_t *brake;
const char *opname = phpdbg_decode_opcode(opcode);
if (memcmp(opname, PHPDBG_STRL("UNKNOWN")) == 0) {
return NULL;
}
- if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE],
- zend_hash_func(opname, strlen(opname)), (void**)&brake) == SUCCESS) {
- return brake;
- }
- return NULL;
+ return zend_hash_index_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], zend_hash_func(opname, strlen(opname)));
} /* }}} */
static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
{
- zend_function *function = (zend_function*) execute_data->function_state.function;
+ zend_function *function = execute_data->func;
switch (param->type) {
case NUMERIC_FUNCTION_PARAM:
@@ -905,8 +828,8 @@ static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend
const char *str = NULL;
size_t len = 0L;
zend_op_array *ops = (zend_op_array*)function;
- str = ops->function_name ? ops->function_name : "main";
- len = strlen(str);
+ str = ops->function_name ? ops->function_name->val : "main";
+ len = ops->function_name ? ops->function_name->len : strlen(str);
if (len == param->len && memcmp(param->str, str, len) == SUCCESS) {
return param->type == STR_PARAM || execute_data->opline - ops->opcodes == param->num;
@@ -936,10 +859,10 @@ static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend
zend_op_array *ops = (zend_op_array*) function;
if (ops->scope) {
- size_t lengths[2] = {strlen(param->method.class), ops->scope->name_length};
+ size_t lengths[2] = { strlen(param->method.class), ops->scope->name->len };
if (lengths[0] == lengths[1] && memcmp(param->method.class, ops->scope->name, lengths[0]) == SUCCESS) {
lengths[0] = strlen(param->method.name);
- lengths[1] = strlen(ops->function_name);
+ lengths[1] = ops->function_name->len;
if (lengths[0] == lengths[1] && memcmp(param->method.name, ops->function_name, lengths[0]) == SUCCESS) {
return param->type == METHOD_PARAM || (execute_data->opline - ops->opcodes) == param->num;
@@ -963,16 +886,13 @@ static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend
static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
{
phpdbg_breakcond_t *bp;
- HashPosition position;
int breakpoint = FAILURE;
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void*)&bp, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) {
- zval *retval = NULL;
- zval **orig_retval = EG(return_value_ptr_ptr);
- zend_op_array *orig_ops = EG(active_op_array);
- zend_op **orig_opline = EG(opline_ptr);
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], bp) {
+ zval retval;
+ const zend_op *orig_opline = EG(current_execute_data)->opline;
+ zend_function *orig_func = EG(current_execute_data)->func;
+ zval *orig_retval = EG(current_execute_data)->return_value;
if (((phpdbg_breakbase_t*)bp)->disabled) {
continue;
@@ -984,49 +904,37 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut
}
}
- ALLOC_INIT_ZVAL(retval);
-
- EG(return_value_ptr_ptr) = &retval;
- EG(active_op_array) = bp->ops;
EG(no_extensions) = 1;
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
+ zend_rebuild_symbol_table(TSRMLS_C);
zend_try {
PHPDBG_G(flags) |= PHPDBG_IN_COND_BP;
- zend_execute(EG(active_op_array) TSRMLS_CC);
+ zend_execute(bp->ops, &retval TSRMLS_CC);
#if PHP_VERSION_ID >= 50700
- if (zend_is_true(retval TSRMLS_CC)) {
+ if (zend_is_true(&retval TSRMLS_CC)) {
#else
- if (zend_is_true(retval)) {
+ if (zend_is_true(&retval)) {
#endif
breakpoint = SUCCESS;
}
- } zend_catch {
- EG(no_extensions)=1;
- EG(return_value_ptr_ptr) = orig_retval;
- EG(active_op_array) = orig_ops;
- EG(opline_ptr) = orig_opline;
- PHPDBG_G(flags) &= ~PHPDBG_IN_COND_BP;
} zend_end_try();
- EG(no_extensions)=1;
- EG(return_value_ptr_ptr) = orig_retval;
- EG(active_op_array) = orig_ops;
- EG(opline_ptr) = orig_opline;
+ EG(no_extensions) = 1;
+ EG(current_execute_data)->opline = orig_opline;
+ EG(current_execute_data)->func = orig_func;
+ EG(current_execute_data)->return_value = orig_retval;
PHPDBG_G(flags) &= ~PHPDBG_IN_COND_BP;
if (breakpoint == SUCCESS) {
break;
}
- }
+ } ZEND_HASH_FOREACH_END();
- return (breakpoint == SUCCESS) ? ((phpdbg_breakbase_t*)bp) : NULL;
+ return (breakpoint == SUCCESS) ? ((phpdbg_breakbase_t *) bp) : NULL;
} /* }}} */
-PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakpoint(zend_execute_data* execute_data TSRMLS_DC) /* {{{ */
+PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakpoint(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
{
phpdbg_breakbase_t *base = NULL;
@@ -1041,28 +949,24 @@ PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakpoint(zend_execute_data* execute
goto result;
}
- if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP) &&
- (base = phpdbg_find_breakpoint_file(execute_data->op_array TSRMLS_CC))) {
+ if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP) && (base = phpdbg_find_breakpoint_file(&execute_data->func->op_array TSRMLS_CC))) {
goto result;
}
if (PHPDBG_G(flags) & (PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_SYM_BP)) {
/* check we are at the beginning of the stack */
- if (execute_data->opline == EG(active_op_array)->opcodes) {
- if ((base = phpdbg_find_breakpoint_symbol(
- execute_data->function_state.function TSRMLS_CC))) {
+ if (execute_data->opline == execute_data->func->op_array.opcodes) {
+ if ((base = phpdbg_find_breakpoint_symbol(execute_data->func TSRMLS_CC))) {
goto result;
}
}
}
- if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP) &&
- (base = phpdbg_find_breakpoint_opline(execute_data->opline TSRMLS_CC))) {
+ if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP) && (base = phpdbg_find_breakpoint_opline((phpdbg_opline_ptr_t) execute_data->opline TSRMLS_CC))) {
goto result;
}
- if ((PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) &&
- (base = phpdbg_find_breakpoint_opcode(execute_data->opline->opcode TSRMLS_CC))) {
+ if ((PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) && (base = phpdbg_find_breakpoint_opcode(execute_data->opline->opcode TSRMLS_CC))) {
goto result;
}
@@ -1079,14 +983,12 @@ result:
PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */
{
- HashTable **table;
- HashPosition position;
+ HashTable *table;
phpdbg_breakbase_t *brake;
+ zend_string *strkey;
+ zend_ulong numkey;
- if ((brake = phpdbg_find_breakbase_ex(num, &table, &position TSRMLS_CC))) {
- char *key;
- uint32_t klen;
- zend_ulong idx;
+ if ((brake = phpdbg_find_breakbase_ex(num, &table, &numkey, &strkey TSRMLS_CC))) {
int type = brake->type;
char *name = NULL;
size_t name_len = 0L;
@@ -1094,7 +996,7 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */
switch (type) {
case PHPDBG_BREAK_FILE:
case PHPDBG_BREAK_METHOD:
- if (zend_hash_num_elements((*table)) == 1) {
+ if (zend_hash_num_elements(table) == 1) {
name = estrdup(brake->name);
name_len = strlen(name);
if (zend_hash_num_elements(&PHPDBG_G(bp)[type]) == 1) {
@@ -1104,7 +1006,7 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */
break;
default: {
- if (zend_hash_num_elements((*table)) == 1) {
+ if (zend_hash_num_elements(table) == 1) {
PHPDBG_G(flags) &= ~(1<<(brake->type+1));
}
}
@@ -1117,34 +1019,29 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */
if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]) == 1) {
PHPDBG_G(flags) &= PHPDBG_HAS_OPLINE_BP;
}
- zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], ((phpdbg_breakopline_t*)brake)->opline);
+ zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], ((phpdbg_breakopline_t *) brake)->opline);
}
- switch (zend_hash_get_current_key_ex(
- (*table), &key, &klen, &idx, 0, &position)) {
-
- case HASH_KEY_IS_STRING:
- zend_hash_del((*table), key, klen);
- break;
-
- default:
- zend_hash_index_del((*table), idx);
+ if (strkey) {
+ zend_hash_del(table, strkey);
+ } else {
+ zend_hash_index_del(table, numkey);
}
switch (type) {
case PHPDBG_BREAK_FILE:
case PHPDBG_BREAK_METHOD:
if (name) {
- zend_hash_del(&PHPDBG_G(bp)[type], name, name_len);
+ zend_hash_str_del(&PHPDBG_G(bp)[type], name, name_len);
efree(name);
}
break;
}
- phpdbg_notice("Deleted breakpoint #%ld", num);
+ phpdbg_notice("breakpoint", "deleted=\"success\" id=\"%ld\"", "Deleted breakpoint #%ld", num);
PHPDBG_BREAK_UNMAPPING(num);
} else {
- phpdbg_error("Failed to find breakpoint #%ld", num);
+ phpdbg_error("breakpoint", "type=\"nobreakpoint\" deleted=\"fail\" id=\"%ld\"", "Failed to find breakpoint #%ld", num);
}
} /* }}} */
@@ -1182,7 +1079,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /*
switch (brake->type) {
case PHPDBG_BREAK_FILE: {
- phpdbg_notice("Breakpoint #%d at %s:%ld, hits: %lu",
+ phpdbg_notice("breakpoint", "id=\"%d\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d at %s:%ld, hits: %lu",
((phpdbg_breakfile_t*)brake)->id,
((phpdbg_breakfile_t*)brake)->filename,
((phpdbg_breakfile_t*)brake)->line,
@@ -1190,7 +1087,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /*
} break;
case PHPDBG_BREAK_SYM: {
- phpdbg_notice("Breakpoint #%d in %s() at %s:%u, hits: %lu",
+ phpdbg_notice("breakpoint", "id=\"%d\" function=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s() at %s:%u, hits: %lu",
((phpdbg_breaksymbol_t*)brake)->id,
((phpdbg_breaksymbol_t*)brake)->symbol,
zend_get_executed_filename(TSRMLS_C),
@@ -1199,7 +1096,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /*
} break;
case PHPDBG_BREAK_OPLINE: {
- phpdbg_notice("Breakpoint #%d in %#lx at %s:%u, hits: %lu",
+ phpdbg_notice("breakpoint", "id=\"%d\" opline=\"%#lx\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %#lx at %s:%u, hits: %lu",
((phpdbg_breakline_t*)brake)->id,
((phpdbg_breakline_t*)brake)->opline,
zend_get_executed_filename(TSRMLS_C),
@@ -1208,7 +1105,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /*
} break;
case PHPDBG_BREAK_METHOD_OPLINE: {
- phpdbg_notice("Breakpoint #%d in %s::%s()#%lu at %s:%u, hits: %lu",
+ phpdbg_notice("breakpoint", "id=\"%d\" method=\"%s::%s\" num=\"%lu\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s::%s()#%lu at %s:%u, hits: %lu",
((phpdbg_breakopline_t*)brake)->id,
((phpdbg_breakopline_t*)brake)->class_name,
((phpdbg_breakopline_t*)brake)->func_name,
@@ -1219,7 +1116,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /*
} break;
case PHPDBG_BREAK_FUNCTION_OPLINE: {
- phpdbg_notice("Breakpoint #%d in %s()#%lu at %s:%u, hits: %lu",
+ phpdbg_notice("breakpoint", "id=\"%d\" num=\"%lu\" function=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s()#%lu at %s:%u, hits: %lu",
((phpdbg_breakopline_t*)brake)->id,
((phpdbg_breakopline_t*)brake)->func_name,
((phpdbg_breakopline_t*)brake)->opline_num,
@@ -1229,9 +1126,8 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /*
} break;
case PHPDBG_BREAK_FILE_OPLINE: {
- phpdbg_notice("Breakpoint #%d in %s:%lu at %s:%u, hits: %lu",
+ phpdbg_notice("breakpoint", "id=\"%d\" num=\"%lu\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in #%lu at %s:%u, hits: %lu",
((phpdbg_breakopline_t*)brake)->id,
- ((phpdbg_breakopline_t*)brake)->class_name,
((phpdbg_breakopline_t*)brake)->opline_num,
zend_get_executed_filename(TSRMLS_C),
zend_get_executed_lineno(TSRMLS_C),
@@ -1239,7 +1135,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /*
} break;
case PHPDBG_BREAK_OPCODE: {
- phpdbg_notice("Breakpoint #%d in %s at %s:%u, hits: %lu",
+ phpdbg_notice("breakpoint", "id=\"%d\" opcode=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s at %s:%u, hits: %lu",
((phpdbg_breakop_t*)brake)->id,
((phpdbg_breakop_t*)brake)->name,
zend_get_executed_filename(TSRMLS_C),
@@ -1248,7 +1144,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /*
} break;
case PHPDBG_BREAK_METHOD: {
- phpdbg_notice("Breakpoint #%d in %s::%s() at %s:%u, hits: %lu",
+ phpdbg_notice("breakpoint", "id=\"%d\" method=\"%s::%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s::%s() at %s:%u, hits: %lu",
((phpdbg_breakmethod_t*)brake)->id,
((phpdbg_breakmethod_t*)brake)->class_name,
((phpdbg_breakmethod_t*)brake)->func_name,
@@ -1260,7 +1156,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /*
case PHPDBG_BREAK_COND: {
if (((phpdbg_breakcond_t*)brake)->paramed) {
char *param;
- phpdbg_notice("Conditional breakpoint #%d: at %s if %s %s:%u, hits: %lu",
+ phpdbg_notice("breakpoint", "id=\"%d\" location=\"%s\" eval=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Conditional breakpoint #%d: at %s if %s at %s:%u, hits: %lu",
((phpdbg_breakcond_t*)brake)->id,
phpdbg_param_tostring(&((phpdbg_breakcond_t*)brake)->param, &param TSRMLS_CC),
((phpdbg_breakcond_t*)brake)->code,
@@ -1270,7 +1166,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /*
if (param)
free(param);
} else {
- phpdbg_notice("Conditional breakpoint #%d: on %s == true %s:%u, hits: %lu",
+ phpdbg_notice("breakpoint", "id=\"%d\" eval=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Conditional breakpoint #%d: on %s == true at %s:%u, hits: %lu",
((phpdbg_breakcond_t*)brake)->id,
((phpdbg_breakcond_t*)brake)->code,
zend_get_executed_filename(TSRMLS_C),
@@ -1282,7 +1178,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /*
default: {
unknown:
- phpdbg_notice("Unknown breakpoint at %s:%u",
+ phpdbg_notice("breakpoint", "id=\"\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Unknown breakpoint at %s:%u",
zend_get_executed_filename(TSRMLS_C),
zend_get_executed_lineno(TSRMLS_C));
}
@@ -1318,313 +1214,236 @@ PHPDBG_API void phpdbg_disable_breakpoints(TSRMLS_D) { /* {{{ */
PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC) /* {{{ */
{
- HashTable **table;
- HashPosition position;
+ HashTable *table;
+ zend_string *strkey;
+ zend_ulong numkey;
- return phpdbg_find_breakbase_ex(id, &table, &position TSRMLS_CC);
+ return phpdbg_find_breakbase_ex(id, &table, &numkey, &strkey TSRMLS_CC);
} /* }}} */
-PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable ***table, HashPosition *position TSRMLS_DC) /* {{{ */
+PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable **table, zend_ulong *numkey, zend_string **strkey TSRMLS_DC) /* {{{ */
{
- if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id, (void**)table) == SUCCESS) {
+ if ((*table = zend_hash_index_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id))) {
phpdbg_breakbase_t *brake;
- for (zend_hash_internal_pointer_reset_ex((**table), position);
- zend_hash_get_current_data_ex((**table), (void**)&brake, position) == SUCCESS;
- zend_hash_move_forward_ex((**table), position)) {
-
+ ZEND_HASH_FOREACH_KEY_PTR(*table, *numkey, *strkey, brake) {
if (brake->id == id) {
return brake;
}
- }
+ } ZEND_HASH_FOREACH_END();
}
+
return NULL;
} /* }}} */
PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */
{
+ phpdbg_xml("<breakpoints %r>");
+
switch (type) {
case PHPDBG_BREAK_SYM: if ((PHPDBG_G(flags) & PHPDBG_HAS_SYM_BP)) {
- HashPosition position;
phpdbg_breaksymbol_t *brake;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Function Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position)) {
- phpdbg_writeln("#%d\t\t%s%s",
+ phpdbg_out(SEPARATE "\n");
+ phpdbg_out("Function Breakpoints:\n");
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], brake) {
+ phpdbg_writeln("function", "id=\"%d\" name=\"%s\" disabled=\"%s\"", "#%d\t\t%s%s",
brake->id, brake->symbol,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_METHOD: if ((PHPDBG_G(flags) & PHPDBG_HAS_METHOD_BP)) {
- HashPosition position[2];
HashTable *class_table;
- char *class_name = NULL;
- uint32_t class_len = 0;
- zend_ulong class_idx = 0L;
-
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Method Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], (void**) &class_table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0])) {
-
- if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD],
- &class_name, &class_len, &class_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
- phpdbg_breakmethod_t *brake;
-
- for (zend_hash_internal_pointer_reset_ex(class_table, &position[1]);
- zend_hash_get_current_data_ex(class_table, (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(class_table, &position[1])) {
- phpdbg_writeln("#%d\t\t%s::%s%s",
- brake->id, brake->class_name, brake->func_name,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
- }
+ phpdbg_out(SEPARATE "\n");
+ phpdbg_out("Method Breakpoints:\n");
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_table) {
+ phpdbg_breakmethod_t *brake;
+
+ ZEND_HASH_FOREACH_PTR(class_table, brake) {
+ phpdbg_writeln("method", "id=\"%d\" name=\"%s::%s\" disabled=\"%s\"", "#%d\t\t%s::%s%s",
+ brake->id, brake->class_name, brake->func_name,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_FILE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP)) {
- HashPosition position[2];
HashTable *points;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("File Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], (void**) &points, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0])) {
+ phpdbg_out(SEPARATE "\n");
+ phpdbg_out("File Breakpoints:\n");
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], points) {
phpdbg_breakfile_t *brake;
- for (zend_hash_internal_pointer_reset_ex(points, &position[1]);
- zend_hash_get_current_data_ex(points, (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(points, &position[1])) {
- phpdbg_writeln("#%d\t\t%s:%lu%s",
+ ZEND_HASH_FOREACH_PTR(points, brake) {
+ phpdbg_writeln("file", "id=\"%d\" name=\"%s\" line=\"%lu\" disabled=\"%s\"", "#%d\t\t%s:%lu%s",
brake->id, brake->filename, brake->line,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP)) {
- HashPosition position;
phpdbg_breakline_t *brake;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Opline Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position)) {
+ phpdbg_out(SEPARATE "\n");
+ phpdbg_out("Opline Breakpoints:\n");
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], brake) {
+ const char *type;
switch (brake->type) {
case PHPDBG_BREAK_METHOD_OPLINE:
+ type = "method";
+ goto print_opline;
case PHPDBG_BREAK_FUNCTION_OPLINE:
+ type = "function";
+ goto print_opline;
case PHPDBG_BREAK_FILE_OPLINE:
- phpdbg_writeln("#%d\t\t%#lx\t\t(%s breakpoint)%s", brake->id, brake->opline,
- brake->type == PHPDBG_BREAK_METHOD_OPLINE?"method":
- brake->type == PHPDBG_BREAK_FUNCTION_OPLINE?"function":
- brake->type == PHPDBG_BREAK_FILE_OPLINE?"file":
- "--- error ---",
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- break;
+ type = "method";
+
+ print_opline: {
+ if (brake->type == PHPDBG_BREAK_METHOD_OPLINE) {
+ type = "method";
+ } else if (brake->type == PHPDBG_BREAK_FUNCTION_OPLINE) {
+ type = "function";
+ } else if (brake->type == PHPDBG_BREAK_FILE_OPLINE) {
+ type = "file";
+ }
+
+ phpdbg_writeln("opline", "id=\"%d\" num=\"%#lx\" type=\"%s\" disabled=\"%s\"", "#%d\t\t%#lx\t\t(%s breakpoint)%s",
+ brake->id, brake->opline, type,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } break;
default:
- phpdbg_writeln("#%d\t\t%#lx", brake->id, brake->opline);
+ phpdbg_writeln("opline", "id=\"%d\" num=\"%#lx\" disabled=\"%s\"", "#%d\t\t%#lx%s",
+ brake->id, brake->opline,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
break;
}
- }
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_METHOD_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_METHOD_OPLINE_BP)) {
- HashPosition position[3];
HashTable *class_table, *method_table;
- char *class_name = NULL, *method_name = NULL;
- uint32_t class_len = 0, method_len = 0;
- zend_ulong class_idx = 0L, method_idx = 0L;
-
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Method opline Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], (void**) &class_table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0])) {
-
- if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE],
- &class_name, &class_len, &class_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
-
- for (zend_hash_internal_pointer_reset_ex(class_table, &position[1]);
- zend_hash_get_current_data_ex(class_table, (void**) &method_table, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(class_table, &position[1])) {
-
- if (zend_hash_get_current_key_ex(class_table,
- &method_name, &method_len, &method_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
-
- phpdbg_breakopline_t *brake;
-
- for (zend_hash_internal_pointer_reset_ex(method_table, &position[2]);
- zend_hash_get_current_data_ex(method_table, (void**)&brake, &position[2]) == SUCCESS;
- zend_hash_move_forward_ex(method_table, &position[2])) {
- phpdbg_writeln("#%d\t\t%s::%s opline %ld%s",
- brake->id, brake->class_name, brake->func_name, brake->opline_num,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
- }
- }
- }
+ phpdbg_out(SEPARATE "\n");
+ phpdbg_out("Method opline Breakpoints:\n");
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], class_table) {
+ ZEND_HASH_FOREACH_PTR(class_table, method_table) {
+ phpdbg_breakopline_t *brake;
+
+ ZEND_HASH_FOREACH_PTR(method_table, brake) {
+ phpdbg_writeln("methodopline", "id=\"%d\" name=\"%s::%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s::%s opline %ld%s",
+ brake->id, brake->class_name, brake->func_name, brake->opline_num,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_FUNCTION_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FUNCTION_OPLINE_BP)) {
- HashPosition position[2];
HashTable *function_table;
- char *function_name = NULL;
- uint32_t function_len = 0;
- zend_ulong function_idx = 0L;
-
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Function opline Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], (void**) &function_table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0])) {
- if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE],
- &function_name, &function_len, &function_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
-
- phpdbg_breakopline_t *brake;
-
- for (zend_hash_internal_pointer_reset_ex(function_table, &position[1]);
- zend_hash_get_current_data_ex(function_table, (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(function_table, &position[1])) {
- phpdbg_writeln("#%d\t\t%s opline %ld%s",
- brake->id, brake->func_name, brake->opline_num,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
-
- }
+ phpdbg_out(SEPARATE "\n");
+ phpdbg_out("Function opline Breakpoints:\n");
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], function_table) {
+ phpdbg_breakopline_t *brake;
+
+ ZEND_HASH_FOREACH_PTR(function_table, brake) {
+ phpdbg_writeln("functionopline", "id=\"%d\" name=\"%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s opline %ld%s",
+ brake->id, brake->func_name, brake->opline_num,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_FILE_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_OPLINE_BP)) {
- HashPosition position[2];
HashTable *file_table;
- char *file_name = NULL;
- uint32_t file_len = 0;
- zend_ulong file_idx = 0L;
-
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("File opline Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], (void**) &file_table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0])) {
-
- if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE],
- &file_name, &file_len, &file_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
-
- phpdbg_breakopline_t *brake;
- for (zend_hash_internal_pointer_reset_ex(file_table, &position[1]);
- zend_hash_get_current_data_ex(file_table, (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(file_table, &position[1])) {
- phpdbg_writeln("#%d\t\t%s opline %ld%s",
- brake->id, brake->class_name, brake->opline_num,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
- }
+ phpdbg_out(SEPARATE "\n");
+ phpdbg_out("File opline Breakpoints:\n");
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], file_table) {
+ phpdbg_breakopline_t *brake;
+
+ ZEND_HASH_FOREACH_PTR(file_table, brake) {
+ phpdbg_writeln("fileopline", "id=\"%d\" name=\"%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s opline %ld%s",
+ brake->id, brake->class_name, brake->opline_num,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_COND: if ((PHPDBG_G(flags) & PHPDBG_HAS_COND_BP)) {
- HashPosition position;
phpdbg_breakcond_t *brake;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Conditional Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) {
+ phpdbg_out(SEPARATE "\n");
+ phpdbg_out("Conditional Breakpoints:\n");
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], brake) {
if (brake->paramed) {
switch (brake->param.type) {
case STR_PARAM:
- phpdbg_writeln("#%d\t\tat %s if %s%s",
- brake->id,
- brake->param.str,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
+ phpdbg_writeln("evalfunction", "id=\"%d\" name=\"%s\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s if %s%s",
+ brake->id, brake->param.str, brake->code,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
break;
case NUMERIC_FUNCTION_PARAM:
- phpdbg_writeln("#%d\t\tat %s#%ld if %s%s",
- brake->id,
- brake->param.str,
- brake->param.num,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
+ phpdbg_writeln("evalfunctionopline", "id=\"%d\" name=\"%s\" num=\"%ld\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s#%ld if %s%s",
+ brake->id, brake->param.str, brake->param.num, brake->code,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
break;
case METHOD_PARAM:
- phpdbg_writeln("#%d\t\tat %s::%s if %s%s",
- brake->id,
- brake->param.method.class,
- brake->param.method.name,
- brake->code,
+ phpdbg_writeln("evalmethod", "id=\"%d\" name=\"%s::%s\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s::%s if %s%s",
+ brake->id, brake->param.method.class, brake->param.method.name, brake->code,
((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
break;
case NUMERIC_METHOD_PARAM:
- phpdbg_writeln("#%d\t\tat %s::%s#%ld if %s%s",
- brake->id,
- brake->param.method.class,
- brake->param.method.name,
- brake->param.num,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
+ phpdbg_writeln("evalmethodopline", "id=\"%d\" name=\"%s::%s\" num=\"%d\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s::%s#%ld if %s%s",
+ brake->id, brake->param.method.class, brake->param.method.name, brake->param.num, brake->code,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
break;
case FILE_PARAM:
- phpdbg_writeln("#%d\t\tat %s:%lu if %s%s",
- brake->id,
- brake->param.file.name,
- brake->param.file.line,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
+ phpdbg_writeln("evalfile", "id=\"%d\" name=\"%s\" line=\"%d\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s:%lu if %s%s",
+ brake->id, brake->param.file.name, brake->param.file.line, brake->code,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
break;
case ADDR_PARAM:
- phpdbg_writeln("#%d\t\tat #%lx if %s%s",
- brake->id,
- brake->param.addr,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
+ phpdbg_writeln("evalopline", "id=\"%d\" opline=\"%#lx\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat #%lx if %s%s",
+ brake->id, brake->param.addr, brake->code,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
break;
default:
- phpdbg_error("Invalid parameter type for conditional breakpoint");
+ phpdbg_error("eval", "type=\"invalidparameter\"", "Invalid parameter type for conditional breakpoint");
return;
}
} else {
- phpdbg_writeln("#%d\t\tif %s%s",
+ phpdbg_writeln("eval", "id=\"%d\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tif %s%s",
brake->id, brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
}
- }
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_OPCODE: if (PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) {
- HashPosition position;
phpdbg_breakop_t *brake;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Opcode Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position)) {
- phpdbg_writeln("#%d\t\t%s%s",
+ phpdbg_out(SEPARATE "\n");
+ phpdbg_out("Opcode Breakpoints:\n");
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], brake) {
+ phpdbg_writeln("opcode", "id=\"%d\" name=\"%s\" disabled=\"%s\"", "#%d\t\t%s%s",
brake->id, brake->name,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
} break;
}
+
+ phpdbg_xml("</breakpoints>");
} /* }}} */
diff --git a/sapi/phpdbg/phpdbg_bp.h b/sapi/phpdbg/phpdbg_bp.h
index 9c3f097d78..4090d90f91 100644
--- a/sapi/phpdbg/phpdbg_bp.h
+++ b/sapi/phpdbg/phpdbg_bp.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -21,6 +21,19 @@
#ifndef PHPDBG_BP_H
#define PHPDBG_BP_H
+/* {{{ defines */
+#define PHPDBG_BREAK_FILE 0
+#define PHPDBG_BREAK_SYM 1
+#define PHPDBG_BREAK_OPLINE 2
+#define PHPDBG_BREAK_METHOD 3
+#define PHPDBG_BREAK_COND 4
+#define PHPDBG_BREAK_OPCODE 5
+#define PHPDBG_BREAK_FUNCTION_OPLINE 6
+#define PHPDBG_BREAK_METHOD_OPLINE 7
+#define PHPDBG_BREAK_FILE_OPLINE 8
+#define PHPDBG_BREAK_MAP 9
+#define PHPDBG_BREAK_TABLES 10 /* }}} */
+
/* {{{ */
typedef struct _zend_op *phpdbg_opline_ptr_t; /* }}} */
@@ -138,7 +151,7 @@ PHPDBG_API void phpdbg_disable_breakpoints(TSRMLS_D); /* }}} */
/* {{{ Breakbase API */
PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC);
-PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable ***table, HashPosition *position TSRMLS_DC); /* }}} */
+PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable **table, zend_ulong *numkey, zend_string **strkey TSRMLS_DC); /* }}} */
/* {{{ Breakpoint Exportation API */
PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC); /* }}} */
diff --git a/sapi/phpdbg/phpdbg_break.c b/sapi/phpdbg/phpdbg_break.c
index d04f2f8bb4..386d4d9562 100644
--- a/sapi/phpdbg/phpdbg_break.c
+++ b/sapi/phpdbg/phpdbg_break.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -28,15 +28,15 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-#define PHPDBG_BREAK_COMMAND_D(f, h, a, m, l, s) \
- PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[10])
+#define PHPDBG_BREAK_COMMAND_D(f, h, a, m, l, s, flags) \
+ PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[10], flags)
/**
* Commands
*/
const phpdbg_command_t phpdbg_break_commands[] = {
- PHPDBG_BREAK_COMMAND_D(at, "specify breakpoint by location and condition", '@', break_at, NULL, "*c"),
- PHPDBG_BREAK_COMMAND_D(del, "delete breakpoint by identifier number", '~', break_del, NULL, "n"),
+ PHPDBG_BREAK_COMMAND_D(at, "specify breakpoint by location and condition", '@', break_at, NULL, "*c", 0),
+ PHPDBG_BREAK_COMMAND_D(del, "delete breakpoint by identifier number", '~', break_del, NULL, "n", 0),
PHPDBG_END_COMMAND
};
diff --git a/sapi/phpdbg/phpdbg_break.h b/sapi/phpdbg/phpdbg_break.h
index de1eff1b56..dc06da62b7 100644
--- a/sapi/phpdbg/phpdbg_break.h
+++ b/sapi/phpdbg/phpdbg_break.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
diff --git a/sapi/phpdbg/phpdbg_btree.c b/sapi/phpdbg/phpdbg_btree.c
index a155efbf9a..918bc0d68f 100644
--- a/sapi/phpdbg/phpdbg_btree.c
+++ b/sapi/phpdbg/phpdbg_btree.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -219,3 +219,18 @@ check_branch_existence:
return SUCCESS;
}
+
+void phpdbg_btree_branch_dump(phpdbg_btree_branch *branch, zend_ulong depth) {
+ if (branch) {
+ if (depth--) {
+ phpdbg_btree_branch_dump(branch->branches[0], depth);
+ phpdbg_btree_branch_dump(branch->branches[1], depth);
+ } else {
+ fprintf(stderr, "%p: %p\n", (void *) branch->result.idx, branch->result.ptr);
+ }
+ }
+}
+
+void phpdbg_btree_dump(phpdbg_btree *tree) {
+ phpdbg_btree_branch_dump(tree->branch, tree->depth);
+}
diff --git a/sapi/phpdbg/phpdbg_btree.h b/sapi/phpdbg/phpdbg_btree.h
index c714d8dc4c..27230572f7 100644
--- a/sapi/phpdbg/phpdbg_btree.h
+++ b/sapi/phpdbg/phpdbg_btree.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -62,4 +62,9 @@ int phpdbg_btree_insert_or_update(phpdbg_btree *tree, zend_ulong idx, void *ptr,
#define phpdbg_btree_update(tree, idx, ptr) phpdbg_btree_insert_or_update(tree, idx, ptr, PHPDBG_BTREE_UPDATE)
#define phpdbg_btree_overwrite(tree, idx, ptr) phpdbg_btree_insert_or_update(tree, idx, ptr, PHPDBG_BTREE_OWERWRITE)
+
+/* debugging functions */
+void phpdbg_btree_branch_dump(phpdbg_btree_branch *branch, zend_ulong depth);
+void phpdbg_btree_dump(phpdbg_btree *tree);
+
#endif
diff --git a/sapi/phpdbg/phpdbg_cmd.c b/sapi/phpdbg/phpdbg_cmd.c
index 0437455054..729babefca 100644
--- a/sapi/phpdbg/phpdbg_cmd.c
+++ b/sapi/phpdbg/phpdbg_cmd.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -23,6 +23,7 @@
#include "phpdbg_utils.h"
#include "phpdbg_set.h"
#include "phpdbg_prompt.h"
+#include "phpdbg_io.h"
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
@@ -39,7 +40,7 @@ static inline const char *phpdbg_command_name(const phpdbg_command_t *command, c
memcpy(&buffer[pos], command->name, command->name_len);
pos += command->name_len;
buffer[pos] = 0;
-
+
return buffer;
}
@@ -167,59 +168,39 @@ PHPDBG_API char* phpdbg_param_tostring(const phpdbg_param_t *param, char **point
{
switch (param->type) {
case STR_PARAM:
- asprintf(pointer,
- "%s", param->str);
+ asprintf(pointer, "%s", param->str);
break;
case ADDR_PARAM:
- asprintf(pointer,
- "%#lx", param->addr);
+ asprintf(pointer, "%#llx", param->addr);
break;
case NUMERIC_PARAM:
- asprintf(pointer,
- "%li",
- param->num);
+ asprintf(pointer, "%li", param->num);
break;
case METHOD_PARAM:
- asprintf(pointer,
- "%s::%s",
- param->method.class,
- param->method.name);
+ asprintf(pointer, "%s::%s", param->method.class, param->method.name);
break;
case FILE_PARAM:
if (param->num) {
- asprintf(pointer,
- "%s:%lu#%lu",
- param->file.name,
- param->file.line,
- param->num);
+ asprintf(pointer, "%s:%lu#%lu", param->file.name, param->file.line, param->num);
} else {
- asprintf(pointer,
- "%s:%lu",
- param->file.name,
- param->file.line);
+ asprintf(pointer, "%s:%lu", param->file.name, param->file.line);
}
break;
case NUMERIC_FUNCTION_PARAM:
- asprintf(pointer,
- "%s#%lu", param->str, param->num);
+ asprintf(pointer, "%s#%lu", param->str, param->num);
break;
case NUMERIC_METHOD_PARAM:
- asprintf(pointer,
- "%s::%s#%lu",
- param->method.class,
- param->method.name,
- param->num);
+ asprintf(pointer, "%s::%s#%lu", param->method.class, param->method.name, param->num);
break;
default:
- asprintf(pointer,
- "%s", "unknown");
+ *pointer = strdup("unknown");
}
return *pointer;
@@ -231,12 +212,12 @@ PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t* src, phpdbg_param_t* des
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;
@@ -276,7 +257,7 @@ PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t* src, phpdbg_param_t* des
break;
case EMPTY_PARAM: { /* do nothing */ } break;
-
+
default: {
/* not yet */
}
@@ -291,7 +272,7 @@ PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t *param TSRMLS_DC) /
case STACK_PARAM:
/* nope */
break;
-
+
case STR_PARAM:
hash += zend_inline_hash_func(param->str, param->len);
break;
@@ -329,7 +310,7 @@ PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t *param TSRMLS_DC) /
break;
case EMPTY_PARAM: { /* do nothing */ } break;
-
+
default: {
/* not yet */
}
@@ -347,7 +328,7 @@ PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *l, const phpdbg_pa
/* nope, or yep */
return 1;
break;
-
+
case NUMERIC_FUNCTION_PARAM:
if (l->num != r->num) {
break;
@@ -402,7 +383,7 @@ PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *l, const phpdbg_pa
case EMPTY_PARAM:
return 1;
-
+
default: {
/* not yet */
}
@@ -419,43 +400,43 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg)
case STR_PARAM:
fprintf(stderr, "%s STR_PARAM(%s=%lu)\n", msg, param->str, param->len);
break;
-
+
case ADDR_PARAM:
- fprintf(stderr, "%s ADDR_PARAM(%lu)\n", msg, param->addr);
+ fprintf(stderr, "%s ADDR_PARAM(%llu)\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=%lu)\n", msg, param->str, param->len);
break;
-
+
case OP_PARAM:
fprintf(stderr, "%s OP_PARAM(%s=%lu)\n", msg, param->str, param->len);
break;
-
+
default: {
/* not yet */
}
@@ -467,13 +448,13 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg)
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:
@@ -487,29 +468,30 @@ PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack) {
case STR_PARAM:
case OP_PARAM:
if (remove->str)
- free(remove->str);
+ free(remove->str);
break;
-
+
case NUMERIC_FILE_PARAM:
case FILE_PARAM:
if (remove->file.name)
free(remove->file.name);
break;
-
+
default: {
/* nothing */
}
}
-
+
free(remove);
remove = NULL;
-
+
if (next)
- remove = next;
+ remove = next;
else break;
}
}
-
+
+
stack->next = NULL;
} /* }}} */
@@ -537,30 +519,29 @@ PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param)
stack->len++;
} /* }}} */
-PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack, char **why TSRMLS_DC) {
+PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack TSRMLS_DC) {
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;
+ received = 0L,
+ current = 0L;
zend_bool optional = 0;
-
+
/* check for arg spec */
if (!(arg) || !(*arg)) {
if (!top) {
return SUCCESS;
}
-
- asprintf(why,
- "The command \"%s\" expected no arguments",
+
+ 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] == '|') {
@@ -569,21 +550,19 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param
least++;
arg++;
}
-
+
arg = command->args;
#define verify_arg(e, a, t) if (!(a)) { \
if (!optional) { \
- asprintf(why, \
- "The command \"%s\" expected %s and got nothing at parameter %lu", \
+ 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)) { \
- asprintf(why, \
- "The command \"%s\" expected %s and got %s at parameter %lu", \
+ 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) TSRMLS_CC), \
@@ -593,14 +572,14 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param
while (arg && *arg) {
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;
@@ -610,14 +589,14 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param
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++;
}
@@ -625,28 +604,27 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param
#undef verify_arg
if ((received < least)) {
- asprintf(why,
- "The command \"%s\" expected at least %lu arguments (%s) and received %lu",
+ 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,
+ 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, char **why) {
+PHPDBG_API const phpdbg_command_t *phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top TSRMLS_DC) {
const phpdbg_command_t *command = commands;
phpdbg_param_t *name = *top;
const phpdbg_command_t *matched[3] = {NULL, NULL, NULL};
ulong matches = 0L;
-
+
while (command && command->name && command->handler) {
- if ((name->len == 1) || (command->name_len >= name->len)) {
+ if (name->len == 1 || command->name_len >= name->len) {
/* match single letter alias */
if (command->alias && (name->len == 1)) {
if (command->alias == (*name->str)) {
@@ -654,85 +632,76 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *
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)) {
+ 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)
+ if (name->len == command->name_len) {
break;
- } else break;
+ }
+ } else {
+ break;
+ }
}
}
}
-
+
command++;
}
-
+
switch (matches) {
- case 0: {
+ case 0:
if (parent) {
- asprintf(
- why,
- "The command \"%s %s\" could not be found",
- parent->name, name->str);
- } else asprintf(
- why,
- "The command \"%s\" could not be found",
- name->str);
- } return parent;
-
- case 1: {
+ 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;
-
+ break;
+
default: {
char *list = NULL;
uint32_t it = 0;
size_t pos = 0;
-
+
while (it < matches) {
if (!list) {
- list = malloc(
- matched[it]->name_len + 1 +
- ((it+1) < matches ? sizeof(", ")-1 : 0));
+ list = emalloc(matched[it]->name_len + 1 + (it + 1 < matches ? sizeof(", ") - 1 : 0));
} else {
- list = realloc(list,
- (pos + matched[it]->name_len) + 1 +
- ((it+1) < matches ? sizeof(", ")-1 : 0));
+ 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);
+ if ((it + 1) < matches) {
+ memcpy(&list[pos], ", ", sizeof(", ") - 1);
pos += (sizeof(", ") - 1);
}
-
+
list[pos] = 0;
it++;
}
-
- asprintf(
- why,
- "The command \"%s\" is ambigious, matching %lu commands (%s)",
- name->str, matches, list);
- free(list);
- } return NULL;
+
+ /* ", " separated matches */
+ phpdbg_error("command", "type=\"ambiguous\" command=\"%s\" matches=\"%lu\" matched=\"%s\"", "The command \"%s\" is ambigious, 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, why);
+ return phpdbg_stack_resolve(command->subs, command, top TSRMLS_CC);
} else {
return command;
}
@@ -741,103 +710,148 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *
} /* }}} */
/* {{{ */
-PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why TSRMLS_DC) {
+PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, zend_bool allow_async_unsafe TSRMLS_DC) {
phpdbg_param_t *top = NULL;
const phpdbg_command_t *handler = NULL;
-
+
if (stack->type != STACK_PARAM) {
- asprintf(
- why, "The passed argument was not a stack !!");
+ phpdbg_error("command", "type=\"nostack\"", "The passed argument was not a stack !");
return FAILURE;
}
-
+
if (!stack->len) {
- asprintf(
- why, "The stack contains nothing !!");
+ phpdbg_error("command", "type=\"emptystack\"", "The stack contains nothing !");
return FAILURE;
}
-
- top = (phpdbg_param_t*) stack->next;
-
+
+ top = (phpdbg_param_t *) stack->next;
+
switch (top->type) {
case EVAL_PARAM:
+ phpdbg_activate_err_buf(0 TSRMLS_CC);
+ phpdbg_free_err_buf(TSRMLS_C);
return PHPDBG_COMMAND_HANDLER(ev)(top TSRMLS_CC);
case RUN_PARAM:
+ if (!allow_async_unsafe) {
+ phpdbg_error("signalsegv", "command=\"run\"", "run command is disallowed during hard interrupt");
+ }
+ phpdbg_activate_err_buf(0 TSRMLS_CC);
+ phpdbg_free_err_buf(TSRMLS_C);
return PHPDBG_COMMAND_HANDLER(run)(top TSRMLS_CC);
-
+
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 TSRMLS_CC);
+ phpdbg_free_err_buf(TSRMLS_C);
return PHPDBG_COMMAND_HANDLER(sh)(top TSRMLS_CC);
-
+
case STR_PARAM: {
- handler = phpdbg_stack_resolve(
- phpdbg_prompt_commands, NULL, &top, why);
-
+ handler = phpdbg_stack_resolve(phpdbg_prompt_commands, NULL, &top TSRMLS_CC);
+
if (handler) {
- if (phpdbg_stack_verify(handler, &top, why TSRMLS_CC) == SUCCESS) {
+ 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 TSRMLS_CC) == SUCCESS) {
+ phpdbg_activate_err_buf(0 TSRMLS_CC);
+ phpdbg_free_err_buf(TSRMLS_C);
return handler->handler(top TSRMLS_CC);
}
}
} return FAILURE;
-
+
default:
- asprintf(
- why, "The first parameter makes no sense !!");
+ phpdbg_error("command", "type=\"invalidcommand\"", "The first parameter makes no sense !");
return FAILURE;
}
-
+
return SUCCESS;
} /* }}} */
-PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */
+PHPDBG_API char *phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */
{
char *cmd = NULL;
-#if !defined(HAVE_LIBREADLINE) && !defined(HAVE_LIBEDIT)
- char buf[PHPDBG_MAX_CMD];
-#endif
char *buffer = NULL;
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
- if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) &&
- (buffered == NULL)) {
- fflush(PHPDBG_G(io)[PHPDBG_STDOUT]);
+ if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) && (buffered == NULL) && !phpdbg_active_sigsafe_mem(TSRMLS_C)) {
+ fflush(PHPDBG_G(io)[PHPDBG_STDOUT].ptr);
}
if (buffered == NULL) {
-disconnect:
if (0) {
+disconnect:
PHPDBG_G(flags) |= (PHPDBG_IS_QUITTING|PHPDBG_IS_DISCONNECTED);
zend_bailout();
return NULL;
}
-#if !defined(HAVE_LIBREADLINE) && !defined(HAVE_LIBEDIT)
- if (!(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) {
- if (!phpdbg_write("%s", phpdbg_get_prompt(TSRMLS_C))) {
+#define USE_LIB_STAR (defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT))
+
+ /* note: EOF makes readline write prompt again in local console mode - and ignored if compiled without readline */
+ /* strongly assuming to be in blocking mode... */
+#if USE_LIB_STAR
+readline:
+ if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE)
+#endif
+ {
+ char buf[PHPDBG_MAX_CMD];
+ int bytes = PHPDBG_G(input_buflen), len = 0;
+ if (PHPDBG_G(input_buflen)) {
+ memcpy(buf, PHPDBG_G(input_buffer), bytes);
+ }
+
+ phpdbg_write("prompt", "", "%s", phpdbg_get_prompt(TSRMLS_C));
+ PHPDBG_G(last_was_newline) = 1;
+
+ do {
+ int i;
+ if (bytes <= 0) {
+ continue;
+ }
+
+ for (i = len; i < len + bytes; i++) {
+ if (buf[i] == '\x03') {
+ if (i != len + bytes - 1) {
+ memmove(buf + i, buf + i + 1, len + bytes - i - 1);
+ }
+ len--;
+ i--;
+ continue;
+ }
+ if (buf[i] == '\n') {
+ PHPDBG_G(input_buflen) = len + bytes - 1 - i;
+ if (PHPDBG_G(input_buflen)) {
+ memcpy(PHPDBG_G(input_buffer), buf + i + 1, PHPDBG_G(input_buflen));
+ }
+ if (i != PHPDBG_MAX_CMD - 1) {
+ buf[i + 1] = 0;
+ }
+ cmd = buf;
+ goto end;
+ }
+ }
+ len += bytes;
+ /* XXX export the timeout through INI??*/
+ } while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, -1 TSRMLS_CC)) > 0);
+
+ if (bytes <= 0) {
goto disconnect;
}
+
+ cmd = buf;
}
-
- /* note: EOF is ignored */
-readline:
- if (!fgets(buf, PHPDBG_MAX_CMD, PHPDBG_G(io)[PHPDBG_STDIN])) {
- /* the user has gone away */
- if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) {
- goto disconnect;
- } else goto readline;
+#if USE_LIB_STAR
+ else {
+ cmd = readline(phpdbg_get_prompt(TSRMLS_C));
}
- cmd = buf;
-#else
- /* note: EOF makes readline write prompt again in local console mode */
-readline:
- if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) {
- char buf[PHPDBG_MAX_CMD];
- if (fgets(buf, PHPDBG_MAX_CMD, PHPDBG_G(io)[PHPDBG_STDIN])) {
- cmd = buf;
- } else goto disconnect;
- } else cmd = readline(phpdbg_get_prompt(TSRMLS_C));
-
if (!cmd) {
goto readline;
}
@@ -846,13 +860,15 @@ readline:
add_history(cmd);
}
#endif
- } else cmd = buffered;
-
+ } else {
+ cmd = buffered;
+ }
+end:
+ PHPDBG_G(last_was_newline) = 1;
buffer = estrdup(cmd);
-#if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT)
- if (!buffered && cmd &&
- !(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) {
+#if USE_LIB_STAR
+ if (!buffered && cmd && !(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) {
free(cmd);
}
#endif
@@ -878,7 +894,7 @@ readline:
buffer = estrdup(PHPDBG_G(buffer));
}
}
-
+
return buffer;
} /* }}} */
@@ -886,4 +902,3 @@ PHPDBG_API void phpdbg_destroy_input(char **input TSRMLS_DC) /*{{{ */
{
efree(*input);
} /* }}} */
-
diff --git a/sapi/phpdbg/phpdbg_cmd.h b/sapi/phpdbg/phpdbg_cmd.h
index 08b50de39e..3896551c9a 100644
--- a/sapi/phpdbg/phpdbg_cmd.h
+++ b/sapi/phpdbg/phpdbg_cmd.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -86,6 +86,8 @@ struct _phpdbg_param {
#define YYSTYPE phpdbg_param_t
#endif
+#define PHPDBG_ASYNC_SAFE 1
+
typedef int (*phpdbg_command_handler_t)(const phpdbg_param_t* TSRMLS_DC);
typedef struct _phpdbg_command_t phpdbg_command_t;
@@ -97,8 +99,9 @@ struct _phpdbg_command_t {
char alias; /* Alias */
phpdbg_command_handler_t handler; /* Command handler */
const phpdbg_command_t *subs; /* Sub Commands */
- char *args; /* Argument Spec */
- const phpdbg_command_t *parent; /* Parent Command */
+ char *args; /* Argument Spec */
+ const phpdbg_command_t *parent; /* Parent Command */
+ zend_bool flags; /* General flags */
};
/* }}} */
@@ -106,7 +109,7 @@ struct _phpdbg_command_t {
#define PHPDBG_STRL(s) s, sizeof(s)-1
#define PHPDBG_MAX_CMD 500
#define PHPDBG_FRAME(v) (PHPDBG_G(frame).v)
-#define PHPDBG_EX(v) (EG(current_execute_data)->v)
+#define PHPDBG_EX(v) (EG(current_execute_data)->v)
typedef struct {
int num;
@@ -133,9 +136,9 @@ PHPDBG_API void phpdbg_destroy_input(char** TSRMLS_DC);
* Stack Management
*/
PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param);
-PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why);
-PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack, char **why TSRMLS_DC);
-PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why TSRMLS_DC);
+PHPDBG_API const phpdbg_command_t *phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top TSRMLS_DC);
+PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack TSRMLS_DC);
+PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, zend_bool allow_async_unsafe TSRMLS_DC);
PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack);
/*
@@ -155,27 +158,27 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg)
*/
#define PHPDBG_COMMAND_HANDLER(name) phpdbg_do_##name
-#define PHPDBG_COMMAND_D_EXP(name, tip, alias, handler, children, args, parent) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, parent}
+#define PHPDBG_COMMAND_D_EXP(name, tip, alias, handler, children, args, parent, flags) \
+ {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, parent, flags}
-#define PHPDBG_COMMAND_D_EX(name, tip, alias, handler, children, args) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, NULL}
+#define PHPDBG_COMMAND_D_EX(name, tip, alias, handler, children, args, flags) \
+ {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, NULL, flags}
-#define PHPDBG_COMMAND_D(name, tip, alias, children, args) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, args, NULL}
+#define PHPDBG_COMMAND_D(name, tip, alias, children, args, flags) \
+ {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, args, NULL, flags}
#define PHPDBG_COMMAND(name) int phpdbg_do_##name(const phpdbg_param_t *param TSRMLS_DC)
#define PHPDBG_COMMAND_ARGS param TSRMLS_CC
-#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0', NULL}
+#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, NULL, NULL, 0}
/*
* Default Switch Case
*/
#define phpdbg_default_switch_case() \
default: \
- phpdbg_error("Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); \
+ phpdbg_error("command", "type=\"wrongarg\" got=\"%s\"", "Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); \
break
#endif /* PHPDBG_CMD_H */
diff --git a/sapi/phpdbg/phpdbg_eol.c b/sapi/phpdbg/phpdbg_eol.c
new file mode 100644
index 0000000000..fc20d567bc
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_eol.c
@@ -0,0 +1,172 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Anatol Belski <ab@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "phpdbg.h"
+#include "phpdbg_eol.h"
+
+ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+
+#define EOL_LIST_LEN 4
+struct phpdbg_eol_rep phpdbg_eol_list[EOL_LIST_LEN] = {
+ {"CRLF", "\r\n", PHPDBG_EOL_CRLF},
+/* {"LFCR", "\n\r", PHPDBG_EOL_LFCR},*/
+ {"LF", "\n", PHPDBG_EOL_LF},
+ {"CR", "\r", PHPDBG_EOL_CR},
+};
+
+int phpdbg_eol_global_update(char *name TSRMLS_DC)
+{
+
+ if (0 == memcmp(name, "CRLF", 4) || 0 == memcmp(name, "crlf", 4) || 0 == memcmp(name, "DOS", 3) || 0 == memcmp(name, "dos", 3)) {
+ PHPDBG_G(eol) = PHPDBG_EOL_CRLF;
+ } else if (0 == memcmp(name, "LF", 2) || 0 == memcmp(name, "lf", 2) || 0 == memcmp(name, "UNIX", 4) || 0 == memcmp(name, "unix", 4)) {
+ PHPDBG_G(eol) = PHPDBG_EOL_LF;
+ } else if (0 == memcmp(name, "CR", 2) || 0 == memcmp(name, "cr", 2) || 0 == memcmp(name, "MAC", 3) || 0 == memcmp(name, "mac", 3)) {
+ PHPDBG_G(eol) = PHPDBG_EOL_CR;
+ } else {
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+char *phpdbg_eol_name(int id)
+{
+ size_t i = 0;
+
+ while (i < EOL_LIST_LEN) {
+
+ if (id == phpdbg_eol_list[i].id) {
+ return phpdbg_eol_list[i].name;
+ }
+
+ i++;
+ }
+
+ return NULL;
+}
+
+char *phpdbg_eol_rep(int id)
+{
+ size_t i = 0;
+
+ while (i < EOL_LIST_LEN) {
+
+ if (id == phpdbg_eol_list[i].id) {
+ return phpdbg_eol_list[i].rep;
+ }
+
+ i++;
+ }
+
+ return NULL;
+}
+
+
+/* Inspired by https://ccrma.stanford.edu/~craig/utility/flip/flip.cpp */
+void phpdbg_eol_convert(char **str, int *len TSRMLS_DC)
+{
+ char *in = *str, *out ;
+ int in_len = *len, out_len, cursor, i;
+ char last, cur;
+
+ if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) != PHPDBG_IS_REMOTE) {
+ return;
+ }
+
+ out_len = *len;
+ if (PHPDBG_EOL_CRLF == PHPDBG_G(eol)) { /* XXX add LFCR case if it's gonna be needed */
+ /* depending on the source EOL the out str will have all CR/LF duplicated */
+ for (i = 0; i < in_len; i++) {
+ if (0x0a == in[i] || 0x0d == in[i]) {
+ out_len++;
+ }
+ }
+ out = (char *)emalloc(out_len);
+
+ last = cur = in[0];
+ i = cursor = 0;
+ for (; i < in_len;) {
+ if (0x0a == cur && last != 0x0d) {
+ out[cursor] = 0x0d;
+ cursor++;
+ out[cursor] = cur;
+ } else if(0x0d == cur) {
+ if (i + 1 < in_len && 0x0a != in[i+1]) {
+ out[cursor] = cur;
+ cursor++;
+ out[cursor] = 0x0a;
+ last = 0x0a;
+ } else {
+ out[cursor] = 0x0d;
+ last = 0x0d;
+ }
+ } else {
+ out[cursor] = cur;
+ last = cur;
+ }
+
+ i++;
+ cursor++;
+ cur = in[i];
+ }
+
+ } else if (PHPDBG_EOL_LF == PHPDBG_G(eol) || PHPDBG_EOL_CR == PHPDBG_G(eol)) {
+ char want, kick;
+
+ if (PHPDBG_EOL_LF == PHPDBG_G(eol)) {
+ want = 0x0a;
+ kick = 0x0d;
+ } else {
+ want = 0x0d;
+ kick = 0x0a;
+ }
+
+ /* We gonna have a smaller or equally long string, estimation is almost neglecting */
+ out = (char *)emalloc(out_len);
+
+ last = cur = in[0];
+ i = cursor = 0;
+ for (; cursor < in_len;) {
+ if (kick == cur) {
+ out[cursor] = want;
+ } else if (want == cur) {
+ if (kick != last) {
+ out[cursor] = want;
+ }
+ } else {
+ out[cursor] = cur;
+ }
+
+ last = cur;
+ cursor++;
+ cur = in[cursor];
+ }
+ } else {
+ return;
+ }
+
+ efree(*str);
+ *str = erealloc(out, cursor);
+ *len = cursor;
+ in = NULL;
+}
diff --git a/sapi/phpdbg/phpdbg_eol.h b/sapi/phpdbg/phpdbg_eol.h
new file mode 100644
index 0000000000..68b54cbe34
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_eol.h
@@ -0,0 +1,46 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Anatol Belski <ab@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef PHPDBG_EOL_H
+#define PHPDBG_EOL_H
+
+#include "phpdbg.h"
+
+struct phpdbg_eol_rep {
+ char *name;
+ char *rep;
+ int id;
+};
+
+enum {
+ PHPDBG_EOL_CRLF, /* DOS */
+ /*PHPDBG_EOL_LFCR,*/ /* for Risc OS? */
+ PHPDBG_EOL_LF, /* UNIX */
+ PHPDBG_EOL_CR /* MAC */
+};
+
+int phpdbg_eol_global_update(char *name TSRMLS_DC);
+
+char *phpdbg_eol_name(int id);
+
+char *phpdbg_eol_rep(int id);
+
+void phpdbg_eol_convert(char **str, int *len TSRMLS_DC);
+
+#endif /* PHPDBG_EOL_H */
+
diff --git a/sapi/phpdbg/phpdbg_frame.c b/sapi/phpdbg/phpdbg_frame.c
index 5678534005..4429a7fb73 100644
--- a/sapi/phpdbg/phpdbg_frame.c
+++ b/sapi/phpdbg/phpdbg_frame.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -37,13 +37,7 @@ void phpdbg_restore_frame(TSRMLS_D) /* {{{ */
/* move things back */
EG(current_execute_data) = PHPDBG_FRAME(execute_data);
- EG(opline_ptr) = &PHPDBG_EX(opline);
- EG(active_op_array) = PHPDBG_EX(op_array);
- EG(return_value_ptr_ptr) = PHPDBG_EX(original_return_value);
- EG(active_symbol_table) = PHPDBG_EX(symbol_table);
- EG(This) = PHPDBG_EX(current_this);
- EG(scope) = PHPDBG_EX(current_scope);
- EG(called_scope) = PHPDBG_EX(current_called_scope);
+ EG(scope) = PHPDBG_EX(scope);
} /* }}} */
void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */
@@ -52,22 +46,27 @@ void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */
int i = 0;
if (PHPDBG_FRAME(num) == frame) {
- phpdbg_notice("Already in frame #%d", frame);
+ phpdbg_notice("frame", "id=\"%d\"", "Already in frame #%d", frame);
return;
}
- while (execute_data) {
- if (i++ == frame) {
- break;
- }
+ phpdbg_try_access {
+ while (execute_data) {
+ if (i++ == frame) {
+ break;
+ }
- do {
- execute_data = execute_data->prev_execute_data;
- } while (execute_data && execute_data->opline == NULL);
- }
+ do {
+ execute_data = execute_data->prev_execute_data;
+ } while (execute_data && execute_data->opline == NULL);
+ }
+ } phpdbg_catch_access {
+ phpdbg_error("signalsegv", "", "Couldn't switch frames, invalid data source");
+ return;
+ } phpdbg_end_try_access();
if (execute_data == NULL) {
- phpdbg_error("No frame #%d", frame);
+ phpdbg_error("frame", "type=\"maxnum\" id=\"%d\"", "No frame #%d", frame);
return;
}
@@ -80,127 +79,143 @@ void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */
PHPDBG_FRAME(execute_data) = EG(current_execute_data);
EG(current_execute_data) = execute_data;
- EG(opline_ptr) = &PHPDBG_EX(opline);
- EG(active_op_array) = PHPDBG_EX(op_array);
- PHPDBG_FRAME(execute_data)->original_return_value = EG(return_value_ptr_ptr);
- EG(return_value_ptr_ptr) = PHPDBG_EX(original_return_value);
- EG(active_symbol_table) = PHPDBG_EX(symbol_table);
- EG(This) = PHPDBG_EX(current_this);
- EG(scope) = PHPDBG_EX(current_scope);
- EG(called_scope) = PHPDBG_EX(current_called_scope);
+ EG(scope) = PHPDBG_EX(scope);
}
- phpdbg_notice("Switched to frame #%d", frame);
- phpdbg_list_file(
- zend_get_executed_filename(TSRMLS_C),
- 3,
- zend_get_executed_lineno(TSRMLS_C)-1,
- zend_get_executed_lineno(TSRMLS_C)
- TSRMLS_CC
- );
+ phpdbg_notice("frame", "id=\"%d\"", "Switched to frame #%d", frame);
+
+ {
+ const char *file_chr = zend_get_executed_filename(TSRMLS_C);
+ zend_string *file = zend_string_init(file_chr, strlen(file_chr), 0);
+ phpdbg_list_file(file, 3, zend_get_executed_lineno(TSRMLS_C) - 1, zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC);
+ efree(file);
+ }
} /* }}} */
-static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */
+static void phpdbg_dump_prototype(zval *tmp TSRMLS_DC) /* {{{ */
{
- zval **funcname, **class, **type, **args, **argstmp;
- char is_class;
+ zval *funcname, *class, class_zv, *type, *args, *argstmp;
- zend_hash_find(Z_ARRVAL_PP(tmp), "function", sizeof("function"),
- (void **)&funcname);
+ funcname = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("function"));
- if ((is_class = zend_hash_find(Z_ARRVAL_PP(tmp),
- "object", sizeof("object"), (void **)&class)) == FAILURE) {
- is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "class", sizeof("class"),
- (void **)&class);
+ if ((class = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("object")))) {
+ ZVAL_NEW_STR(&class_zv, Z_OBJCE_P(class)->name);
+ class = &class_zv;
} else {
- zend_get_object_classname(*class, (const char **)&Z_STRVAL_PP(class),
- (uint32_t *)&Z_STRLEN_PP(class) TSRMLS_CC);
+ class = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("class"));
+ }
+
+ if (class) {
+ type = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("type"));
}
- if (is_class == SUCCESS) {
- zend_hash_find(Z_ARRVAL_PP(tmp), "type", sizeof("type"), (void **)&type);
+ args = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("args"));
+
+ phpdbg_xml(" symbol=\"%s%s%s\"", class ? Z_STRVAL_P(class) : "", class ? Z_STRVAL_P(type) : "", Z_STRVAL_P(funcname));
+
+ if (args) {
+ phpdbg_xml(">");
+ } else {
+ phpdbg_xml(" />");
}
- phpdbg_write("%s%s%s(",
- is_class == FAILURE?"":Z_STRVAL_PP(class),
- is_class == FAILURE?"":Z_STRVAL_PP(type),
- Z_STRVAL_PP(funcname)
- );
-
- if (zend_hash_find(Z_ARRVAL_PP(tmp), "args", sizeof("args"),
- (void **)&args) == SUCCESS) {
- HashPosition iterator;
- const zend_function *func = phpdbg_get_function(
- Z_STRVAL_PP(funcname), is_class == FAILURE ? NULL : Z_STRVAL_PP(class) TSRMLS_CC);
- const zend_arg_info *arginfo = func ? func->common.arg_info : NULL;
- int j = 0, m = func ? func->common.num_args : 0;
+ phpdbg_out("%s%s%s(", class ? Z_STRVAL_P(class) : "", class ? Z_STRVAL_P(type) : "", Z_STRVAL_P(funcname));
+
+ if (args) {
+ const zend_function *func = NULL;
+ const zend_arg_info *arginfo = NULL;
zend_bool is_variadic = 0;
+ int j = 0, m;
+
+ phpdbg_try_access {
+ /* assuming no autoloader call is necessary, class should have been loaded if it's in backtrace ... */
+ if ((func = phpdbg_get_function(Z_STRVAL_P(funcname), class ? Z_STRVAL_P(class) : NULL TSRMLS_CC))) {
+ arginfo = func->common.arg_info;
+ }
+ } phpdbg_end_try_access();
+
+ m = func ? func->common.num_args : 0;
- zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(args), &iterator);
- while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args),
- (void **) &argstmp, &iterator) == SUCCESS) {
+ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), argstmp) {
if (j) {
- phpdbg_write(", ");
+ phpdbg_out(", ");
}
+ phpdbg_xml("<arg %r");
if (m && j < m) {
-#if PHP_VERSION_ID >= 50600
- is_variadic = arginfo[j].is_variadic;
-#endif
- phpdbg_write("%s=%s",
- arginfo[j].name, is_variadic ? "[": "");
+ if (!is_variadic) {
+ is_variadic = arginfo ? arginfo[j].is_variadic : 0;
+ }
+ phpdbg_xml(" variadic=\"%s\" name=\"%s\">", is_variadic ? "variadic" : "", arginfo ? arginfo[j].name : "");
+ phpdbg_out("%s=%s", arginfo ? arginfo[j].name : "?", is_variadic ? "[": "");
+
+ } else {
+ phpdbg_xml(">");
}
++j;
- zend_print_flat_zval_r(*argstmp TSRMLS_CC);
- zend_hash_move_forward_ex(Z_ARRVAL_PP(args), &iterator);
- }
+ zend_print_flat_zval_r(argstmp TSRMLS_CC);
+
+ phpdbg_xml("</arg>");
+ } ZEND_HASH_FOREACH_END();
+
if (is_variadic) {
- phpdbg_write("]");
+ phpdbg_out("]");
}
+ phpdbg_xml("</frame>");
}
- phpdbg_write(")");
+ phpdbg_out(")");
}
void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */
{
- zval zbacktrace;
- zval **tmp;
- zval **file, **line;
HashPosition position;
+ zval zbacktrace;
+ zval *tmp;
+ zval *file, *line;
int i = 0, limit = num;
- int user_defined;
if (limit < 0) {
- phpdbg_error("Invalid backtrace size %d", limit);
+ phpdbg_error("backtrace", "type=\"minnum\"", "Invalid backtrace size %d", limit);
+ return;
}
- zend_fetch_debug_backtrace(
- &zbacktrace, 0, 0, limit TSRMLS_CC);
+ phpdbg_try_access {
+ zend_fetch_debug_backtrace(&zbacktrace, 0, 0, limit TSRMLS_CC);
+ } phpdbg_catch_access {
+ phpdbg_error("signalsegv", "", "Couldn't fetch backtrace, invalid data source");
+ return;
+ } phpdbg_end_try_access();
+
+ phpdbg_xml("<backtrace %r>");
zend_hash_internal_pointer_reset_ex(Z_ARRVAL(zbacktrace), &position);
- zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position);
+ tmp = zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), &position);
while (1) {
- user_defined = zend_hash_find(Z_ARRVAL_PP(tmp), "file", sizeof("file"), (void **)&file);
- zend_hash_find(Z_ARRVAL_PP(tmp), "line", sizeof("line"), (void **)&line);
+ file = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("file"));
+ line = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("line"));
zend_hash_move_forward_ex(Z_ARRVAL(zbacktrace), &position);
- if (zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace),
- (void**)&tmp, &position) == FAILURE) {
- phpdbg_write("frame #%d: {main} at %s:%ld", i, Z_STRVAL_PP(file), Z_LVAL_PP(line));
+ if (!(tmp = zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), &position))) {
+ phpdbg_write("frame", "id=\"%d\" symbol=\"{main}\" file=\"%s\" line=\"%d\"", "frame #%d: {main} at %s:%ld", i, Z_STRVAL_P(file), Z_LVAL_P(line));
break;
}
- if (user_defined == SUCCESS) {
- phpdbg_write("frame #%d: ", i++);
+ if (file) { /* userland */
+ phpdbg_out("frame #%d: ", i);
+ phpdbg_xml("<frame %r id=\"%d\" file=\"%s\" line=\"%d\"", i, Z_STRVAL_P(file), Z_LVAL_P(line));
phpdbg_dump_prototype(tmp TSRMLS_CC);
- phpdbg_writeln(" at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line));
+ phpdbg_out(" at %s:%ld\n", Z_STRVAL_P(file), Z_LVAL_P(line));
+ i++;
} else {
- phpdbg_write(" => ");
+ phpdbg_out(" => ");
+ phpdbg_xml("<frame %r id=\"%d\" internal=\"internal\"", i);
phpdbg_dump_prototype(tmp TSRMLS_CC);
- phpdbg_writeln(" (internal function)");
+ phpdbg_out(" (internal function)\n");
}
}
- phpdbg_writeln(EMPTY);
+ phpdbg_out("\n");
+ phpdbg_xml("</backtrace>");
+
zval_dtor(&zbacktrace);
} /* }}} */
diff --git a/sapi/phpdbg/phpdbg_frame.h b/sapi/phpdbg/phpdbg_frame.h
index 757f98fd71..7c4574ed28 100644
--- a/sapi/phpdbg/phpdbg_frame.h
+++ b/sapi/phpdbg/phpdbg_frame.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
diff --git a/sapi/phpdbg/phpdbg_help.c b/sapi/phpdbg/phpdbg_help.c
index 3421f7ebeb..652e170694 100644
--- a/sapi/phpdbg/phpdbg_help.c
+++ b/sapi/phpdbg/phpdbg_help.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -22,6 +22,7 @@
#include "phpdbg.h"
#include "phpdbg_help.h"
#include "phpdbg_prompt.h"
+#include "phpdbg_eol.h"
#include "zend.h"
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
@@ -61,6 +62,11 @@ void pretty_print(char *text TSRMLS_DC)
unsigned int last_blank_count = 0; /* printable char offset of last blank char */
unsigned int line_count = 0; /* number printable chars on current line */
+ if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
+ phpdbg_xml("<help %r msg=\"%s\" />", text);
+ return;
+ }
+
/* First pass calculates a safe size for the pretty print version */
for (p = text; *p; p++) {
if (UNEXPECTED(p[0] == '*') && p[1] == '*') {
@@ -128,10 +134,10 @@ void pretty_print(char *text TSRMLS_DC)
*q++ = '\0';
if ((q-new)>size) {
- phpdbg_error("Output overrun of %lu bytes", ((q-new) - size));
+ phpdbg_error("help", "overrun=\"%lu\"", "Output overrun of %lu bytes", ((q - new) - size));
}
- phpdbg_write("%s\n", new);
+ phpdbg_out("%s\n", new);
efree(new);
} /* }}} */
@@ -201,7 +207,7 @@ static int get_command(
return num_matches;
-} /* }}} */
+} /* }}} */
PHPDBG_COMMAND(help) /* {{{ */
{
@@ -231,7 +237,7 @@ PHPDBG_COMMAND(help) /* {{{ */
pretty_print(get_help("duplicate!" TSRMLS_CC) TSRMLS_CC);
return SUCCESS;
} else {
- phpdbg_error("Internal help error, non-unique alias \"%c\"", param->str[0]);
+ phpdbg_error("help", "type=\"ambiguousalias\" alias=\"%s\"", "Internal help error, non-unique alias \"%c\"", param->str[0]);
return FAILURE;
}
@@ -259,34 +265,41 @@ PHPDBG_HELP(aliases) /* {{{ */
int len;
/* Print out aliases for all commands except help as this one comes last */
- phpdbg_writeln("Below are the aliased, short versions of all supported commands");
+ phpdbg_writeln("help", "", "Below are the aliased, short versions of all supported commands");
+ phpdbg_xml("<helpcommands %r>");
for(c = phpdbg_prompt_commands; c->name; c++) {
if (c->alias && c->alias != 'h') {
- phpdbg_writeln(" %c %-20s %s", c->alias, c->name, c->tip);
+ phpdbg_writeln("command", "alias=\"%c\" name=\"%s\" tip=\"%s\"", " %c %-20s %s", c->alias, c->name, c->tip);
if (c->subs) {
len = 20 - 1 - c->name_len;
for(c_sub = c->subs; c_sub->alias; c_sub++) {
if (c_sub->alias) {
- phpdbg_writeln(" %c %c %s %-*s %s",
- c->alias, c_sub->alias, (char *)c->name, len, c_sub->name, c_sub->tip);
+ phpdbg_writeln("subcommand", "parent_alias=\"%c\" alias=\"%c\" parent=\"%s\" name=\"%-*s\" tip=\"%s\"", " %c %c %s %-*s %s",
+ c->alias, c_sub->alias, c->name, len, c_sub->name, c_sub->tip);
}
}
}
}
}
+ phpdbg_xml("</helpcommands>");
+
/* Print out aliases for help as this one comes last, with the added text on how aliases are used */
get_command("h", 1, &c, phpdbg_prompt_commands TSRMLS_CC);
- phpdbg_writeln(" %c %-20s %s\n", c->alias, c->name, c->tip);
+ phpdbg_writeln("aliasinfo", "alias=\"%c\" name=\"%s\" tip=\"%s\"", " %c %-20s %s\n", c->alias, c->name, c->tip);
+
+ phpdbg_xml("<helpaliases>");
len = 20 - 1 - c->name_len;
for(c_sub = c->subs; c_sub->alias; c_sub++) {
if (c_sub->alias) {
- phpdbg_writeln(" %c %c %s %-*s %s",
+ phpdbg_writeln("alias", "parent_alias=\"%c\" alias=\"%c\" parent=\"%s\" name=\"%-*s\" tip=\"%s\"", " %c %c %s %-*s %s",
c->alias, c_sub->alias, c->name, len, c_sub->name, c_sub->tip);
}
}
+ phpdbg_xml("</helpaliases>");
+
pretty_print(get_help("aliases!" TSRMLS_CC) TSRMLS_CC);
return SUCCESS;
} /* }}} */
@@ -307,7 +320,7 @@ PHPDBG_HELP(aliases) /* {{{ */
* Also note the convention that help text not directly referenceable as a help param
* has a key ending in !
*/
-#define CR "\n"
+#define CR "\n"
phpdbg_help_text_t phpdbg_help_text[] = {
/******************************** General Help Topics ********************************/
@@ -375,6 +388,7 @@ phpdbg_help_text_t phpdbg_help_text[] = {
" **-S** **-S**cli Override SAPI name, careful!" CR
" **-l** **-l**4000 Setup remote console ports" CR
" **-a** **-a**192.168.0.3 Setup remote console bind address" CR
+" **-x** Enable xml output (instead of normal text output)" CR
" **-V** Print version number" CR
" **--** **--** arg1 arg2 Use to delimit phpdbg arguments and php $argv; append any $argv "
"argument after it" CR CR
@@ -386,9 +400,7 @@ phpdbg_help_text_t phpdbg_help_text[] = {
"bind address using the **-a** option. If **-a** is specied without an argument, then phpdbg "
"will bind to all available interfaces. You should be aware of the security implications of "
"doing this, so measures should be taken to secure this service if bound to a publicly accessible "
-"interface/port." CR CR
-
-"Specify both stdin and stdout with -lstdin/stdout; by default stdout is stdin * 2."
+"interface/port."
},
{"phpdbginit", CR
@@ -642,14 +654,16 @@ phpdbg_help_text_t phpdbg_help_text[] = {
"Specific info commands are show below:" CR CR
" **Target** **Alias** **Purpose**" CR
-" **break** **b** show current breakpoints" CR
-" **files** **F** show included files" CR
-" **classes** **c** show loaded classes" CR
-" **funcs** **f** show loaded classes" CR
-" **error** **e** show last error" CR
-" **vars** **v** show active variables" CR
-" **literal** **l** show active literal constants" CR
-" **memory** **m** show memory manager stats"
+" **break** **b** show current breakpoints" CR
+" **files** **F** show included files" CR
+" **classes** **c** show loaded classes" CR
+" **funcs** **f** show loaded functions" CR
+" **error** **e** show last error" CR
+" **constants** **d** show user-defined constants" CR
+" **vars** **v** show active variables" CR
+" **globals** **g** show superglobal variables" CR
+" **literal** **l** show active literal constants" CR
+" **memory** **m** show memory manager stats"
},
// ******** same issue about breakpoints in called frames
diff --git a/sapi/phpdbg/phpdbg_help.h b/sapi/phpdbg/phpdbg_help.h
index c7af5c894b..4a433fda6c 100644
--- a/sapi/phpdbg/phpdbg_help.h
+++ b/sapi/phpdbg/phpdbg_help.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -35,9 +35,9 @@ PHPDBG_HELP(aliases);
extern const phpdbg_command_t phpdbg_help_commands[];
#define phpdbg_help_header() \
- phpdbg_notice("Welcome to phpdbg, the interactive PHP debugger, v%s", PHPDBG_VERSION);
+ phpdbg_notice("version", "version=\"%s\"", "Welcome to phpdbg, the interactive PHP debugger, v%s", PHPDBG_VERSION);
#define phpdbg_help_footer() \
- phpdbg_notice("Please report bugs to <%s>", PHPDBG_ISSUES);
+ phpdbg_notice("issues", "url=\"%s\"", "Please report bugs to <%s>", PHPDBG_ISSUES);
typedef struct _phpdbg_help_text_t {
char *key;
diff --git a/sapi/phpdbg/phpdbg_info.c b/sapi/phpdbg/phpdbg_info.c
index 5911185300..01633e4feb 100644
--- a/sapi/phpdbg/phpdbg_info.c
+++ b/sapi/phpdbg/phpdbg_info.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -27,18 +27,20 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-#define PHPDBG_INFO_COMMAND_D(f, h, a, m, l, s) \
- PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[14])
+#define PHPDBG_INFO_COMMAND_D(f, h, a, m, l, s, flags) \
+ PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[14], flags)
const phpdbg_command_t phpdbg_info_commands[] = {
- PHPDBG_INFO_COMMAND_D(break, "show breakpoints", 'b', info_break, NULL, 0),
- PHPDBG_INFO_COMMAND_D(files, "show included files", 'F', info_files, NULL, 0),
- PHPDBG_INFO_COMMAND_D(classes, "show loaded classes", 'c', info_classes, NULL, 0),
- PHPDBG_INFO_COMMAND_D(funcs, "show loaded classes", 'f', info_funcs, NULL, 0),
- PHPDBG_INFO_COMMAND_D(error, "show last error", 'e', info_error, NULL, 0),
- PHPDBG_INFO_COMMAND_D(vars, "show active variables", 'v', info_vars, NULL, 0),
- PHPDBG_INFO_COMMAND_D(literal, "show active literal constants", 'l', info_literal, NULL, 0),
- PHPDBG_INFO_COMMAND_D(memory, "show memory manager stats", 'm', info_memory, NULL, 0),
+ PHPDBG_INFO_COMMAND_D(break, "show breakpoints", 'b', info_break, NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_INFO_COMMAND_D(files, "show included files", 'F', info_files, NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_INFO_COMMAND_D(classes, "show loaded classes", 'c', info_classes, NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_INFO_COMMAND_D(funcs, "show loaded classes", 'f', info_funcs, NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_INFO_COMMAND_D(error, "show last error", 'e', info_error, NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_INFO_COMMAND_D(constants, "show user defined constants", 'd', info_constants, NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_INFO_COMMAND_D(vars, "show active variables", 'v', info_vars, NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_INFO_COMMAND_D(globals, "show superglobals", 'g', info_globals, NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_INFO_COMMAND_D(literal, "show active literal constants", 'l', info_literal, NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_INFO_COMMAND_D(memory, "show memory manager stats", 'm', info_memory, NULL, 0, PHPDBG_ASYNC_SAFE),
PHPDBG_END_COMMAND
};
@@ -59,18 +61,22 @@ PHPDBG_INFO(break) /* {{{ */
PHPDBG_INFO(files) /* {{{ */
{
- HashPosition pos;
- char *fname;
+ zend_string *fname;
- phpdbg_notice("Included files: %d",
- zend_hash_num_elements(&EG(included_files)));
+ phpdbg_try_access {
+ phpdbg_notice("includedfilecount", "num=\"%d\"", "Included files: %d", zend_hash_num_elements(&EG(included_files)));
+ } phpdbg_catch_access {
+ phpdbg_error("signalsegv", "", "Could not fetch included file count, invalid data source");
+ return SUCCESS;
+ } phpdbg_end_try_access();
- zend_hash_internal_pointer_reset_ex(&EG(included_files), &pos);
- while (zend_hash_get_current_key_ex(&EG(included_files), &fname,
- NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) {
- phpdbg_writeln("File: %s", fname);
- zend_hash_move_forward_ex(&EG(included_files), &pos);
- }
+ phpdbg_try_access {
+ ZEND_HASH_FOREACH_STR_KEY(&EG(included_files), fname) {
+ phpdbg_writeln("includedfile", "name=\"%s\"", "File: %s", fname);
+ } ZEND_HASH_FOREACH_END();
+ } phpdbg_catch_access {
+ phpdbg_error("signalsegv", "", "Could not fetch file name, invalid data source, aborting included file listing");
+ } phpdbg_end_try_access();
return SUCCESS;
} /* }}} */
@@ -78,125 +84,189 @@ PHPDBG_INFO(files) /* {{{ */
PHPDBG_INFO(error) /* {{{ */
{
if (PG(last_error_message)) {
- phpdbg_writeln("Last error: %s at %s line %d",
- PG(last_error_message), PG(last_error_file), PG(last_error_lineno));
+ phpdbg_try_access {
+ phpdbg_writeln("lasterror", "error=\"%s\" file=\"%s\" line=\"%d\"", "Last error: %s at %s line %d", PG(last_error_message), PG(last_error_file), PG(last_error_lineno));
+ } phpdbg_catch_access {
+ phpdbg_notice("lasterror", "error=\"\"", "No error found!");
+ } phpdbg_end_try_access();
} else {
- phpdbg_notice("No error found!");
+ phpdbg_notice("lasterror", "error=\"\"", "No error found!");
}
return SUCCESS;
} /* }}} */
-PHPDBG_INFO(vars) /* {{{ */
+PHPDBG_INFO(constants) /* {{{ */
{
- HashTable vars;
- HashPosition pos;
- char *var;
- zval **data;
+ HashTable consts;
+ zend_constant *data;
- if (!EG(active_op_array)) {
- phpdbg_error("No active op array!");
- return SUCCESS;
+ zend_hash_init(&consts, 8, NULL, NULL, 0);
+
+ if (EG(zend_constants)) {
+ phpdbg_try_access {
+ ZEND_HASH_FOREACH_PTR(EG(zend_constants), data) {
+ if (data->module_number == PHP_USER_CONSTANT) {
+ zend_hash_update_ptr(&consts, data->name, data);
+ }
+ } ZEND_HASH_FOREACH_END();
+ } phpdbg_catch_access {
+ phpdbg_error("signalsegv", "", "Cannot fetch all the constants, invalid data source");
+ } phpdbg_end_try_access();
}
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
+ phpdbg_notice("constantinfo", "num=\"%d\"", "User-defined constants (%d)", zend_hash_num_elements(&consts));
+
+ if (zend_hash_num_elements(&consts)) {
+ phpdbg_out("Address Refs Type Constant\n");
+ ZEND_HASH_FOREACH_PTR(&consts, data) {
+
+#define VARIABLEINFO(attrs, msg, ...) phpdbg_writeln("constant", "address=\"%p\" refcount=\"%d\" type=\"%s\" name=\"%.*s\" " attrs, "%-18p %-7d %-9s %.*s" msg, &data->value, Z_REFCOUNT(data->value), zend_zval_type_name(&data->value), data->name->len, data->name->val, ##__VA_ARGS__)
+
+ switch (Z_TYPE(data->value)) {
+ case IS_STRING:
+ phpdbg_try_access {
+ VARIABLEINFO("length=\"%d\" value=\"%.*s\"", "\nstring (%d) \"%.*s%s\"", Z_STRLEN(data->value), Z_STRLEN(data->value) < 255 ? Z_STRLEN(data->value) : 255, Z_STRVAL(data->value), Z_STRLEN(data->value) > 255 ? "..." : "");
+ } phpdbg_catch_access {
+ VARIABLEINFO("", "");
+ } phpdbg_end_try_access();
+ break;
+ case IS_TRUE:
+ VARIABLEINFO("value=\"true\"", "\nbool (true)");
+ break;
+ case IS_FALSE:
+ VARIABLEINFO("value=\"false\"", "\nbool (false)");
+ break;
+ case IS_LONG:
+ VARIABLEINFO("value=\"%ld\"", "\nint (%ld)", Z_LVAL(data->value));
+ break;
+ case IS_DOUBLE:
+ VARIABLEINFO("value=\"%lf\"", "\ndouble (%lf)", Z_DVAL(data->value));
+ break;
+ default:
+ VARIABLEINFO("", "");
+
+#undef VARIABLEINFO
+ }
+ } ZEND_HASH_FOREACH_END();
+ }
- if (!EG(active_symbol_table)) {
- phpdbg_error("No active symbol table!");
- return SUCCESS;
+ return SUCCESS;
+} /* }}} */
+
+static int phpdbg_arm_auto_global(zend_auto_global *auto_global TSRMLS_DC) {
+ if (auto_global->armed) {
+ if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) {
+ phpdbg_notice("variableinfo", "unreachable=\"%.*s\"", "Cannot show information about superglobal variable %.*s", auto_global->name->len, auto_global->name->val);
+ } else {
+ auto_global->armed = auto_global->auto_global_callback(auto_global->name TSRMLS_CC);
}
}
- zend_hash_init(&vars, 8, NULL, NULL, 0);
+ return 0;
+}
- zend_hash_internal_pointer_reset_ex(EG(active_symbol_table), &pos);
- while (zend_hash_get_current_key_ex(EG(active_symbol_table), &var,
- NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) {
- zend_hash_get_current_data_ex(EG(active_symbol_table), (void **)&data, &pos);
- if (*var != '_') {
- zend_hash_update(
- &vars, var, strlen(var)+1, (void**)data, sizeof(zval*), NULL);
- }
- zend_hash_move_forward_ex(EG(active_symbol_table), &pos);
+static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) {
+ HashTable vars;
+ zend_array *symtable;
+ zend_string *var;
+ zval *data;
+
+ if (!EG(current_execute_data) || !EG(current_execute_data)->func) {
+ phpdbg_error("inactive", "type=\"op_array\"", "No active op array!");
+ return SUCCESS;
+ }
+
+ if (show_globals) {
+ /* that array should only be manipulated during init, so safe for async access during execution */
+ zend_hash_apply(CG(auto_globals), (apply_func_t) phpdbg_arm_auto_global TSRMLS_CC);
+ symtable = &EG(symbol_table);
+ } else if (!(symtable = zend_rebuild_symbol_table(TSRMLS_C))) {
+ phpdbg_error("inactive", "type=\"symbol_table\"", "No active symbol table!");
+ return SUCCESS;
}
- {
- zend_op_array *ops = EG(active_op_array);
-
+ zend_hash_init(&vars, 8, NULL, NULL, 0);
+
+ phpdbg_try_access {
+ ZEND_HASH_FOREACH_STR_KEY_VAL(&symtable->ht, var, data) {
+ if (zend_is_auto_global(var TSRMLS_CC) ^ !show_globals) {
+ zend_hash_update(&vars, var, data);
+ }
+ } ZEND_HASH_FOREACH_END();
+ } phpdbg_catch_access {
+ phpdbg_error("signalsegv", "", "Cannot fetch all data from the symbol table, invalid data source");
+ } phpdbg_end_try_access();
+
+ if (show_globals) {
+ phpdbg_notice("variableinfo", "num=\"%d\"", "Superglobal variables (%d)", zend_hash_num_elements(&vars));
+ } else {
+ zend_op_array *ops = &EG(current_execute_data)->func->op_array;
+
if (ops->function_name) {
if (ops->scope) {
- phpdbg_notice(
- "Variables in %s::%s() (%d)", ops->scope->name, ops->function_name, zend_hash_num_elements(&vars));
+ phpdbg_notice("variableinfo", "method=\"%s::%s\" num=\"%d\"", "Variables in %s::%s() (%d)", ops->scope->name, ops->function_name, zend_hash_num_elements(&vars));
} else {
- phpdbg_notice(
- "Variables in %s() (%d)", ops->function_name, zend_hash_num_elements(&vars));
+ phpdbg_notice("variableinfo", "function=\"%s\" num=\"%d\"", "Variables in %s() (%d)", ops->function_name, zend_hash_num_elements(&vars));
}
} else {
if (ops->filename) {
- phpdbg_notice(
- "Variables in %s (%d)", ops->filename, zend_hash_num_elements(&vars));
+ phpdbg_notice("variableinfo", "file=\"%s\" num=\"%d\"", "Variables in %s (%d)", ops->filename->val, zend_hash_num_elements(&vars));
} else {
- phpdbg_notice(
- "Variables @ %p (%d)", ops, zend_hash_num_elements(&vars));
+ phpdbg_notice("variableinfo", "opline=\"%p\" num=\"%d\"", "Variables @ %p (%d)", ops, zend_hash_num_elements(&vars));
}
}
}
if (zend_hash_num_elements(&vars)) {
- phpdbg_writeln("Address\t\tRefs\tType\t\tVariable");
- for (zend_hash_internal_pointer_reset_ex(&vars, &pos);
- zend_hash_get_current_data_ex(&vars, (void**) &data, &pos) == SUCCESS;
- zend_hash_move_forward_ex(&vars, &pos)) {
- char *var;
-
- zend_hash_get_current_key_ex(&vars, &var, NULL, NULL, 0, &pos);
-
- if (*data) {
- phpdbg_write(
- "%p\t%d\t",
- *data,
- Z_REFCOUNT_PP(data));
-
- switch (Z_TYPE_PP(data)) {
- case IS_STRING: phpdbg_write("(string)\t"); break;
- case IS_LONG: phpdbg_write("(integer)\t"); break;
- case IS_DOUBLE: phpdbg_write("(float)\t"); break;
- case IS_RESOURCE: phpdbg_write("(resource)\t"); break;
- case IS_ARRAY: phpdbg_write("(array)\t"); break;
- case IS_OBJECT: phpdbg_write("(object)\t"); break;
- case IS_NULL: phpdbg_write("(null)\t"); break;
+ phpdbg_out("Address Refs Type Variable\n");
+ ZEND_HASH_FOREACH_STR_KEY_VAL(&vars, var, data) {
+ phpdbg_try_access {
+#define VARIABLEINFO(attrs, msg, ...) phpdbg_writeln("variable", "address=\"%p\" refcount=\"%d\" type=\"%s\" refstatus=\"%s\" name=\"%.*s\" " attrs, "%-18p %-7d %-9s %s$%.*s" msg, data, Z_REFCOUNT_P(data), zend_zval_type_name(data), Z_ISREF_P(data) ? "&": "", var->len, var->val, ##__VA_ARGS__)
+
+ switch (Z_TYPE_P(data)) {
+ case IS_RESOURCE:
+ phpdbg_try_access {
+ const char *type = zend_rsrc_list_get_rsrc_type(Z_RES_P(data) TSRMLS_CC);
+ VARIABLEINFO("type=\"%s\"", "\n|-------(typeof)------> (%s)\n", type ? type : "unknown");
+ } phpdbg_catch_access {
+ VARIABLEINFO("type=\"unknown\"", "\n|-------(typeof)------> (unknown)\n");
+ } phpdbg_end_try_access();
+ break;
+ case IS_OBJECT:
+ phpdbg_try_access {
+ VARIABLEINFO("instanceof=\"%s\"", "\n|-----(instanceof)----> (%s)\n", Z_OBJCE_P(data)->name);
+ } phpdbg_catch_access {
+ VARIABLEINFO("instanceof=\"%s\"", "\n|-----(instanceof)----> (unknown)\n");
+ } phpdbg_end_try_access();
+ break;
+ case IS_STRING:
+ phpdbg_try_access {
+ VARIABLEINFO("length=\"%d\" value=\"%.*s\"", "\nstring (%d) \"%.*s%s\"", Z_STRLEN_P(data), Z_STRLEN_P(data) < 255 ? Z_STRLEN_P(data) : 255, Z_STRVAL_P(data), Z_STRLEN_P(data) > 255 ? "..." : "");
+ } phpdbg_catch_access {
+ VARIABLEINFO("", "");
+ } phpdbg_end_try_access();
+ break;
+ case IS_TRUE:
+ VARIABLEINFO("value=\"true\"", "\nbool (true)");
+ break;
+ case IS_FALSE:
+ VARIABLEINFO("value=\"false\"", "\nbool (false)");
+ break;
+ case IS_LONG:
+ VARIABLEINFO("value=\"%ld\"", "\nint (%ld)", Z_LVAL_P(data));
+ break;
+ case IS_DOUBLE:
+ VARIABLEINFO("value=\"%lf\"", "\ndouble (%lf)", Z_DVAL_P(data));
+ break;
+ default:
+ VARIABLEINFO("", "");
}
- if (Z_TYPE_PP(data) == IS_RESOURCE) {
- int type;
-
- phpdbg_writeln(
- "%s$%s", Z_ISREF_PP(data) ? "&": "", var);
- if (zend_list_find(Z_RESVAL_PP(data), &type)) {
- phpdbg_write(
- "|-------(typeof)------> (%s)",
- zend_rsrc_list_get_rsrc_type(type TSRMLS_CC));
- } else {
- phpdbg_write(
- "|-------(typeof)------> (unknown)");
- }
- phpdbg_writeln(EMPTY);
- } else if (Z_TYPE_PP(data) == IS_OBJECT) {
- phpdbg_writeln(
- "%s$%s", Z_ISREF_PP(data) ? "&": "", var);
- phpdbg_write(
- "|-----(instanceof)----> (%s)", Z_OBJCE_PP(data)->name);
- phpdbg_writeln(EMPTY);
- } else {
- phpdbg_write(
- "%s$%s", Z_ISREF_PP(data) ? "&": "", var);
- }
- } else {
- phpdbg_write(
- "n/a\tn/a\tn/a\t$%s", var);
- }
- phpdbg_writeln(EMPTY);
- }
+#undef VARIABLEINFO
+ } phpdbg_catch_access {
+ phpdbg_writeln("variable", "address=\"%p\" name=\"%s\"", "%p\tn/a\tn/a\t$%s", data, var);
+ } phpdbg_end_try_access();
+ } ZEND_HASH_FOREACH_END();
}
zend_hash_destroy(&vars);
@@ -204,42 +274,48 @@ PHPDBG_INFO(vars) /* {{{ */
return SUCCESS;
} /* }}} */
+PHPDBG_INFO(vars) /* {{{ */
+{
+ return phpdbg_print_symbols(0 TSRMLS_CC);
+}
+
+PHPDBG_INFO(globals) /* {{{ */
+{
+ return phpdbg_print_symbols(1 TSRMLS_CC);
+}
+
PHPDBG_INFO(literal) /* {{{ */
{
- if ((EG(in_execution) && EG(active_op_array)) || PHPDBG_G(ops)) {
- zend_op_array *ops = EG(active_op_array) ? EG(active_op_array) : PHPDBG_G(ops);
+ /* literals are assumed to not be manipulated during executing of their op_array and as such async safe */
+ zend_bool in_executor = PHPDBG_G(in_execution) && EG(current_execute_data) && EG(current_execute_data)->func;
+ if (in_executor || PHPDBG_G(ops)) {
+ zend_op_array *ops = in_executor ? &EG(current_execute_data)->func->op_array : PHPDBG_G(ops);
int literal = 0, count = ops->last_literal-1;
if (ops->function_name) {
if (ops->scope) {
- phpdbg_notice(
- "Literal Constants in %s::%s() (%d)", ops->scope->name, ops->function_name, count);
+ phpdbg_notice("literalinfo", "method=\"%s::%s\" num=\"%d\"", "Literal Constants in %s::%s() (%d)", ops->scope->name, ops->function_name, count);
} else {
- phpdbg_notice(
- "Literal Constants in %s() (%d)", ops->function_name, count);
+ phpdbg_notice("literalinfo", "function=\"%s\" num=\"%d\"", "Literal Constants in %s() (%d)", ops->function_name, count);
}
} else {
if (ops->filename) {
- phpdbg_notice(
- "Literal Constants in %s (%d)", ops->filename, count);
+ phpdbg_notice("literalinfo", "file=\"%s\" num=\"%d\"", "Literal Constants in %s (%d)", ops->filename->val, count);
} else {
- phpdbg_notice(
- "Literal Constants @ %p (%d)", ops, count);
+ phpdbg_notice("literalinfo", "opline=\"%p\" num=\"%d\"", "Literal Constants @ %p (%d)", ops, count);
}
}
while (literal < ops->last_literal) {
- if (Z_TYPE(ops->literals[literal].constant) != IS_NULL) {
- phpdbg_write("|-------- C%u -------> [", literal);
- zend_print_zval(
- &ops->literals[literal].constant, 0);
- phpdbg_write("]");
- phpdbg_writeln(EMPTY);
+ if (Z_TYPE(ops->literals[literal]) != IS_NULL) {
+ phpdbg_write("literal", "id=\"%u\"", "|-------- C%u -------> [", literal);
+ zend_print_zval(&ops->literals[literal], 0 TSRMLS_CC);
+ phpdbg_out("]\n");
}
literal++;
}
} else {
- phpdbg_error("Not executing!");
+ phpdbg_error("inactive", "type=\"execution\"", "Not executing!");
}
return SUCCESS;
@@ -247,85 +323,84 @@ PHPDBG_INFO(literal) /* {{{ */
PHPDBG_INFO(memory) /* {{{ */
{
- if (is_zend_mm(TSRMLS_C)) {
- phpdbg_notice("Memory Manager Information");
- phpdbg_notice("Current");
- phpdbg_writeln("|-------> Used:\t%.3f kB",
- (float) (zend_memory_usage(0 TSRMLS_CC)/1024));
- phpdbg_writeln("|-------> Real:\t%.3f kB",
- (float) (zend_memory_usage(1 TSRMLS_CC)/1024));
- phpdbg_notice("Peak");
- phpdbg_writeln("|-------> Used:\t%.3f kB",
- (float) (zend_memory_peak_usage(0 TSRMLS_CC)/1024));
- phpdbg_writeln("|-------> Real:\t%.3f kB",
- (float) (zend_memory_peak_usage(1 TSRMLS_CC)/1024));
+ size_t used, real, peak_used, peak_real;
+ zend_mm_heap *heap;
+ zend_bool is_mm;
+
+ if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) {
+ heap = zend_mm_set_heap(phpdbg_original_heap_sigsafe_mem(TSRMLS_C) TSRMLS_CC);
+ }
+ if ((is_mm = is_zend_mm(TSRMLS_C))) {
+ used = zend_memory_usage(0 TSRMLS_CC);
+ real = zend_memory_usage(1 TSRMLS_CC);
+ peak_used = zend_memory_peak_usage(0 TSRMLS_CC);
+ peak_real = zend_memory_peak_usage(1 TSRMLS_CC);
+ }
+ if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) {
+ zend_mm_set_heap(heap TSRMLS_CC);
+ }
+
+ if (is_mm) {
+ phpdbg_notice("meminfo", "", "Memory Manager Information");
+ phpdbg_notice("current", "", "Current");
+ phpdbg_writeln("used", "mem=\"%.3f\"", "|-------> Used:\t%.3f kB", (float) (used / 1024));
+ phpdbg_writeln("real", "mem=\"%.3f\"", "|-------> Real:\t%.3f kB", (float) (real / 1024));
+ phpdbg_notice("peak", "", "Peak");
+ phpdbg_writeln("used", "mem=\"%.3f\"", "|-------> Used:\t%.3f kB", (float) (peak_used / 1024));
+ phpdbg_writeln("real", "mem=\"%.3f\"", "|-------> Real:\t%.3f kB", (float) (peak_real / 1024));
} else {
- phpdbg_error("Memory Manager Disabled!");
+ phpdbg_error("inactive", "type=\"memory_manager\"", "Memory Manager Disabled!");
}
return SUCCESS;
} /* }}} */
-static inline void phpdbg_print_class_name(zend_class_entry **ce TSRMLS_DC) /* {{{ */
+static inline void phpdbg_print_class_name(zend_class_entry *ce TSRMLS_DC) /* {{{ */
{
- phpdbg_write(
- "%s %s %s (%d)",
- ((*ce)->type == ZEND_USER_CLASS) ?
- "User" : "Internal",
- ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ?
- "Interface" :
- ((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ?
- "Abstract Class" :
- "Class",
- (*ce)->name, zend_hash_num_elements(&(*ce)->function_table));
+ const char *visibility = ce->type == ZEND_USER_CLASS ? "User" : "Internal";
+ const char *type = (ce->ce_flags & ZEND_ACC_INTERFACE) ? "Interface" : (ce->ce_flags & ZEND_ACC_ABSTRACT) ? "Abstract Class" : "Class";
+
+ phpdbg_writeln("class", "type=\"%s\" flags=\"%s\" name=\"%.*s\" methodcount=\"%d\"", "%s %s %.*s (%d)", visibility, type, ce->name->len, ce->name->val, zend_hash_num_elements(&ce->function_table));
} /* }}} */
PHPDBG_INFO(classes) /* {{{ */
{
- HashPosition position;
- zend_class_entry **ce;
+ zend_class_entry *ce;
HashTable classes;
zend_hash_init(&classes, 8, NULL, NULL, 0);
- for (zend_hash_internal_pointer_reset_ex(EG(class_table), &position);
- zend_hash_get_current_data_ex(EG(class_table), (void**)&ce, &position) == SUCCESS;
- zend_hash_move_forward_ex(EG(class_table), &position)) {
-
- if ((*ce)->type == ZEND_USER_CLASS) {
- zend_hash_next_index_insert(
- &classes, ce, sizeof(ce), NULL);
- }
- }
-
- phpdbg_notice("User Classes (%d)",
- zend_hash_num_elements(&classes));
+ phpdbg_try_access {
+ ZEND_HASH_FOREACH_PTR(EG(class_table), ce) {
+ if (ce->type == ZEND_USER_CLASS) {
+ zend_hash_next_index_insert_ptr(&classes, ce);
+ }
+ } ZEND_HASH_FOREACH_END();
+ } phpdbg_catch_access {
+ phpdbg_notice("signalsegv", "", "Not all classes could be fetched, possibly invalid data source");
+ } phpdbg_end_try_access();
- for (zend_hash_internal_pointer_reset_ex(&classes, &position);
- zend_hash_get_current_data_ex(&classes, (void**)&ce, &position) == SUCCESS;
- zend_hash_move_forward_ex(&classes, &position)) {
+ phpdbg_notice("classinfo", "num=\"%d\"", "User Classes (%d)", zend_hash_num_elements(&classes));
+ /* once added, assume that classes are stable... until shutdown. */
+ ZEND_HASH_FOREACH_PTR(&classes, ce) {
phpdbg_print_class_name(ce TSRMLS_CC);
- phpdbg_writeln(EMPTY);
- if ((*ce)->parent) {
- zend_class_entry *pce = (*ce)->parent;
+ if (ce->parent) {
+ phpdbg_xml("<parents %r>");
+ zend_class_entry *pce = ce->parent;
do {
- phpdbg_write("|-------- ");
- phpdbg_print_class_name(&pce TSRMLS_CC);
- phpdbg_writeln(EMPTY);
+ phpdbg_out("|-------- ");
+ phpdbg_print_class_name(pce TSRMLS_CC);
} while ((pce = pce->parent));
+ phpdbg_xml("</parents>");
}
- if ((*ce)->info.user.filename) {
- phpdbg_writeln(
- "|---- in %s on line %u",
- (*ce)->info.user.filename,
- (*ce)->info.user.line_start);
+ if (ce->info.user.filename) {
+ phpdbg_writeln("classsource", "file=\"%s\" line=\"%u\"", "|---- in %s on line %u", ce->info.user.filename->val, ce->info.user.line_start);
} else {
- phpdbg_writeln("|---- no source code");
+ phpdbg_writeln("classsource", "", "|---- no source code");
}
- phpdbg_writeln(EMPTY);
- }
+ } ZEND_HASH_FOREACH_END();
zend_hash_destroy(&classes);
@@ -334,36 +409,34 @@ PHPDBG_INFO(classes) /* {{{ */
PHPDBG_INFO(funcs) /* {{{ */
{
- HashPosition position;
- zend_function *zf, **pzf;
+ zend_function *zf;
HashTable functions;
zend_hash_init(&functions, 8, NULL, NULL, 0);
- for (zend_hash_internal_pointer_reset_ex(EG(function_table), &position);
- zend_hash_get_current_data_ex(EG(function_table), (void**)&zf, &position) == SUCCESS;
- zend_hash_move_forward_ex(EG(function_table), &position)) {
+ phpdbg_try_access {
+ ZEND_HASH_FOREACH_PTR(EG(function_table), zf) {
+ if (zf->type == ZEND_USER_FUNCTION) {
+ zend_hash_next_index_insert_ptr(&functions, zf);
+ }
+ } ZEND_HASH_FOREACH_END();
+ } phpdbg_catch_access {
+ phpdbg_notice("signalsegv", "", "Not all functions could be fetched, possibly invalid data source");
+ } phpdbg_end_try_access();
- if (zf->type == ZEND_USER_FUNCTION) {
- zend_hash_next_index_insert(
- &functions, (void**) &zf, sizeof(zend_function), NULL);
- }
- }
+ phpdbg_notice("functioninfo", "num=\"%d\"", "User Functions (%d)", zend_hash_num_elements(&functions));
- phpdbg_notice("User Functions (%d)",
- zend_hash_num_elements(&functions));
+ ZEND_HASH_FOREACH_PTR(&functions, zf) {
+ zend_op_array *op_array = &zf->op_array;
- for (zend_hash_internal_pointer_reset_ex(&functions, &position);
- zend_hash_get_current_data_ex(&functions, (void**)&pzf, &position) == SUCCESS;
- zend_hash_move_forward_ex(&functions, &position)) {
- zend_op_array *op_array = &((*pzf)->op_array);
+ phpdbg_write("function", "name=\"%s\"", "|-------- %s", op_array->function_name ? op_array->function_name->val : "{main}");
- phpdbg_writeln(
- "|-------- %s in %s on line %d",
- op_array->function_name ? op_array->function_name : "{main}",
- op_array->filename ? op_array->filename : "(no source code)",
- op_array->line_start);
- }
+ if (op_array->filename) {
+ phpdbg_writeln("functionsource", "file=\"%s\" line=\"%d\"", " in %s on line %d", op_array->filename->val, op_array->line_start);
+ } else {
+ phpdbg_writeln("functionsource", "", " (no source code)");
+ }
+ } ZEND_HASH_FOREACH_END();
zend_hash_destroy(&functions);
diff --git a/sapi/phpdbg/phpdbg_info.h b/sapi/phpdbg/phpdbg_info.h
index fcdc131fd5..aac9fa3ab3 100644
--- a/sapi/phpdbg/phpdbg_info.h
+++ b/sapi/phpdbg/phpdbg_info.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -30,7 +30,9 @@ PHPDBG_INFO(break);
PHPDBG_INFO(classes);
PHPDBG_INFO(funcs);
PHPDBG_INFO(error);
+PHPDBG_INFO(constants);
PHPDBG_INFO(vars);
+PHPDBG_INFO(globals);
PHPDBG_INFO(literal);
PHPDBG_INFO(memory);
diff --git a/sapi/phpdbg/phpdbg_io.c b/sapi/phpdbg/phpdbg_io.c
new file mode 100644
index 0000000000..97f0356285
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_io.c
@@ -0,0 +1,272 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Anatol Belski <ab@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "phpdbg_io.h"
+
+#ifdef PHP_WIN32
+#undef UNICODE
+#include "win32/inet.h"
+#include <winsock2.h>
+#include <windows.h>
+#include <Ws2tcpip.h>
+#include "win32/sockets.h"
+
+#else
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <sys/socket.h>
+#include <netinet/in.h>
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#include <netdb.h>
+#include <fcntl.h>
+#include <poll.h>
+#endif
+
+ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+
+PHPDBG_API int phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo TSRMLS_DC) {
+ int got_now, i = len, j;
+ char *p = ptr;
+#ifndef PHP_WIN32
+ struct pollfd pfd;
+
+ if (tmo < 0) goto recv_once;
+ pfd.fd = sock;
+ pfd.events = POLLIN;
+
+ j = poll(&pfd, 1, tmo);
+
+ if (j == 0) {
+#else
+ struct fd_set readfds;
+ struct timeval ttmo;
+
+ if (tmo < 0) goto recv_once;
+ FD_ZERO(&readfds);
+ FD_SET(sock, &readfds);
+
+ ttmo.tv_sec = 0;
+ ttmo.tv_usec = tmo*1000;
+
+ j = select(0, &readfds, NULL, NULL, &ttmo);
+
+ if (j <= 0) {
+#endif
+ return -1;
+ }
+
+recv_once:
+ while(i > 0) {
+ if (tmo < 0) {
+ /* There's something to read. Read what's available and proceed
+ disregarding whether len could be exhausted or not.*/
+ int can_read = recv(sock, p, i, MSG_PEEK);
+#ifndef _WIN32
+ if (can_read == -1 && errno == EINTR) {
+ continue;
+ }
+#endif
+ i = can_read;
+ }
+
+#ifdef _WIN32
+ got_now = recv(sock, p, i, 0);
+#else
+ do {
+ got_now = recv(sock, p, i, 0);
+ } while (got_now == -1 && errno == EINTR);
+#endif
+
+ if (got_now == -1) {
+ write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Read operation timed out!\n"));
+ return -1;
+ }
+ i -= got_now;
+ p += got_now;
+ }
+
+ return p - ptr;
+}
+
+PHPDBG_API int phpdbg_send_bytes(int sock, const char *ptr, int len) {
+ int sent, i = len;
+ const char *p = ptr;
+/* XXX poll/select needed here? */
+ while(i > 0) {
+ sent = send(sock, p, i, 0);
+ if (sent == -1) {
+ return -1;
+ }
+ i -= sent;
+ p += sent;
+ }
+
+ return len;
+}
+
+
+PHPDBG_API int phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_DC) {
+ if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) {
+ return phpdbg_consume_bytes(sock, ptr, len, tmo TSRMLS_CC);
+ }
+
+ return read(sock, ptr, len);
+}
+
+
+PHPDBG_API int phpdbg_mixed_write(int sock, const char *ptr, int len TSRMLS_DC) {
+ if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) {
+ return phpdbg_send_bytes(sock, ptr, len);
+ }
+
+ return write(sock, ptr, len);
+}
+
+
+PHPDBG_API int phpdbg_open_socket(const char *interface, unsigned short port TSRMLS_DC) {
+ struct addrinfo res;
+ int fd = phpdbg_create_listenable_socket(interface, port, &res TSRMLS_CC);
+
+ if (fd == -1) {
+ return -1;
+ }
+
+ if (bind(fd, res.ai_addr, res.ai_addrlen) == -1) {
+ phpdbg_close_socket(fd);
+ return -4;
+ }
+
+ listen(fd, 5);
+
+ return fd;
+}
+
+
+PHPDBG_API int phpdbg_create_listenable_socket(const char *addr, unsigned short port, struct addrinfo *addr_res TSRMLS_DC) {
+ int sock = -1, rc;
+ int reuse = 1;
+ struct in6_addr serveraddr;
+ struct addrinfo hints, *res = NULL;
+ char port_buf[8];
+ int8_t any_addr = *addr == '*';
+
+ do {
+ memset(&hints, 0, sizeof hints);
+ if (any_addr) {
+ hints.ai_flags = AI_PASSIVE;
+ } else {
+ hints.ai_flags = AI_NUMERICSERV;
+ }
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ rc = inet_pton(AF_INET, addr, &serveraddr);
+ if (1 == rc) {
+ hints.ai_family = AF_INET;
+ if (!any_addr) {
+ hints.ai_flags |= AI_NUMERICHOST;
+ }
+ } else {
+ rc = inet_pton(AF_INET6, addr, &serveraddr);
+ if (1 == rc) {
+ hints.ai_family = AF_INET6;
+ if (!any_addr) {
+ hints.ai_flags |= AI_NUMERICHOST;
+ }
+ } else {
+ /* XXX get host by name ??? */
+ }
+ }
+
+ snprintf(port_buf, 7, "%u", port);
+ if (!any_addr) {
+ rc = getaddrinfo(addr, port_buf, &hints, &res);
+ } else {
+ rc = getaddrinfo(NULL, port_buf, &hints, &res);
+ }
+
+ if (0 != rc) {
+#ifndef PHP_WIN32
+ if (rc == EAI_SYSTEM) {
+ char buf[128];
+ int wrote;
+
+ wrote = snprintf(buf, 128, "Could not translate address '%s'", addr);
+ buf[wrote] = '\0';
+ write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf));
+
+ return sock;
+ } else {
+#endif
+ char buf[256];
+ int wrote;
+
+ wrote = snprintf(buf, 256, "Host '%s' not found. %s", addr, estrdup(gai_strerror(rc)));
+ buf[wrote] = '\0';
+ write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf));
+
+ return sock;
+#ifndef PHP_WIN32
+ }
+#endif
+ return sock;
+ }
+
+ if((sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) {
+ char buf[128];
+ int wrote;
+
+ wrote = sprintf(buf, "Unable to create socket");
+ buf[wrote] = '\0';
+ write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf));
+
+ return sock;
+ }
+
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse)) == -1) {
+ phpdbg_close_socket(sock);
+ return sock;
+ }
+
+
+ } while (0);
+
+ *addr_res = *res;
+
+ return sock;
+}
+
+PHPDBG_API void phpdbg_close_socket(int sock) {
+ if (socket >= 0) {
+#ifdef _WIN32
+ closesocket(sock);
+#else
+ shutdown(sock, SHUT_RDWR);
+ close(sock);
+#endif
+ }
+}
+
diff --git a/sapi/phpdbg/phpdbg_io.h b/sapi/phpdbg/phpdbg_io.h
new file mode 100644
index 0000000000..3ac8f4112d
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_io.h
@@ -0,0 +1,34 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Anatol Belski <ab@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef PHPDBG_IO_H
+#define PHPDBG_IO_H
+
+#include "phpdbg.h"
+
+PHPDBG_API int phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo TSRMLS_DC);
+PHPDBG_API int phpdbg_send_bytes(int sock, const char *ptr, int len);
+PHPDBG_API int phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_DC);
+PHPDBG_API int phpdbg_mixed_write(int sock, const char *ptr, int len TSRMLS_DC);
+
+PHPDBG_API int phpdbg_create_listenable_socket(const char *addr, unsigned short port, struct addrinfo *res TSRMLS_DC);
+PHPDBG_API int phpdbg_open_socket(const char *interface, unsigned short port TSRMLS_DC);
+PHPDBG_API void phpdbg_close_socket(int sock);
+
+#endif /* PHPDBG_IO_H */
+
diff --git a/sapi/phpdbg/phpdbg_lexer.c b/sapi/phpdbg/phpdbg_lexer.c
index 3092dc396d..90f3a449da 100644
--- a/sapi/phpdbg/phpdbg_lexer.c
+++ b/sapi/phpdbg/phpdbg_lexer.c
@@ -1,5 +1,5 @@
/* Generated by re2c 0.13.5 */
-#line 1 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 1 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
/*
* phpdbg_lexer.l
*/
@@ -23,8 +23,9 @@
#define YYFILL(n)
#define NORMAL 0
-#define RAW 1
-#define INITIAL 2
+#define PRE_RAW 1
+#define RAW 2
+#define INITIAL 3
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
@@ -44,14 +45,18 @@ restart:
LEX(text) = YYCURSOR;
-#line 48 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
+#line 49 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
{
YYCTYPE yych;
unsigned int yyaccept = 0;
- if (YYGETCONDITION() < 1) {
- goto yyc_NORMAL;
+ if (YYGETCONDITION() < 2) {
+ if (YYGETCONDITION() < 1) {
+ goto yyc_NORMAL;
+ } else {
+ goto yyc_PRE_RAW;
+ }
} else {
- if (YYGETCONDITION() < 2) {
+ if (YYGETCONDITION() < 3) {
goto yyc_RAW;
} else {
goto yyc_INITIAL;
@@ -62,10 +67,10 @@ yyc_INITIAL:
{
static const unsigned char yybm[] = {
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 128, 128, 0, 0, 128, 0, 0,
+ 0, 192, 96, 0, 0, 192, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 128, 0, 0, 0, 0, 0, 0, 0,
+ 192, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -98,1046 +103,1417 @@ yyc_INITIAL:
YYDEBUG(0, *YYCURSOR);
YYFILL(4);
yych = *YYCURSOR;
- if (yych <= 'D') {
- if (yych <= '\n') {
- if (yych <= 0x00) goto yy6;
- if (yych <= 0x08) goto yy11;
- if (yych >= '\n') goto yy4;
+ if (yybm[0+yych] & 32) {
+ goto yy4;
+ }
+ if (yych <= 'E') {
+ if (yych <= '\f') {
+ if (yych <= 0x00) goto yy7;
+ if (yych != '\t') goto yy12;
} else {
- if (yych <= '\r') {
- if (yych <= '\f') goto yy11;
+ if (yych <= 0x1F) {
+ if (yych >= 0x0E) goto yy12;
} else {
- if (yych != ' ') goto yy11;
+ if (yych <= ' ') goto yy2;
+ if (yych <= 'D') goto yy12;
+ goto yy8;
}
}
} else {
if (yych <= 'd') {
- if (yych <= 'Q') {
- if (yych <= 'E') goto yy7;
- goto yy11;
- } else {
- if (yych <= 'R') goto yy10;
- if (yych <= 'S') goto yy8;
- goto yy11;
- }
+ if (yych <= 'Q') goto yy12;
+ if (yych <= 'R') goto yy11;
+ if (yych <= 'S') goto yy9;
+ goto yy12;
} else {
if (yych <= 'q') {
- if (yych <= 'e') goto yy7;
- goto yy11;
+ if (yych <= 'e') goto yy8;
+ goto yy12;
} else {
- if (yych <= 'r') goto yy9;
- if (yych <= 's') goto yy8;
- goto yy11;
+ if (yych <= 'r') goto yy10;
+ if (yych <= 's') goto yy9;
+ goto yy12;
}
}
}
+yy2:
YYDEBUG(2, *YYCURSOR);
++YYCURSOR;
if ((yych = *YYCURSOR) <= '\f') {
+ if (yych <= 0x00) goto yy29;
if (yych <= 0x08) goto yy3;
- if (yych <= '\n') goto yy26;
+ if (yych <= '\n') goto yy29;
} else {
- if (yych <= '\r') goto yy26;
- if (yych == ' ') goto yy26;
+ if (yych <= '\r') goto yy29;
+ if (yych == ' ') goto yy29;
}
yy3:
YYDEBUG(3, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 161 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 176 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
YYSETCONDITION(NORMAL);
YYCURSOR = LEX(text);
goto restart;
}
-#line 154 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
+#line 161 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
yy4:
YYDEBUG(4, *YYCURSOR);
++YYCURSOR;
- if ((yych = *YYCURSOR) <= '\f') {
- if (yych <= 0x08) goto yy5;
- if (yych <= '\n') goto yy26;
- } else {
- if (yych <= '\r') goto yy26;
- if (yych == ' ') goto yy26;
- }
-yy5:
+ YYFILL(1);
+ yych = *YYCURSOR;
YYDEBUG(5, *YYCURSOR);
+ if (yybm[0+yych] & 128) {
+ goto yy28;
+ }
+ if (yych <= 0x00) goto yy27;
+ if (yych == '\n') goto yy4;
+yy6:
+ YYDEBUG(6, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 68 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 69 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
return 0;
}
-#line 172 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy6:
- YYDEBUG(6, *YYCURSOR);
- yych = *++YYCURSOR;
- goto yy3;
+#line 180 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
yy7:
YYDEBUG(7, *YYCURSOR);
- yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'V') goto yy22;
- if (yych == 'v') goto yy22;
+ yych = *++YYCURSOR;
goto yy3;
yy8:
YYDEBUG(8, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'H') goto yy18;
- if (yych == 'h') goto yy18;
+ if (yych == 'V') goto yy23;
+ if (yych == 'v') goto yy23;
goto yy3;
yy9:
YYDEBUG(9, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yybm[0+yych] & 128) {
- goto yy15;
- }
- if (yych == 'U') goto yy12;
- if (yych == 'u') goto yy12;
+ if (yych == 'H') goto yy19;
+ if (yych == 'h') goto yy19;
goto yy3;
yy10:
YYDEBUG(10, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'U') goto yy12;
- if (yych == 'u') goto yy12;
+ if (yybm[0+yych] & 64) {
+ goto yy16;
+ }
+ if (yych == 'U') goto yy13;
+ if (yych == 'u') goto yy13;
goto yy3;
yy11:
YYDEBUG(11, *YYCURSOR);
- yych = *++YYCURSOR;
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == 'U') goto yy13;
+ if (yych == 'u') goto yy13;
goto yy3;
yy12:
YYDEBUG(12, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'N') goto yy14;
- if (yych == 'n') goto yy14;
+ goto yy3;
yy13:
YYDEBUG(13, *YYCURSOR);
- YYCURSOR = YYMARKER;
- goto yy3;
+ yych = *++YYCURSOR;
+ if (yych == 'N') goto yy15;
+ if (yych == 'n') goto yy15;
yy14:
YYDEBUG(14, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yybm[0+yych] & 128) {
- goto yy15;
- }
- goto yy13;
+ YYCURSOR = YYMARKER;
+ goto yy3;
yy15:
YYDEBUG(15, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yybm[0+yych] & 64) {
+ goto yy16;
+ }
+ goto yy14;
+yy16:
+ YYDEBUG(16, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(16, *YYCURSOR);
- if (yybm[0+yych] & 128) {
- goto yy15;
- }
YYDEBUG(17, *YYCURSOR);
+ if (yybm[0+yych] & 64) {
+ goto yy16;
+ }
+ YYDEBUG(18, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 155 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 163 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
- YYSETCONDITION(RAW);
+ YYSETCONDITION(PRE_RAW);
phpdbg_init_param(yylval, EMPTY_PARAM);
return T_RUN;
}
-#line 245 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy18:
- YYDEBUG(18, *YYCURSOR);
+#line 253 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy19:
+ YYDEBUG(19, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= '\f') {
- if (yych <= 0x08) goto yy13;
- if (yych >= '\v') goto yy13;
+ if (yych <= 0x08) goto yy14;
+ if (yych >= '\v') goto yy14;
} else {
- if (yych <= '\r') goto yy19;
- if (yych != ' ') goto yy13;
+ if (yych <= '\r') goto yy20;
+ if (yych != ' ') goto yy14;
}
-yy19:
- YYDEBUG(19, *YYCURSOR);
+yy20:
+ YYDEBUG(20, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(20, *YYCURSOR);
+ YYDEBUG(21, *YYCURSOR);
if (yych <= '\f') {
- if (yych <= 0x08) goto yy21;
- if (yych <= '\n') goto yy19;
+ if (yych <= 0x08) goto yy22;
+ if (yych <= '\n') goto yy20;
} else {
- if (yych <= '\r') goto yy19;
- if (yych == ' ') goto yy19;
+ if (yych <= '\r') goto yy20;
+ if (yych == ' ') goto yy20;
}
-yy21:
- YYDEBUG(21, *YYCURSOR);
+yy22:
+ YYDEBUG(22, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 150 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 158 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
- YYSETCONDITION(RAW);
+ YYSETCONDITION(PRE_RAW);
phpdbg_init_param(yylval, EMPTY_PARAM);
return T_SHELL;
}
-#line 278 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy22:
- YYDEBUG(22, *YYCURSOR);
+#line 286 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy23:
+ YYDEBUG(23, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= '\f') {
- if (yych <= 0x08) goto yy13;
- if (yych >= '\v') goto yy13;
+ if (yych <= 0x08) goto yy14;
+ if (yych >= '\v') goto yy14;
} else {
- if (yych <= '\r') goto yy23;
- if (yych != ' ') goto yy13;
+ if (yych <= '\r') goto yy24;
+ if (yych != ' ') goto yy14;
}
-yy23:
- YYDEBUG(23, *YYCURSOR);
+yy24:
+ YYDEBUG(24, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(24, *YYCURSOR);
+ YYDEBUG(25, *YYCURSOR);
if (yych <= '\f') {
- if (yych <= 0x08) goto yy25;
- if (yych <= '\n') goto yy23;
+ if (yych <= 0x08) goto yy26;
+ if (yych <= '\n') goto yy24;
} else {
- if (yych <= '\r') goto yy23;
- if (yych == ' ') goto yy23;
+ if (yych <= '\r') goto yy24;
+ if (yych == ' ') goto yy24;
}
-yy25:
- YYDEBUG(25, *YYCURSOR);
+yy26:
+ YYDEBUG(26, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 145 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 153 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
- YYSETCONDITION(RAW);
+ YYSETCONDITION(PRE_RAW);
phpdbg_init_param(yylval, EMPTY_PARAM);
return T_EVAL;
}
-#line 311 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy26:
- YYDEBUG(26, *YYCURSOR);
+#line 319 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy27:
+ YYDEBUG(27, *YYCURSOR);
+ yych = *++YYCURSOR;
+ goto yy6;
+yy28:
+ YYDEBUG(28, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(27, *YYCURSOR);
- if (yych <= '\f') {
- if (yych <= 0x08) goto yy28;
- if (yych <= '\n') goto yy26;
- } else {
- if (yych <= '\r') goto yy26;
- if (yych == ' ') goto yy26;
+yy29:
+ YYDEBUG(29, *YYCURSOR);
+ if (yybm[0+yych] & 128) {
+ goto yy28;
}
-yy28:
- YYDEBUG(28, *YYCURSOR);
+ if (yych <= 0x00) goto yy27;
+ if (yych == '\n') goto yy4;
+ YYDEBUG(30, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 147 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
/* ignore whitespace */
goto restart;
}
-#line 334 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
+#line 344 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
}
/* *********************************** */
yyc_NORMAL:
{
static const unsigned char yybm[] = {
- 0, 16, 16, 16, 16, 16, 16, 16,
- 16, 8, 8, 16, 16, 8, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 8, 16, 16, 0, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 48, 16,
- 176, 176, 176, 176, 176, 176, 176, 176,
- 176, 176, 0, 16, 16, 16, 16, 16,
- 16, 208, 208, 208, 208, 208, 208, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 16, 16, 16, 16, 16,
- 16, 208, 208, 208, 208, 208, 208, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
+ 0, 8, 8, 8, 8, 8, 8, 8,
+ 8, 66, 68, 8, 8, 66, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 66, 8, 8, 0, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 24, 8,
+ 152, 152, 152, 152, 152, 152, 152, 152,
+ 152, 152, 0, 8, 8, 8, 8, 8,
+ 8, 168, 168, 168, 168, 168, 168, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 8, 8, 8, 8, 8,
+ 8, 168, 168, 168, 168, 168, 168, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
};
- YYDEBUG(29, *YYCURSOR);
+ YYDEBUG(31, *YYCURSOR);
YYFILL(11);
yych = *YYCURSOR;
- YYDEBUG(-1, yych);
- switch (yych) {
- case 0x00: goto yy36;
- case '\t':
- case '\r':
- case ' ': goto yy31;
- case '\n': goto yy34;
- case '#': goto yy55;
- case '-': goto yy41;
- case '.':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': goto yy42;
- case '0': goto yy45;
- case ':': goto yy57;
- case 'D':
- case 'd': goto yy46;
- case 'E':
- case 'e': goto yy47;
- case 'F':
- case 'f': goto yy48;
- case 'I':
- case 'i': goto yy37;
- case 'N':
- case 'n': goto yy49;
- case 'O':
- case 'o': goto yy50;
- case 'T':
- case 't': goto yy51;
- case 'Y':
- case 'y': goto yy52;
- case 'Z': goto yy53;
- case 'z': goto yy54;
- default: goto yy39;
+ if (yybm[0+yych] & 2) {
+ goto yy33;
}
-yy31:
- YYDEBUG(31, *YYCURSOR);
+ if (yych <= 'N') {
+ if (yych <= '0') {
+ if (yych <= '#') {
+ if (yych <= '\t') {
+ if (yych <= 0x00) goto yy39;
+ goto yy43;
+ } else {
+ if (yych <= '\n') goto yy36;
+ if (yych <= '"') goto yy43;
+ goto yy58;
+ }
+ } else {
+ if (yych <= '-') {
+ if (yych <= ',') goto yy43;
+ goto yy40;
+ } else {
+ if (yych <= '.') goto yy45;
+ if (yych <= '/') goto yy43;
+ goto yy48;
+ }
+ }
+ } else {
+ if (yych <= 'E') {
+ if (yych <= ':') {
+ if (yych <= '9') goto yy45;
+ goto yy60;
+ } else {
+ if (yych <= 'C') goto yy43;
+ if (yych <= 'D') goto yy49;
+ goto yy50;
+ }
+ } else {
+ if (yych <= 'H') {
+ if (yych <= 'F') goto yy51;
+ goto yy43;
+ } else {
+ if (yych <= 'I') goto yy42;
+ if (yych <= 'M') goto yy43;
+ goto yy52;
+ }
+ }
+ }
+ } else {
+ if (yych <= 'f') {
+ if (yych <= 'Y') {
+ if (yych <= 'S') {
+ if (yych <= 'O') goto yy53;
+ goto yy43;
+ } else {
+ if (yych <= 'T') goto yy54;
+ if (yych <= 'X') goto yy43;
+ goto yy55;
+ }
+ } else {
+ if (yych <= 'c') {
+ if (yych <= 'Z') goto yy56;
+ goto yy43;
+ } else {
+ if (yych <= 'd') goto yy49;
+ if (yych <= 'e') goto yy50;
+ goto yy51;
+ }
+ }
+ } else {
+ if (yych <= 'o') {
+ if (yych <= 'i') {
+ if (yych <= 'h') goto yy43;
+ goto yy42;
+ } else {
+ if (yych <= 'm') goto yy43;
+ if (yych <= 'n') goto yy52;
+ goto yy53;
+ }
+ } else {
+ if (yych <= 'x') {
+ if (yych == 't') goto yy54;
+ goto yy43;
+ } else {
+ if (yych <= 'y') goto yy55;
+ if (yych <= 'z') goto yy57;
+ goto yy43;
+ }
+ }
+ }
+ }
+yy33:
+ YYDEBUG(33, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(32, *YYCURSOR);
- if (yybm[0+yych] & 8) {
- goto yy31;
+ YYDEBUG(34, *YYCURSOR);
+ if (yybm[0+yych] & 2) {
+ goto yy33;
}
- YYDEBUG(33, *YYCURSOR);
+ if (yych <= 0x00) goto yy39;
+ if (yych == '\n') goto yy36;
+ YYDEBUG(35, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 147 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
/* ignore whitespace */
goto restart;
}
-#line 434 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy34:
- YYDEBUG(34, *YYCURSOR);
+#line 493 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy36:
+ YYDEBUG(36, *YYCURSOR);
++YYCURSOR;
- if (yybm[0+(yych = *YYCURSOR)] & 8) {
- goto yy31;
+ YYFILL(1);
+ yych = *YYCURSOR;
+ YYDEBUG(37, *YYCURSOR);
+ if (yybm[0+yych] & 2) {
+ goto yy33;
}
-yy35:
- YYDEBUG(35, *YYCURSOR);
+ if (yych <= 0x00) goto yy39;
+ if (yych == '\n') goto yy36;
+yy38:
+ YYDEBUG(38, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 68 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 69 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
return 0;
}
-#line 448 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy36:
- YYDEBUG(36, *YYCURSOR);
+#line 512 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy39:
+ YYDEBUG(39, *YYCURSOR);
yych = *++YYCURSOR;
- goto yy35;
-yy37:
- YYDEBUG(37, *YYCURSOR);
+ goto yy38;
+yy40:
+ YYDEBUG(40, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'F') goto yy106;
- if (yych == 'f') goto yy106;
- goto yy40;
-yy38:
- YYDEBUG(38, *YYCURSOR);
+ if (yybm[0+yych] & 16) {
+ goto yy45;
+ }
+ if (yych == 'r') goto yy113;
+ goto yy44;
+yy41:
+ YYDEBUG(41, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 125 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 133 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
phpdbg_init_param(yylval, STR_PARAM);
yylval->str = zend_strndup(yytext, yyleng);
yylval->len = yyleng;
return T_ID;
}
-#line 470 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy39:
- YYDEBUG(39, *YYCURSOR);
+#line 536 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy42:
+ YYDEBUG(42, *YYCURSOR);
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == 'F') goto yy109;
+ if (yych == 'f') goto yy109;
+ goto yy44;
+yy43:
+ YYDEBUG(43, *YYCURSOR);
yyaccept = 0;
YYMARKER = ++YYCURSOR;
YYFILL(3);
yych = *YYCURSOR;
-yy40:
- YYDEBUG(40, *YYCURSOR);
- if (yybm[0+yych] & 16) {
- goto yy39;
- }
- if (yych <= '9') goto yy38;
- goto yy62;
-yy41:
- YYDEBUG(41, *YYCURSOR);
- yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- if (yybm[0+yych] & 32) {
- goto yy42;
+yy44:
+ YYDEBUG(44, *YYCURSOR);
+ if (yybm[0+yych] & 8) {
+ goto yy43;
}
- goto yy40;
-yy42:
- YYDEBUG(42, *YYCURSOR);
+ if (yych <= '9') goto yy41;
+ goto yy65;
+yy45:
+ YYDEBUG(45, *YYCURSOR);
yyaccept = 1;
YYMARKER = ++YYCURSOR;
YYFILL(3);
yych = *YYCURSOR;
- YYDEBUG(43, *YYCURSOR);
- if (yybm[0+yych] & 32) {
- goto yy42;
+ YYDEBUG(46, *YYCURSOR);
+ if (yybm[0+yych] & 16) {
+ goto yy45;
}
if (yych <= 0x1F) {
if (yych <= '\n') {
- if (yych <= 0x00) goto yy44;
- if (yych <= 0x08) goto yy39;
+ if (yych <= 0x00) goto yy47;
+ if (yych <= 0x08) goto yy43;
} else {
- if (yych != '\r') goto yy39;
+ if (yych != '\r') goto yy43;
}
} else {
if (yych <= '#') {
- if (yych <= ' ') goto yy44;
- if (yych <= '"') goto yy39;
+ if (yych <= ' ') goto yy47;
+ if (yych <= '"') goto yy43;
} else {
- if (yych == ':') goto yy62;
- goto yy39;
+ if (yych == ':') goto yy65;
+ goto yy43;
}
}
-yy44:
- YYDEBUG(44, *YYCURSOR);
+yy47:
+ YYDEBUG(47, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 106 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 114 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
phpdbg_init_param(yylval, NUMERIC_PARAM);
yylval->num = atoi(yytext);
return T_DIGITS;
}
-#line 527 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy45:
- YYDEBUG(45, *YYCURSOR);
+#line 592 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy48:
+ YYDEBUG(48, *YYCURSOR);
yyaccept = 1;
yych = *(YYMARKER = ++YYCURSOR);
- if (yybm[0+yych] & 32) {
- goto yy42;
+ if (yybm[0+yych] & 16) {
+ goto yy45;
}
if (yych <= 0x1F) {
if (yych <= '\n') {
- if (yych <= 0x00) goto yy44;
- if (yych <= 0x08) goto yy40;
- goto yy44;
+ if (yych <= 0x00) goto yy47;
+ if (yych <= 0x08) goto yy44;
+ goto yy47;
} else {
- if (yych == '\r') goto yy44;
- goto yy40;
+ if (yych == '\r') goto yy47;
+ goto yy44;
}
} else {
if (yych <= '#') {
- if (yych <= ' ') goto yy44;
- if (yych <= '"') goto yy40;
- goto yy44;
+ if (yych <= ' ') goto yy47;
+ if (yych <= '"') goto yy44;
+ goto yy47;
} else {
- if (yych == 'x') goto yy102;
- goto yy40;
+ if (yych == 'x') goto yy105;
+ goto yy44;
}
}
-yy46:
- YYDEBUG(46, *YYCURSOR);
- yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'I') goto yy96;
- if (yych == 'i') goto yy96;
- goto yy40;
-yy47:
- YYDEBUG(47, *YYCURSOR);
- yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'N') goto yy91;
- if (yych == 'n') goto yy91;
- goto yy40;
-yy48:
- YYDEBUG(48, *YYCURSOR);
- yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'A') goto yy88;
- if (yych == 'a') goto yy88;
- goto yy40;
yy49:
YYDEBUG(49, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'O') goto yy84;
- if (yych == 'o') goto yy84;
- goto yy40;
+ if (yych == 'I') goto yy99;
+ if (yych == 'i') goto yy99;
+ goto yy44;
yy50:
YYDEBUG(50, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych <= 'N') {
- if (yych == 'F') goto yy83;
- if (yych <= 'M') goto yy40;
- goto yy77;
- } else {
- if (yych <= 'f') {
- if (yych <= 'e') goto yy40;
- goto yy83;
- } else {
- if (yych == 'n') goto yy77;
- goto yy40;
- }
- }
+ if (yych == 'N') goto yy94;
+ if (yych == 'n') goto yy94;
+ goto yy44;
yy51:
YYDEBUG(51, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'R') goto yy81;
- if (yych == 'r') goto yy81;
- goto yy40;
+ if (yych == 'A') goto yy91;
+ if (yych == 'a') goto yy91;
+ goto yy44;
yy52:
YYDEBUG(52, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'E') goto yy76;
- if (yych == 'e') goto yy76;
- goto yy40;
+ if (yych == 'O') goto yy87;
+ if (yych == 'o') goto yy87;
+ goto yy44;
yy53:
YYDEBUG(53, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'E') goto yy73;
- goto yy40;
+ if (yych <= 'N') {
+ if (yych == 'F') goto yy86;
+ if (yych <= 'M') goto yy44;
+ goto yy80;
+ } else {
+ if (yych <= 'f') {
+ if (yych <= 'e') goto yy44;
+ goto yy86;
+ } else {
+ if (yych == 'n') goto yy80;
+ goto yy44;
+ }
+ }
yy54:
YYDEBUG(54, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'e') goto yy61;
- goto yy40;
+ if (yych == 'R') goto yy84;
+ if (yych == 'r') goto yy84;
+ goto yy44;
yy55:
YYDEBUG(55, *YYCURSOR);
- ++YYCURSOR;
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == 'E') goto yy79;
+ if (yych == 'e') goto yy79;
+ goto yy44;
+yy56:
YYDEBUG(56, *YYCURSOR);
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == 'E') goto yy76;
+ goto yy44;
+yy57:
+ YYDEBUG(57, *YYCURSOR);
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == 'e') goto yy64;
+ goto yy44;
+yy58:
+ YYDEBUG(58, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(59, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 84 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 92 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
return T_POUND;
}
-#line 634 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy57:
- YYDEBUG(57, *YYCURSOR);
+#line 699 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy60:
+ YYDEBUG(60, *YYCURSOR);
++YYCURSOR;
- if ((yych = *YYCURSOR) == ':') goto yy59;
- YYDEBUG(58, *YYCURSOR);
+ if ((yych = *YYCURSOR) == ':') goto yy62;
+ YYDEBUG(61, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 90 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 98 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
return T_COLON;
}
-#line 645 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy59:
- YYDEBUG(59, *YYCURSOR);
+#line 710 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy62:
+ YYDEBUG(62, *YYCURSOR);
++YYCURSOR;
- YYDEBUG(60, *YYCURSOR);
+ YYDEBUG(63, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 87 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 95 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
return T_DCOLON;
}
-#line 655 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy61:
- YYDEBUG(61, *YYCURSOR);
+#line 720 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy64:
+ YYDEBUG(64, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'n') goto yy67;
- goto yy40;
-yy62:
- YYDEBUG(62, *YYCURSOR);
+ if (yych == 'n') goto yy70;
+ goto yy44;
+yy65:
+ YYDEBUG(65, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == '/') goto yy64;
-yy63:
- YYDEBUG(63, *YYCURSOR);
+ if (yych == '/') goto yy67;
+yy66:
+ YYDEBUG(66, *YYCURSOR);
YYCURSOR = YYMARKER;
- if (yyaccept <= 1) {
- if (yyaccept <= 0) {
- goto yy38;
+ if (yyaccept <= 2) {
+ if (yyaccept <= 1) {
+ if (yyaccept <= 0) {
+ goto yy41;
+ } else {
+ goto yy47;
+ }
} else {
- goto yy44;
+ goto yy75;
}
} else {
- if (yyaccept <= 2) {
- goto yy72;
+ if (yyaccept <= 3) {
+ goto yy108;
} else {
- goto yy105;
+ goto yy119;
}
}
-yy64:
- YYDEBUG(64, *YYCURSOR);
+yy67:
+ YYDEBUG(67, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '/') goto yy63;
- YYDEBUG(65, *YYCURSOR);
+ if (yych != '/') goto yy66;
+ YYDEBUG(68, *YYCURSOR);
++YYCURSOR;
- YYDEBUG(66, *YYCURSOR);
+ YYDEBUG(69, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 78 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 86 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
phpdbg_init_param(yylval, STR_PARAM);
yylval->str = zend_strndup(yytext, yyleng);
yylval->len = yyleng;
return T_PROTO;
}
-#line 697 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy67:
- YYDEBUG(67, *YYCURSOR);
+#line 766 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy70:
+ YYDEBUG(70, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych != 'd') goto yy40;
- YYDEBUG(68, *YYCURSOR);
+ if (yych != 'd') goto yy44;
+ YYDEBUG(71, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych != '_') goto yy40;
-yy69:
- YYDEBUG(69, *YYCURSOR);
+ if (yych != '_') goto yy44;
+yy72:
+ YYDEBUG(72, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yybm[0+yych] & 64) {
- goto yy70;
+ if (yybm[0+yych] & 32) {
+ goto yy73;
}
- goto yy40;
-yy70:
- YYDEBUG(70, *YYCURSOR);
+ goto yy44;
+yy73:
+ YYDEBUG(73, *YYCURSOR);
yyaccept = 2;
YYMARKER = ++YYCURSOR;
YYFILL(3);
yych = *YYCURSOR;
- YYDEBUG(71, *YYCURSOR);
- if (yybm[0+yych] & 64) {
- goto yy70;
+ YYDEBUG(74, *YYCURSOR);
+ if (yybm[0+yych] & 32) {
+ goto yy73;
}
if (yych <= 0x1F) {
if (yych <= '\n') {
- if (yych <= 0x00) goto yy72;
- if (yych <= 0x08) goto yy39;
+ if (yych <= 0x00) goto yy75;
+ if (yych <= 0x08) goto yy43;
} else {
- if (yych != '\r') goto yy39;
+ if (yych != '\r') goto yy43;
}
} else {
if (yych <= '#') {
- if (yych <= ' ') goto yy72;
- if (yych <= '"') goto yy39;
+ if (yych <= ' ') goto yy75;
+ if (yych <= '"') goto yy43;
} else {
- if (yych == ':') goto yy62;
- goto yy39;
+ if (yych == ':') goto yy65;
+ goto yy43;
}
}
-yy72:
- YYDEBUG(72, *YYCURSOR);
+yy75:
+ YYDEBUG(75, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 118 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 126 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
phpdbg_init_param(yylval, OP_PARAM);
yylval->str = zend_strndup(yytext, yyleng);
yylval->len = yyleng;
return T_OPCODE;
}
-#line 751 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy73:
- YYDEBUG(73, *YYCURSOR);
+#line 820 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy76:
+ YYDEBUG(76, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych != 'N') goto yy40;
- YYDEBUG(74, *YYCURSOR);
+ if (yych != 'N') goto yy44;
+ YYDEBUG(77, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych != 'D') goto yy40;
- YYDEBUG(75, *YYCURSOR);
+ if (yych != 'D') goto yy44;
+ YYDEBUG(78, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == '_') goto yy69;
- goto yy40;
-yy76:
- YYDEBUG(76, *YYCURSOR);
+ if (yych == '_') goto yy72;
+ goto yy44;
+yy79:
+ YYDEBUG(79, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'S') goto yy77;
- if (yych != 's') goto yy40;
-yy77:
- YYDEBUG(77, *YYCURSOR);
+ if (yych == 'S') goto yy80;
+ if (yych != 's') goto yy44;
+yy80:
+ YYDEBUG(80, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych <= '\f') {
- if (yych <= 0x08) goto yy40;
- if (yych >= '\v') goto yy40;
- } else {
- if (yych <= '\r') goto yy78;
- if (yych != ' ') goto yy40;
+ if (yybm[0+yych] & 64) {
+ goto yy81;
}
-yy78:
- YYDEBUG(78, *YYCURSOR);
+ goto yy44;
+yy81:
+ YYDEBUG(81, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(79, *YYCURSOR);
- if (yych <= '\f') {
- if (yych <= 0x08) goto yy80;
- if (yych <= '\n') goto yy78;
- } else {
- if (yych <= '\r') goto yy78;
- if (yych == ' ') goto yy78;
+ YYDEBUG(82, *YYCURSOR);
+ if (yybm[0+yych] & 64) {
+ goto yy81;
}
-yy80:
- YYDEBUG(80, *YYCURSOR);
+ YYDEBUG(83, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 94 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 102 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
phpdbg_init_param(yylval, NUMERIC_PARAM);
yylval->num = 1;
return T_TRUTHY;
}
-#line 805 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy81:
- YYDEBUG(81, *YYCURSOR);
+#line 866 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy84:
+ YYDEBUG(84, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'U') goto yy82;
- if (yych != 'u') goto yy40;
-yy82:
- YYDEBUG(82, *YYCURSOR);
+ if (yych == 'U') goto yy85;
+ if (yych != 'u') goto yy44;
+yy85:
+ YYDEBUG(85, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'E') goto yy77;
- if (yych == 'e') goto yy77;
- goto yy40;
-yy83:
- YYDEBUG(83, *YYCURSOR);
+ if (yych == 'E') goto yy80;
+ if (yych == 'e') goto yy80;
+ goto yy44;
+yy86:
+ YYDEBUG(86, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'F') goto yy84;
- if (yych != 'f') goto yy40;
-yy84:
- YYDEBUG(84, *YYCURSOR);
+ if (yych == 'F') goto yy87;
+ if (yych != 'f') goto yy44;
+yy87:
+ YYDEBUG(87, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= '\f') {
- if (yych <= 0x08) goto yy40;
- if (yych >= '\v') goto yy40;
+ if (yych <= 0x08) goto yy44;
+ if (yych >= '\v') goto yy44;
} else {
- if (yych <= '\r') goto yy85;
- if (yych != ' ') goto yy40;
+ if (yych <= '\r') goto yy88;
+ if (yych != ' ') goto yy44;
}
-yy85:
- YYDEBUG(85, *YYCURSOR);
+yy88:
+ YYDEBUG(88, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(86, *YYCURSOR);
+ YYDEBUG(89, *YYCURSOR);
if (yych <= '\f') {
- if (yych <= 0x08) goto yy87;
- if (yych <= '\n') goto yy85;
+ if (yych <= 0x08) goto yy90;
+ if (yych <= '\n') goto yy88;
} else {
- if (yych <= '\r') goto yy85;
- if (yych == ' ') goto yy85;
+ if (yych <= '\r') goto yy88;
+ if (yych == ' ') goto yy88;
}
-yy87:
- YYDEBUG(87, *YYCURSOR);
+yy90:
+ YYDEBUG(90, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 100 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 108 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
phpdbg_init_param(yylval, NUMERIC_PARAM);
yylval->num = 0;
return T_FALSY;
}
-#line 858 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy88:
- YYDEBUG(88, *YYCURSOR);
- yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'L') goto yy89;
- if (yych != 'l') goto yy40;
-yy89:
- YYDEBUG(89, *YYCURSOR);
- yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'S') goto yy90;
- if (yych != 's') goto yy40;
-yy90:
- YYDEBUG(90, *YYCURSOR);
- yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'E') goto yy84;
- if (yych == 'e') goto yy84;
- goto yy40;
+#line 919 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
yy91:
YYDEBUG(91, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'A') goto yy92;
- if (yych != 'a') goto yy40;
+ if (yych == 'L') goto yy92;
+ if (yych != 'l') goto yy44;
yy92:
YYDEBUG(92, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'B') goto yy93;
- if (yych != 'b') goto yy40;
+ if (yych == 'S') goto yy93;
+ if (yych != 's') goto yy44;
yy93:
YYDEBUG(93, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'L') goto yy94;
- if (yych != 'l') goto yy40;
+ if (yych == 'E') goto yy87;
+ if (yych == 'e') goto yy87;
+ goto yy44;
yy94:
YYDEBUG(94, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'E') goto yy95;
- if (yych != 'e') goto yy40;
+ if (yych == 'A') goto yy95;
+ if (yych != 'a') goto yy44;
yy95:
YYDEBUG(95, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'D') goto yy77;
- if (yych == 'd') goto yy77;
- goto yy40;
+ if (yych == 'B') goto yy96;
+ if (yych != 'b') goto yy44;
yy96:
YYDEBUG(96, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'S') goto yy97;
- if (yych != 's') goto yy40;
+ if (yych == 'L') goto yy97;
+ if (yych != 'l') goto yy44;
yy97:
YYDEBUG(97, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'A') goto yy98;
- if (yych != 'a') goto yy40;
+ if (yych == 'E') goto yy98;
+ if (yych != 'e') goto yy44;
yy98:
YYDEBUG(98, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'B') goto yy99;
- if (yych != 'b') goto yy40;
+ if (yych == 'D') goto yy80;
+ if (yych == 'd') goto yy80;
+ goto yy44;
yy99:
YYDEBUG(99, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'L') goto yy100;
- if (yych != 'l') goto yy40;
+ if (yych == 'S') goto yy100;
+ if (yych != 's') goto yy44;
yy100:
YYDEBUG(100, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'E') goto yy101;
- if (yych != 'e') goto yy40;
+ if (yych == 'A') goto yy101;
+ if (yych != 'a') goto yy44;
yy101:
YYDEBUG(101, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'D') goto yy84;
- if (yych == 'd') goto yy84;
- goto yy40;
+ if (yych == 'B') goto yy102;
+ if (yych != 'b') goto yy44;
yy102:
YYDEBUG(102, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yybm[0+yych] & 128) {
- goto yy103;
- }
- goto yy40;
+ if (yych == 'L') goto yy103;
+ if (yych != 'l') goto yy44;
yy103:
YYDEBUG(103, *YYCURSOR);
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == 'E') goto yy104;
+ if (yych != 'e') goto yy44;
+yy104:
+ YYDEBUG(104, *YYCURSOR);
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == 'D') goto yy87;
+ if (yych == 'd') goto yy87;
+ goto yy44;
+yy105:
+ YYDEBUG(105, *YYCURSOR);
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yybm[0+yych] & 128) {
+ goto yy106;
+ }
+ goto yy44;
+yy106:
+ YYDEBUG(106, *YYCURSOR);
yyaccept = 3;
YYMARKER = ++YYCURSOR;
YYFILL(3);
yych = *YYCURSOR;
- YYDEBUG(104, *YYCURSOR);
+ YYDEBUG(107, *YYCURSOR);
if (yybm[0+yych] & 128) {
- goto yy103;
+ goto yy106;
}
if (yych <= 0x1F) {
if (yych <= '\n') {
- if (yych <= 0x00) goto yy105;
- if (yych <= 0x08) goto yy39;
+ if (yych <= 0x00) goto yy108;
+ if (yych <= 0x08) goto yy43;
} else {
- if (yych != '\r') goto yy39;
+ if (yych != '\r') goto yy43;
}
} else {
if (yych <= '#') {
- if (yych <= ' ') goto yy105;
- if (yych <= '"') goto yy39;
+ if (yych <= ' ') goto yy108;
+ if (yych <= '"') goto yy43;
} else {
- if (yych == ':') goto yy62;
- goto yy39;
+ if (yych == ':') goto yy65;
+ goto yy43;
}
}
-yy105:
- YYDEBUG(105, *YYCURSOR);
+yy108:
+ YYDEBUG(108, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 112 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 120 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
phpdbg_init_param(yylval, ADDR_PARAM);
yylval->addr = strtoul(yytext, 0, 16);
return T_ADDR;
}
-#line 989 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy106:
- YYDEBUG(106, *YYCURSOR);
+#line 1050 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy109:
+ YYDEBUG(109, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= '\f') {
- if (yych <= 0x08) goto yy40;
- if (yych >= '\v') goto yy40;
+ if (yych <= 0x08) goto yy44;
+ if (yych >= '\v') goto yy44;
} else {
- if (yych <= '\r') goto yy107;
- if (yych != ' ') goto yy40;
+ if (yych <= '\r') goto yy110;
+ if (yych != ' ') goto yy44;
}
-yy107:
- YYDEBUG(107, *YYCURSOR);
+yy110:
+ YYDEBUG(110, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(108, *YYCURSOR);
+ YYDEBUG(111, *YYCURSOR);
if (yych <= '\f') {
- if (yych <= 0x08) goto yy109;
- if (yych <= '\n') goto yy107;
+ if (yych <= 0x08) goto yy112;
+ if (yych <= '\n') goto yy110;
} else {
- if (yych <= '\r') goto yy107;
- if (yych == ' ') goto yy107;
+ if (yych <= '\r') goto yy110;
+ if (yych == ' ') goto yy110;
}
-yy109:
- YYDEBUG(109, *YYCURSOR);
+yy112:
+ YYDEBUG(112, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 72 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 80 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
YYSETCONDITION(RAW);
phpdbg_init_param(yylval, EMPTY_PARAM);
return T_IF;
}
-#line 1023 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
+#line 1084 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy113:
+ YYDEBUG(113, *YYCURSOR);
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych <= ' ') {
+ if (yych <= '\f') {
+ if (yych <= 0x08) goto yy44;
+ if (yych >= '\v') goto yy44;
+ } else {
+ if (yych <= '\r') goto yy114;
+ if (yych <= 0x1F) goto yy44;
+ }
+ } else {
+ if (yych <= '.') {
+ if (yych <= ',') goto yy44;
+ if (yych <= '-') goto yy116;
+ goto yy117;
+ } else {
+ if (yych <= '/') goto yy44;
+ if (yych <= '9') goto yy117;
+ goto yy44;
+ }
+ }
+yy114:
+ YYDEBUG(114, *YYCURSOR);
+ ++YYCURSOR;
+ YYFILL(2);
+ yych = *YYCURSOR;
+ YYDEBUG(115, *YYCURSOR);
+ if (yych <= ' ') {
+ if (yych <= '\f') {
+ if (yych <= 0x08) goto yy66;
+ if (yych <= '\n') goto yy114;
+ goto yy66;
+ } else {
+ if (yych <= '\r') goto yy114;
+ if (yych <= 0x1F) goto yy66;
+ goto yy114;
+ }
+ } else {
+ if (yych <= '.') {
+ if (yych <= ',') goto yy66;
+ if (yych <= '-') goto yy120;
+ goto yy121;
+ } else {
+ if (yych <= '/') goto yy66;
+ if (yych <= '9') goto yy121;
+ goto yy66;
+ }
+ }
+yy116:
+ YYDEBUG(116, *YYCURSOR);
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == '.') goto yy117;
+ if (yych <= '/') goto yy44;
+ if (yych >= ':') goto yy44;
+yy117:
+ YYDEBUG(117, *YYCURSOR);
+ yyaccept = 4;
+ YYMARKER = ++YYCURSOR;
+ YYFILL(3);
+ yych = *YYCURSOR;
+ YYDEBUG(118, *YYCURSOR);
+ if (yych <= ' ') {
+ if (yych <= '\n') {
+ if (yych <= 0x00) goto yy119;
+ if (yych <= 0x08) goto yy43;
+ } else {
+ if (yych == '\r') goto yy119;
+ if (yych <= 0x1F) goto yy43;
+ }
+ } else {
+ if (yych <= '.') {
+ if (yych == '#') goto yy119;
+ if (yych <= '-') goto yy43;
+ goto yy117;
+ } else {
+ if (yych <= '/') goto yy43;
+ if (yych <= '9') goto yy117;
+ if (yych <= ':') goto yy65;
+ goto yy43;
+ }
+ }
+yy119:
+ YYDEBUG(119, *YYCURSOR);
+ yyleng = (size_t) YYCURSOR - (size_t) yytext;
+#line 73 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
+ {
+ char *text = yytext + 2;
+ while (*++text < '0');
+ yylval->num = atoi(text);
+ return T_REQ_ID;
+}
+#line 1179 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy120:
+ YYDEBUG(120, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == '.') goto yy121;
+ if (yych <= '/') goto yy66;
+ if (yych >= ':') goto yy66;
+yy121:
+ YYDEBUG(121, *YYCURSOR);
+ ++YYCURSOR;
+ YYFILL(1);
+ yych = *YYCURSOR;
+ YYDEBUG(122, *YYCURSOR);
+ if (yych == '.') goto yy121;
+ if (yych <= '/') goto yy119;
+ if (yych <= '9') goto yy121;
+ goto yy119;
}
/* *********************************** */
-yyc_RAW:
+yyc_PRE_RAW:
{
static const unsigned char yybm[] = {
- 0, 64, 64, 64, 64, 64, 64, 64,
- 64, 224, 128, 64, 64, 224, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 224, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 160, 48, 0, 0, 160, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 160, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 64, 0,
64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
};
- YYDEBUG(110, *YYCURSOR);
+ YYDEBUG(123, *YYCURSOR);
YYFILL(2);
yych = *YYCURSOR;
+ if (yybm[0+yych] & 16) {
+ goto yy127;
+ }
+ if (yych <= '\r') {
+ if (yych <= 0x08) {
+ if (yych <= 0x00) goto yy130;
+ goto yy132;
+ } else {
+ if (yych <= '\t') goto yy125;
+ if (yych <= '\f') goto yy132;
+ }
+ } else {
+ if (yych <= ' ') {
+ if (yych <= 0x1F) goto yy132;
+ } else {
+ if (yych == '-') goto yy131;
+ goto yy132;
+ }
+ }
+yy125:
+ YYDEBUG(125, *YYCURSOR);
+ ++YYCURSOR;
+ if ((yych = *YYCURSOR) <= '\f') {
+ if (yych <= 0x00) goto yy142;
+ if (yych <= 0x08) goto yy126;
+ if (yych <= '\n') goto yy142;
+ } else {
+ if (yych <= '\r') goto yy142;
+ if (yych == ' ') goto yy142;
+ }
+yy126:
+ YYDEBUG(126, *YYCURSOR);
+ yyleng = (size_t) YYCURSOR - (size_t) yytext;
+#line 169 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
+ {
+ YYSETCONDITION(RAW);
+
+ YYCURSOR = LEX(text);
+ goto restart;
+}
+#line 1277 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy127:
+ YYDEBUG(127, *YYCURSOR);
+ ++YYCURSOR;
+ YYFILL(1);
+ yych = *YYCURSOR;
+ YYDEBUG(128, *YYCURSOR);
+ if (yybm[0+yych] & 128) {
+ goto yy141;
+ }
+ if (yych <= 0x00) goto yy140;
+ if (yych == '\n') goto yy127;
+yy129:
+ YYDEBUG(129, *YYCURSOR);
+ yyleng = (size_t) YYCURSOR - (size_t) yytext;
+#line 69 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
+ {
+ return 0;
+}
+#line 1296 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy130:
+ YYDEBUG(130, *YYCURSOR);
+ yych = *++YYCURSOR;
+ goto yy126;
+yy131:
+ YYDEBUG(131, *YYCURSOR);
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == 'r') goto yy133;
+ goto yy126;
+yy132:
+ YYDEBUG(132, *YYCURSOR);
+ yych = *++YYCURSOR;
+ goto yy126;
+yy133:
+ YYDEBUG(133, *YYCURSOR);
+ ++YYCURSOR;
+ YYFILL(2);
+ yych = *YYCURSOR;
+ YYDEBUG(134, *YYCURSOR);
if (yybm[0+yych] & 32) {
- goto yy112;
+ goto yy133;
}
- if (yych <= 0x00) goto yy117;
- if (yych == '\n') goto yy115;
- goto yy118;
-yy112:
- YYDEBUG(112, *YYCURSOR);
+ if (yych <= '.') {
+ if (yych <= ',') goto yy135;
+ if (yych <= '-') goto yy136;
+ goto yy137;
+ } else {
+ if (yych <= '/') goto yy135;
+ if (yych <= '9') goto yy137;
+ }
+yy135:
+ YYDEBUG(135, *YYCURSOR);
+ YYCURSOR = YYMARKER;
+ goto yy126;
+yy136:
+ YYDEBUG(136, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yybm[0+yych] & 64) {
+ goto yy137;
+ }
+ goto yy135;
+yy137:
+ YYDEBUG(137, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(113, *YYCURSOR);
+ YYDEBUG(138, *YYCURSOR);
+ if (yybm[0+yych] & 64) {
+ goto yy137;
+ }
+ YYDEBUG(139, *YYCURSOR);
+ yyleng = (size_t) YYCURSOR - (size_t) yytext;
+#line 73 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
+ {
+ char *text = yytext + 2;
+ while (*++text < '0');
+ yylval->num = atoi(text);
+ return T_REQ_ID;
+}
+#line 1357 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy140:
+ YYDEBUG(140, *YYCURSOR);
+ yych = *++YYCURSOR;
+ goto yy129;
+yy141:
+ YYDEBUG(141, *YYCURSOR);
+ ++YYCURSOR;
+ YYFILL(1);
+ yych = *YYCURSOR;
+yy142:
+ YYDEBUG(142, *YYCURSOR);
+ if (yybm[0+yych] & 128) {
+ goto yy141;
+ }
+ if (yych <= 0x00) goto yy140;
+ if (yych == '\n') goto yy127;
+ YYDEBUG(143, *YYCURSOR);
+ yyleng = (size_t) YYCURSOR - (size_t) yytext;
+#line 147 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
+ {
+ /* ignore whitespace */
+
+ goto restart;
+}
+#line 1382 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+ }
+/* *********************************** */
+yyc_RAW:
+ {
+ static const unsigned char yybm[] = {
+ 0, 128, 128, 128, 128, 128, 128, 128,
+ 128, 160, 64, 128, 128, 160, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 160, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ };
+ YYDEBUG(144, *YYCURSOR);
+ YYFILL(1);
+ yych = *YYCURSOR;
if (yybm[0+yych] & 32) {
- goto yy112;
+ goto yy146;
}
- if (yych <= 0x00) goto yy114;
- if (yych == '\n') goto yy120;
- goto yy118;
-yy114:
- YYDEBUG(114, *YYCURSOR);
+ if (yych <= 0x00) goto yy152;
+ if (yych == '\n') goto yy149;
+ goto yy153;
+yy146:
+ YYDEBUG(146, *YYCURSOR);
+ ++YYCURSOR;
+ YYFILL(1);
+ yych = *YYCURSOR;
+ YYDEBUG(147, *YYCURSOR);
+ if (yybm[0+yych] & 32) {
+ goto yy146;
+ }
+ if (yych <= 0x00) goto yy152;
+ if (yych == '\n') goto yy149;
+ goto yy153;
+yy148:
+ YYDEBUG(148, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 132 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 140 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
phpdbg_init_param(yylval, STR_PARAM);
yylval->str = zend_strndup(yytext, yyleng);
yylval->len = yyleng;
return T_INPUT;
}
-#line 1093 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy115:
- YYDEBUG(115, *YYCURSOR);
+#line 1452 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy149:
+ YYDEBUG(149, *YYCURSOR);
++YYCURSOR;
- if (yybm[0+(yych = *YYCURSOR)] & 128) {
- goto yy120;
+ YYFILL(1);
+ yych = *YYCURSOR;
+ YYDEBUG(150, *YYCURSOR);
+ if (yybm[0+yych] & 64) {
+ goto yy149;
}
-yy116:
- YYDEBUG(116, *YYCURSOR);
+ if (yych <= '\f') {
+ if (yych <= 0x00) goto yy152;
+ if (yych == '\t') goto yy155;
+ } else {
+ if (yych <= '\r') goto yy155;
+ if (yych == ' ') goto yy155;
+ }
+yy151:
+ YYDEBUG(151, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 68 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 69 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
return 0;
}
-#line 1107 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
-yy117:
- YYDEBUG(117, *YYCURSOR);
+#line 1476 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
+yy152:
+ YYDEBUG(152, *YYCURSOR);
yych = *++YYCURSOR;
- goto yy116;
-yy118:
- YYDEBUG(118, *YYCURSOR);
+ goto yy151;
+yy153:
+ YYDEBUG(153, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(119, *YYCURSOR);
- if (yybm[0+yych] & 64) {
- goto yy118;
+ YYDEBUG(154, *YYCURSOR);
+ if (yybm[0+yych] & 128) {
+ goto yy153;
}
- goto yy114;
-yy120:
- YYDEBUG(120, *YYCURSOR);
+ goto yy148;
+yy155:
+ YYDEBUG(155, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(121, *YYCURSOR);
- if (yybm[0+yych] & 128) {
- goto yy120;
+ YYDEBUG(156, *YYCURSOR);
+ if (yybm[0+yych] & 64) {
+ goto yy149;
}
- YYDEBUG(122, *YYCURSOR);
+ if (yych <= '\f') {
+ if (yych <= 0x00) goto yy152;
+ if (yych == '\t') goto yy155;
+ } else {
+ if (yych <= '\r') goto yy155;
+ if (yych == ' ') goto yy155;
+ }
+ YYDEBUG(157, *YYCURSOR);
yyleng = (size_t) YYCURSOR - (size_t) yytext;
-#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 147 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
{
/* ignore whitespace */
goto restart;
}
-#line 1139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c"
+#line 1515 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c"
}
}
-#line 168 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l"
+#line 183 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l"
}
diff --git a/sapi/phpdbg/phpdbg_lexer.h b/sapi/phpdbg/phpdbg_lexer.h
index d0e259f453..ab51e7daa8 100644
--- a/sapi/phpdbg/phpdbg_lexer.h
+++ b/sapi/phpdbg/phpdbg_lexer.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
diff --git a/sapi/phpdbg/phpdbg_lexer.l b/sapi/phpdbg/phpdbg_lexer.l
index 7b3ce38c47..0c27fc22ac 100644
--- a/sapi/phpdbg/phpdbg_lexer.l
+++ b/sapi/phpdbg/phpdbg_lexer.l
@@ -21,8 +21,9 @@
#define YYFILL(n)
#define NORMAL 0
-#define RAW 1
-#define INITIAL 2
+#define PRE_RAW 1
+#define RAW 2
+#define INITIAL 3
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
@@ -65,10 +66,17 @@ INPUT [^\n\000]+
<!*> := yyleng = (size_t) YYCURSOR - (size_t) yytext;
-<*>[\n\000] {
+<*>{WS}?[\n\000] {
return 0;
}
+<PRE_RAW, NORMAL>[-][r]{WS}?{DIGITS} {
+ char *text = yytext + 2;
+ while (*++text < '0');
+ yylval->num = atoi(text);
+ return T_REQ_ID;
+}
+
<NORMAL>{T_IF}{WS} {
YYSETCONDITION(RAW);
phpdbg_init_param(yylval, EMPTY_PARAM);
@@ -143,21 +151,28 @@ INPUT [^\n\000]+
}
<INITIAL>{T_EVAL}{WS} {
- YYSETCONDITION(RAW);
+ YYSETCONDITION(PRE_RAW);
phpdbg_init_param(yylval, EMPTY_PARAM);
return T_EVAL;
}
<INITIAL>{T_SHELL}{WS} {
- YYSETCONDITION(RAW);
+ YYSETCONDITION(PRE_RAW);
phpdbg_init_param(yylval, EMPTY_PARAM);
return T_SHELL;
}
<INITIAL>({T_RUN}|{T_RUN_SHORT}){WS} {
- YYSETCONDITION(RAW);
+ YYSETCONDITION(PRE_RAW);
phpdbg_init_param(yylval, EMPTY_PARAM);
return T_RUN;
}
+<PRE_RAW>. {
+ YYSETCONDITION(RAW);
+
+ YYCURSOR = LEX(text);
+ goto restart;
+}
+
<INITIAL>. {
YYSETCONDITION(NORMAL);
diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c
index eac17ba6a7..de03a3651e 100644
--- a/sapi/phpdbg/phpdbg_list.c
+++ b/sapi/phpdbg/phpdbg_list.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -34,35 +34,37 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-#define PHPDBG_LIST_COMMAND_D(f, h, a, m, l, s) \
- PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[13])
+#define PHPDBG_LIST_COMMAND_D(f, h, a, m, l, s, flags) \
+ PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[13], flags)
const phpdbg_command_t phpdbg_list_commands[] = {
- PHPDBG_LIST_COMMAND_D(lines, "lists the specified lines", 'l', list_lines, NULL, "l"),
- PHPDBG_LIST_COMMAND_D(class, "lists the specified class", 'c', list_class, NULL, "s"),
- PHPDBG_LIST_COMMAND_D(method, "lists the specified method", 'm', list_method, NULL, "m"),
- PHPDBG_LIST_COMMAND_D(func, "lists the specified function", 'f', list_func, NULL, "s"),
+ PHPDBG_LIST_COMMAND_D(lines, "lists the specified lines", 'l', list_lines, NULL, "l", PHPDBG_ASYNC_SAFE),
+ PHPDBG_LIST_COMMAND_D(class, "lists the specified class", 'c', list_class, NULL, "s", PHPDBG_ASYNC_SAFE),
+ PHPDBG_LIST_COMMAND_D(method, "lists the specified method", 'm', list_method, NULL, "m", PHPDBG_ASYNC_SAFE),
+ PHPDBG_LIST_COMMAND_D(func, "lists the specified function", 'f', list_func, NULL, "s", PHPDBG_ASYNC_SAFE),
PHPDBG_END_COMMAND
};
PHPDBG_LIST(lines) /* {{{ */
{
if (!PHPDBG_G(exec) && !zend_is_executing(TSRMLS_C)) {
- phpdbg_error("Not executing, and execution context not set");
+ phpdbg_error("inactive", "type=\"execution\"", "Not executing, and execution context not set");
return SUCCESS;
}
switch (param->type) {
- case NUMERIC_PARAM:
- phpdbg_list_file(phpdbg_current_file(TSRMLS_C),
- (param->num < 0 ? 1 - param->num : param->num),
- (param->num < 0 ? param->num : 0) + zend_get_executed_lineno(TSRMLS_C),
- 0 TSRMLS_CC);
- break;
-
- case FILE_PARAM:
- phpdbg_list_file(param->file.name, param->file.line, 0, 0 TSRMLS_CC);
- break;
+ case NUMERIC_PARAM: {
+ const char *char_file = phpdbg_current_file(TSRMLS_C);
+ zend_string *file = zend_string_init(char_file, strlen(char_file), 0);
+ phpdbg_list_file(file, param->num < 0 ? 1 - param->num : param->num, (param->num < 0 ? param->num : 0) + zend_get_executed_lineno(TSRMLS_C), 0 TSRMLS_CC);
+ efree(file);
+ } break;
+
+ case FILE_PARAM: {
+ zend_string *file = zend_string_init(param->file.name, strlen(param->file.name), 0);
+ phpdbg_list_file(file, param->file.line, 0, 0 TSRMLS_CC);
+ efree(file);
+ } break;
phpdbg_default_switch_case();
}
@@ -79,21 +81,21 @@ PHPDBG_LIST(func) /* {{{ */
PHPDBG_LIST(method) /* {{{ */
{
- zend_class_entry **ce;
+ zend_class_entry *ce;
- if (zend_lookup_class(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) {
+ if (phpdbg_safe_class_lookup(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) {
zend_function *function;
char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name));
- if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**) &function) == SUCCESS) {
+ if ((function = zend_hash_str_find_ptr(&ce->function_table, lcname, strlen(lcname)))) {
phpdbg_list_function(function TSRMLS_CC);
} else {
- phpdbg_error("Could not find %s::%s", param->method.class, param->method.name);
+ phpdbg_error("list", "type=\"notfound\" method=\"%s::%s\"", "Could not find %s::%s", param->method.class, param->method.name);
}
efree(lcname);
} else {
- phpdbg_error("Could not find the class %s", param->method.class);
+ phpdbg_error("list", "type=\"notfound\" class=\"%s\"", "Could not find the class %s", param->method.class);
}
return SUCCESS;
@@ -101,82 +103,69 @@ PHPDBG_LIST(method) /* {{{ */
PHPDBG_LIST(class) /* {{{ */
{
- zend_class_entry **ce;
-
- if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) {
- if ((*ce)->type == ZEND_USER_CLASS) {
- if ((*ce)->info.user.filename) {
- phpdbg_list_file(
- (*ce)->info.user.filename,
- (*ce)->info.user.line_end - (*ce)->info.user.line_start + 1,
- (*ce)->info.user.line_start, 0 TSRMLS_CC
- );
+ zend_class_entry *ce;
+
+ if (phpdbg_safe_class_lookup(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) {
+ if (ce->type == ZEND_USER_CLASS) {
+ if (ce->info.user.filename) {
+ phpdbg_list_file(ce->info.user.filename, ce->info.user.line_end - ce->info.user.line_start + 1, ce->info.user.line_start, 0 TSRMLS_CC);
} else {
- phpdbg_error("The source of the requested class (%s) cannot be found", (*ce)->name);
+ phpdbg_error("list", "type=\"nosource\" class=\"%s\"", "The source of the requested class (%s) cannot be found", ce->name);
}
} else {
- phpdbg_error("The class requested (%s) is not user defined", (*ce)->name);
+ phpdbg_error("list", "type=\"internalclass\" class=\"%s\"", "The class requested (%s) is not user defined", ce->name);
}
} else {
- phpdbg_error("The requested class (%s) could not be found", param->str);
+ phpdbg_error("list", "type=\"notfound\" class=\"%s\"", "The requested class (%s) could not be found", param->str);
}
return SUCCESS;
} /* }}} */
-void phpdbg_list_file(const char *filename, long count, long offset, int highlight TSRMLS_DC) /* {{{ */
+void phpdbg_list_file(zend_string *filename, uint count, int offset, uint highlight TSRMLS_DC) /* {{{ */
{
- struct stat st;
- char *opened = NULL;
- char buffer[8096] = {0,};
- long line = 0;
-
- php_stream *stream = NULL;
-
- if (VCWD_STAT(filename, &st) == FAILURE) {
- phpdbg_error("Failed to stat file %s", filename);
- return;
- }
+ uint line, lastline;
+ phpdbg_file_source *data;
- stream = php_stream_open_wrapper(filename, "rb", USE_PATH, &opened);
-
- if (!stream) {
- phpdbg_error("Failed to open file %s to list", filename);
+ if (!(data = zend_hash_find_ptr(&PHPDBG_G(file_sources), filename))) {
+ phpdbg_error("list", "type=\"unknownfile\"", "Could not find information about included file...");
return;
}
-
+
if (offset < 0) {
count += offset;
offset = 0;
}
-
- while (php_stream_gets(stream, buffer, sizeof(buffer)) != NULL) {
- long linelen = strlen(buffer);
-
- ++line;
-
- if (offset <= line) {
- if (!highlight) {
- phpdbg_write("%05ld: %s", line, buffer);
- } else {
- if (highlight != line) {
- phpdbg_write(" %05ld: %s", line, buffer);
- } else {
- phpdbg_write(">%05ld: %s", line, buffer);
- }
- }
- if (buffer[linelen - 1] != '\n') {
- phpdbg_write("\n");
+ lastline = offset + count;
+
+ if (lastline > data->lines) {
+ lastline = data->lines;
+ }
+
+ phpdbg_xml("<list %r file=\"%s\">", filename);
+
+ for (line = offset; line < lastline;) {
+ uint linestart = data->line[line++];
+ uint linelen = data->line[line] - linestart;
+ char *buffer = data->buf + linestart;
+
+ if (!highlight) {
+ phpdbg_write("line", "line=\"%u\" code=\"%.*s\"", " %05u: %.*s", line, linelen, buffer);
+ } else {
+ if (highlight != line) {
+ phpdbg_write("line", "line=\"%u\" code=\"%.*s\"", " %05u: %.*s", line, linelen, buffer);
+ } else {
+ phpdbg_write("line", "line=\"%u\" code=\"%.*s\" current=\"current\"", ">%05u: %.*s", line, linelen, buffer);
}
}
- if (count > 0 && count + offset - 1 < line) {
- break;
+ if (*(buffer + linelen - 1) != '\n' || !linelen) {
+ phpdbg_out("\n");
}
}
-
- php_stream_close(stream);
+
+ phpdbg_xml("</list>");
} /* }}} */
void phpdbg_list_function(const zend_function *fbc TSRMLS_DC) /* {{{ */
@@ -184,14 +173,13 @@ void phpdbg_list_function(const zend_function *fbc TSRMLS_DC) /* {{{ */
const zend_op_array *ops;
if (fbc->type != ZEND_USER_FUNCTION) {
- phpdbg_error("The function requested (%s) is not user defined", fbc->common.function_name);
+ phpdbg_error("list", "type=\"internalfunction\" function=\"%s\"", "The function requested (%s) is not user defined", fbc->common.function_name);
return;
}
- ops = (zend_op_array*)fbc;
+ ops = (zend_op_array *) fbc;
- phpdbg_list_file(ops->filename,
- ops->line_end - ops->line_start + 1, ops->line_start, 0 TSRMLS_CC);
+ phpdbg_list_file(ops->filename, ops->line_end - ops->line_start + 1, ops->line_start, 0 TSRMLS_CC);
} /* }}} */
void phpdbg_list_function_byname(const char *str, size_t len TSRMLS_DC) /* {{{ */
@@ -209,11 +197,11 @@ void phpdbg_list_function_byname(const char *str, size_t len TSRMLS_DC) /* {{{ *
func_table = &EG(scope)->function_table;
} else {
- phpdbg_error("No active class");
+ phpdbg_error("inactive", "type=\"noclasses\"", "No active class");
return;
}
} else if (!EG(function_table)) {
- phpdbg_error("No function table loaded");
+ phpdbg_error("inactive", "type=\"function_table\"", "No function table loaded");
return;
} else {
func_table = EG(function_table);
@@ -222,12 +210,87 @@ void phpdbg_list_function_byname(const char *str, size_t len TSRMLS_DC) /* {{{ *
/* use lowercase names, case insensitive */
func_name = zend_str_tolower_dup(func_name, func_name_len);
- if (zend_hash_find(func_table, func_name, func_name_len+1, (void**)&fbc) == SUCCESS) {
- phpdbg_list_function(fbc TSRMLS_CC);
- } else {
- phpdbg_error("Function %s not found", func_name);
- }
+ phpdbg_try_access {
+ if ((fbc = zend_hash_str_find_ptr(func_table, func_name, func_name_len))) {
+ phpdbg_list_function(fbc TSRMLS_CC);
+ } else {
+ phpdbg_error("list", "type=\"nofunction\" function=\"%s\"", "Function %s not found", func_name);
+ }
+ } phpdbg_catch_access {
+ phpdbg_error("signalsegv", "function=\"%s\"", "Could not list function %s, invalid data source", func_name);
+ } phpdbg_end_try_access();
efree(func_name);
} /* }}} */
+zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type TSRMLS_DC) {
+ phpdbg_file_source data, *dataptr;
+ zend_file_handle fake = {{0}};
+ zend_op_array *ret;
+ char *filename = (char *)(file->opened_path ? file->opened_path : file->filename);
+ uint line;
+ char *bufptr, *endptr;
+
+ zend_stream_fixup(file, &data.buf, &data.len TSRMLS_CC);
+
+ data.filename = filename;
+ data.line[0] = 0;
+
+ if (file->handle.stream.mmap.old_closer) {
+ /* do not unmap */
+ file->handle.stream.closer = file->handle.stream.mmap.old_closer;
+ }
+
+#if HAVE_MMAP
+ if (file->handle.stream.mmap.map) {
+ data.map = file->handle.stream.mmap.map;
+ }
+#endif
+
+ fake.type = ZEND_HANDLE_MAPPED;
+ fake.handle.stream.mmap.buf = data.buf;
+ fake.handle.stream.mmap.len = data.len;
+ fake.free_filename = 0;
+ fake.opened_path = file->opened_path;
+ fake.filename = filename;
+ fake.opened_path = file->opened_path;
+
+ *(dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint) * data.len)) = data;
+
+ for (line = 0, bufptr = data.buf - 1, endptr = data.buf + data.len; ++bufptr < endptr;) {
+ if (*bufptr == '\n') {
+ dataptr->line[++line] = (uint)(bufptr - data.buf) + 1;
+ }
+ }
+ dataptr->lines = ++line;
+ dataptr->line[line] = endptr - data.buf;
+ dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line);
+
+ zend_hash_str_add_ptr(&PHPDBG_G(file_sources), filename, strlen(filename), dataptr);
+
+ ret = PHPDBG_G(compile_file)(&fake, type TSRMLS_CC);
+
+ fake.opened_path = NULL;
+ zend_file_handle_dtor(&fake TSRMLS_CC);
+
+ return ret;
+}
+
+void phpdbg_free_file_source(phpdbg_file_source *data) {
+#if HAVE_MMAP
+ if (data->map) {
+ munmap(data->map, data->len + ZEND_MMAP_AHEAD);
+ } else
+#endif
+ if (data->buf) {
+ efree(data->buf);
+ }
+
+ efree(data);
+}
+
+void phpdbg_init_list(TSRMLS_D) {
+ PHPDBG_G(compile_file) = zend_compile_file;
+ zend_hash_init(&PHPDBG_G(file_sources), 1, NULL, (dtor_func_t) phpdbg_free_file_source, 0);
+ zend_compile_file = phpdbg_compile_file;
+}
diff --git a/sapi/phpdbg/phpdbg_list.h b/sapi/phpdbg/phpdbg_list.h
index 84f6b63195..43a2d474d5 100644
--- a/sapi/phpdbg/phpdbg_list.h
+++ b/sapi/phpdbg/phpdbg_list.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -33,9 +33,22 @@ PHPDBG_LIST(method);
PHPDBG_LIST(func);
void phpdbg_list_function_byname(const char *, size_t TSRMLS_DC);
-void phpdbg_list_function(const zend_function* TSRMLS_DC);
-void phpdbg_list_file(const char*, long, long, int TSRMLS_DC);
+void phpdbg_list_function(const zend_function * TSRMLS_DC);
+void phpdbg_list_file(zend_string *, uint, int, uint TSRMLS_DC);
extern const phpdbg_command_t phpdbg_list_commands[];
+void phpdbg_init_list(TSRMLS_D);
+
+typedef struct {
+ char *filename;
+ char *buf;
+ size_t len;
+#if HAVE_MMAP
+ void *map;
+#endif
+ uint lines;
+ uint line[1];
+} phpdbg_file_source;
+
#endif /* PHPDBG_LIST_H */
diff --git a/sapi/phpdbg/phpdbg_opcode.c b/sapi/phpdbg/phpdbg_opcode.c
index f33b1378bf..99f43344a4 100644
--- a/sapi/phpdbg/phpdbg_opcode.c
+++ b/sapi/phpdbg/phpdbg_opcode.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -26,7 +26,7 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-static inline uint32_t phpdbg_decode_literal(zend_op_array *ops, zend_literal *literal TSRMLS_DC) /* {{{ */
+static inline uint32_t phpdbg_decode_literal(zend_op_array *ops, zval *literal TSRMLS_DC) /* {{{ */
{
int iter = 0;
@@ -46,26 +46,25 @@ static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, uint32_t
switch (type &~ EXT_TYPE_UNUSED) {
case IS_CV:
- asprintf(&decode, "$%s", ops->vars[op->var].name);
+ asprintf(&decode, "$%s", ops->vars[EX_VAR_TO_NUM(op->var)]->val);
break;
case IS_VAR:
case IS_TMP_VAR: {
zend_ulong id = 0, *pid = NULL;
if (vars != NULL) {
- if (zend_hash_index_find(vars, (zend_ulong) ops->vars - op->var, (void**) &pid) != SUCCESS) {
+ if ((pid = zend_hash_index_find_ptr(vars, (zend_ulong) ops->vars - op->var))) {
+ id = *pid;
+ } else {
id = zend_hash_num_elements(vars);
- zend_hash_index_update(
- vars, (zend_ulong) ops->vars - op->var,
- (void**) &id,
- sizeof(zend_ulong), NULL);
- } else id = *pid;
+ zend_hash_index_update_mem(vars, (zend_ulong) ops->vars - op->var, &id, sizeof(zend_ulong));
+ }
}
- asprintf(&decode, "@%lu", id);
+ asprintf(&decode, "@%llu", id);
} break;
case IS_CONST:
- asprintf(&decode, "C%u", phpdbg_decode_literal(ops, op->literal TSRMLS_CC));
+ asprintf(&decode, "C%u", phpdbg_decode_literal(ops, op->zv TSRMLS_CC));
break;
case IS_UNUSED:
@@ -92,8 +91,7 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op, HashTable *vars TSRM
case ZEND_JMPZNZ:
decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars TSRMLS_CC);
- asprintf(
- &decode[2], "J%u or J%lu", op->op2.opline_num, op->extended_value);
+ asprintf(&decode[2], "J%u or J%llu", op->op2.opline_num, op->extended_value);
goto result;
case ZEND_JMPZ:
@@ -105,8 +103,7 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op, HashTable *vars TSRM
case ZEND_JMP_SET:
#endif
decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars TSRMLS_CC);
- asprintf(
- &decode[2], "J%ld", op->op2.jmp_addr - ops->opcodes);
+ asprintf(&decode[2], "J%ld", op->op2.jmp_addr - ops->opcodes);
goto result;
case ZEND_RECV_INIT:
@@ -118,8 +115,7 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op, HashTable *vars TSRM
result:
decode[3] = phpdbg_decode_op(ops, &op->result, op->result_type, vars TSRMLS_CC);
format:
- asprintf(
- &decode[0],
+ asprintf(&decode[0],
"%-20s %-20s %-20s",
decode[1] ? decode[1] : "",
decode[2] ? decode[2] : "",
@@ -145,26 +141,26 @@ void phpdbg_print_opline_ex(zend_execute_data *execute_data, HashTable *vars, ze
(PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ||
(PHPDBG_G(oplog)))) {
- zend_op *opline = execute_data->opline;
- char *decode = phpdbg_decode_opline(execute_data->op_array, opline, vars TSRMLS_CC);
+ zend_op *opline = (zend_op *) execute_data->opline;
+ char *decode = phpdbg_decode_opline(&execute_data->func->op_array, opline, vars TSRMLS_CC);
if (ignore_flags || (!(PHPDBG_G(flags) & PHPDBG_IS_QUIET) || (PHPDBG_G(flags) & PHPDBG_IS_STEPPING))) {
/* output line info */
- phpdbg_notice("L%-5u %16p %-30s %s %s",
+ phpdbg_notice("opline", "line=\"%u\" opline=\"%p\" opcode=\"%s\" op=\"%s\" file=\"%s\"", "L%-5u %16p %-30s %s %s",
opline->lineno,
opline,
phpdbg_decode_opcode(opline->opcode),
decode,
- execute_data->op_array->filename ? execute_data->op_array->filename : "unknown");
+ execute_data->func->op_array.filename ? execute_data->func->op_array.filename->val : "unknown");
}
if (!ignore_flags && PHPDBG_G(oplog)) {
- phpdbg_log_ex(PHPDBG_G(oplog), "L%-5u %16p %-30s %s %s",
+ phpdbg_log_ex(fileno(PHPDBG_G(oplog)), "L%-5u %16p %-30s %s %s",
opline->lineno,
opline,
phpdbg_decode_opcode(opline->opcode),
decode,
- execute_data->op_array->filename ? execute_data->op_array->filename : "unknown");
+ execute_data->func->op_array.filename ? execute_data->func->op_array.filename->val : "unknown");
}
if (decode) {
@@ -180,179 +176,6 @@ void phpdbg_print_opline(zend_execute_data *execute_data, zend_bool ignore_flags
const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */
{
-#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO
-#define CASE(s) case s: return #s
- switch (opcode) {
- CASE(ZEND_NOP);
- CASE(ZEND_ADD);
- CASE(ZEND_SUB);
- CASE(ZEND_MUL);
- CASE(ZEND_DIV);
- CASE(ZEND_MOD);
- CASE(ZEND_SL);
- CASE(ZEND_SR);
- CASE(ZEND_CONCAT);
- CASE(ZEND_BW_OR);
- CASE(ZEND_BW_AND);
- CASE(ZEND_BW_XOR);
- CASE(ZEND_BW_NOT);
- CASE(ZEND_BOOL_NOT);
- CASE(ZEND_BOOL_XOR);
- CASE(ZEND_IS_IDENTICAL);
- CASE(ZEND_IS_NOT_IDENTICAL);
- CASE(ZEND_IS_EQUAL);
- CASE(ZEND_IS_NOT_EQUAL);
- CASE(ZEND_IS_SMALLER);
- CASE(ZEND_IS_SMALLER_OR_EQUAL);
- CASE(ZEND_CAST);
- CASE(ZEND_QM_ASSIGN);
- CASE(ZEND_ASSIGN_ADD);
- CASE(ZEND_ASSIGN_SUB);
- CASE(ZEND_ASSIGN_MUL);
- CASE(ZEND_ASSIGN_DIV);
- CASE(ZEND_ASSIGN_MOD);
- CASE(ZEND_ASSIGN_SL);
- CASE(ZEND_ASSIGN_SR);
- CASE(ZEND_ASSIGN_CONCAT);
- CASE(ZEND_ASSIGN_BW_OR);
- CASE(ZEND_ASSIGN_BW_AND);
- CASE(ZEND_ASSIGN_BW_XOR);
- CASE(ZEND_PRE_INC);
- CASE(ZEND_PRE_DEC);
- CASE(ZEND_POST_INC);
- CASE(ZEND_POST_DEC);
- CASE(ZEND_ASSIGN);
- CASE(ZEND_ASSIGN_REF);
- CASE(ZEND_ECHO);
- CASE(ZEND_PRINT);
- CASE(ZEND_JMP);
- CASE(ZEND_JMPZ);
- CASE(ZEND_JMPNZ);
- CASE(ZEND_JMPZNZ);
- CASE(ZEND_JMPZ_EX);
- CASE(ZEND_JMPNZ_EX);
- CASE(ZEND_CASE);
- CASE(ZEND_BRK);
- CASE(ZEND_CONT);
- CASE(ZEND_BOOL);
- CASE(ZEND_INIT_STRING);
- CASE(ZEND_ADD_CHAR);
- CASE(ZEND_ADD_STRING);
- CASE(ZEND_ADD_VAR);
- CASE(ZEND_BEGIN_SILENCE);
- CASE(ZEND_END_SILENCE);
- CASE(ZEND_INIT_FCALL_BY_NAME);
- CASE(ZEND_DO_FCALL);
- CASE(ZEND_DO_FCALL_BY_NAME);
- CASE(ZEND_RETURN);
- CASE(ZEND_RECV);
- CASE(ZEND_RECV_INIT);
- CASE(ZEND_SEND_VAL);
- CASE(ZEND_SEND_VAR);
- CASE(ZEND_SEND_REF);
- CASE(ZEND_NEW);
- CASE(ZEND_INIT_NS_FCALL_BY_NAME);
- CASE(ZEND_FREE);
- CASE(ZEND_INIT_ARRAY);
- CASE(ZEND_ADD_ARRAY_ELEMENT);
- CASE(ZEND_INCLUDE_OR_EVAL);
- CASE(ZEND_UNSET_VAR);
- CASE(ZEND_UNSET_DIM);
- CASE(ZEND_UNSET_OBJ);
- CASE(ZEND_FE_RESET);
- CASE(ZEND_FE_FETCH);
- CASE(ZEND_EXIT);
- CASE(ZEND_FETCH_R);
- CASE(ZEND_FETCH_DIM_R);
- CASE(ZEND_FETCH_OBJ_R);
- CASE(ZEND_FETCH_W);
- CASE(ZEND_FETCH_DIM_W);
- CASE(ZEND_FETCH_OBJ_W);
- CASE(ZEND_FETCH_RW);
- CASE(ZEND_FETCH_DIM_RW);
- CASE(ZEND_FETCH_OBJ_RW);
- CASE(ZEND_FETCH_IS);
- CASE(ZEND_FETCH_DIM_IS);
- CASE(ZEND_FETCH_OBJ_IS);
- CASE(ZEND_FETCH_FUNC_ARG);
- CASE(ZEND_FETCH_DIM_FUNC_ARG);
- CASE(ZEND_FETCH_OBJ_FUNC_ARG);
- CASE(ZEND_FETCH_UNSET);
- CASE(ZEND_FETCH_DIM_UNSET);
- CASE(ZEND_FETCH_OBJ_UNSET);
- CASE(ZEND_FETCH_LIST);
- CASE(ZEND_FETCH_CONSTANT);
- CASE(ZEND_GOTO);
- CASE(ZEND_EXT_STMT);
- CASE(ZEND_EXT_FCALL_BEGIN);
- CASE(ZEND_EXT_FCALL_END);
- CASE(ZEND_EXT_NOP);
- CASE(ZEND_TICKS);
- CASE(ZEND_SEND_VAR_NO_REF);
- CASE(ZEND_CATCH);
- CASE(ZEND_THROW);
- CASE(ZEND_FETCH_CLASS);
- CASE(ZEND_CLONE);
- CASE(ZEND_RETURN_BY_REF);
- CASE(ZEND_INIT_METHOD_CALL);
- CASE(ZEND_INIT_STATIC_METHOD_CALL);
- CASE(ZEND_ISSET_ISEMPTY_VAR);
- CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ);
- CASE(ZEND_PRE_INC_OBJ);
- CASE(ZEND_PRE_DEC_OBJ);
- CASE(ZEND_POST_INC_OBJ);
- CASE(ZEND_POST_DEC_OBJ);
- CASE(ZEND_ASSIGN_OBJ);
- CASE(ZEND_INSTANCEOF);
- CASE(ZEND_DECLARE_CLASS);
- CASE(ZEND_DECLARE_INHERITED_CLASS);
- CASE(ZEND_DECLARE_FUNCTION);
- CASE(ZEND_RAISE_ABSTRACT_ERROR);
- CASE(ZEND_DECLARE_CONST);
- CASE(ZEND_ADD_INTERFACE);
- CASE(ZEND_DECLARE_INHERITED_CLASS_DELAYED);
- CASE(ZEND_VERIFY_ABSTRACT_CLASS);
- CASE(ZEND_ASSIGN_DIM);
- CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ);
- CASE(ZEND_HANDLE_EXCEPTION);
- CASE(ZEND_USER_OPCODE);
-#ifdef ZEND_JMP_SET
- CASE(ZEND_JMP_SET);
-#endif
- CASE(ZEND_DECLARE_LAMBDA_FUNCTION);
-#ifdef ZEND_ADD_TRAIT
- CASE(ZEND_ADD_TRAIT);
-#endif
-#ifdef ZEND_BIND_TRAITS
- CASE(ZEND_BIND_TRAITS);
-#endif
-#ifdef ZEND_SEPARATE
- CASE(ZEND_SEPARATE);
-#endif
-#ifdef ZEND_DISCARD_EXCEPTION
- CASE(ZEND_DISCARD_EXCEPTION);
-#endif
-#ifdef ZEND_YIELD
- CASE(ZEND_YIELD);
-#endif
-#ifdef ZEND_GENERATOR_RETURN
- CASE(ZEND_GENERATOR_RETURN);
-#endif
-#ifdef ZEND_FAST_CALL
- CASE(ZEND_FAST_CALL);
-#endif
-#ifdef ZEND_FAST_RET
- CASE(ZEND_FAST_RET);
-#endif
-#ifdef ZEND_RECV_VARIADIC
- CASE(ZEND_RECV_VARIADIC);
-#endif
- CASE(ZEND_OP_DATA);
- default:
- return "UNKNOWN";
- }
-#else
const char *ret = zend_get_opcode_name(opcode);
return ret?ret:"UNKNOWN";
-#endif
} /* }}} */
diff --git a/sapi/phpdbg/phpdbg_opcode.h b/sapi/phpdbg/phpdbg_opcode.h
index 647237119c..144442981d 100644
--- a/sapi/phpdbg/phpdbg_opcode.h
+++ b/sapi/phpdbg/phpdbg_opcode.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
diff --git a/sapi/phpdbg/phpdbg_out.c b/sapi/phpdbg/phpdbg_out.c
new file mode 100644
index 0000000000..4d70381533
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_out.c
@@ -0,0 +1,1306 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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 "zend.h"
+#include "php.h"
+#include "spprintf.h"
+#include "phpdbg.h"
+#include "phpdbg_io.h"
+#include "phpdbg_eol.h"
+#include "ext/standard/html.h"
+
+#ifdef _WIN32
+# include "win32/time.h"
+#endif
+
+ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+
+/* copied from php-src/main/snprintf.c and slightly modified */
+/*
+ * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
+ *
+ * XXX: this is a magic number; do not decrease it
+ * Emax = 1023
+ * NDIG = 320
+ * NUM_BUF_SIZE >= strlen("-") + Emax + strlrn(".") + NDIG + strlen("E+1023") + 1;
+ */
+#define NUM_BUF_SIZE 2048
+
+/*
+ * Descriptor for buffer area
+ */
+struct buf_area {
+ char *buf_end;
+ char *nextb; /* pointer to next byte to read/write */
+};
+
+typedef struct buf_area buffy;
+
+/*
+ * The INS_CHAR macro inserts a character in the buffer and writes
+ * the buffer back to disk if necessary
+ * It uses the char pointers sp and bep:
+ * sp points to the next available character in the buffer
+ * bep points to the end-of-buffer+1
+ * While using this macro, note that the nextb pointer is NOT updated.
+ *
+ * NOTE: Evaluation of the c argument should not have any side-effects
+ */
+#define INS_CHAR(c, sp, bep, cc) \
+ { \
+ if (sp < bep) \
+ { \
+ *sp++ = c; \
+ } \
+ cc++; \
+ }
+
+#define NUM( c ) ( c - '0' )
+
+#define STR_TO_DEC( str, num ) \
+ num = NUM( *str++ ) ; \
+ while ( isdigit((int)*str ) ) \
+ { \
+ num *= 10 ; \
+ num += NUM( *str++ ) ; \
+ }
+
+/*
+ * This macro does zero padding so that the precision
+ * requirement is satisfied. The padding is done by
+ * adding '0's to the left of the string that is going
+ * to be printed.
+ */
+#define FIX_PRECISION( adjust, precision, s, s_len ) \
+ if ( adjust ) \
+ while ( s_len < precision ) \
+ { \
+ *--s = '0' ; \
+ s_len++ ; \
+ }
+
+/*
+ * Macro that does padding. The padding is done by printing
+ * the character ch.
+ */
+#define PAD( width, len, ch ) do \
+ { \
+ INS_CHAR( ch, sp, bep, cc ) ; \
+ width-- ; \
+ } \
+ while ( width > len )
+
+/*
+ * Prefix the character ch to the string str
+ * Increase length
+ * Set the has_prefix flag
+ */
+#define PREFIX( str, length, ch ) *--str = ch ; length++ ; has_prefix = YES
+
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#define LCONV_DECIMAL_POINT (*lconv->decimal_point)
+#else
+#define LCONV_DECIMAL_POINT '.'
+#endif
+#define NUL '\0'
+#define S_NULL "(null)"
+#define S_NULL_LEN 6
+#define FLOAT_DIGITS 6
+
+/*
+ * Do format conversion placing the output in buffer
+ */
+static int format_converter(register buffy *odp, const char *fmt, zend_bool escape_xml, va_list ap TSRMLS_DC) {
+ char *sp;
+ char *bep;
+ int cc = 0;
+ int i;
+
+ char *s = NULL, *free_s = NULL;
+ size_t s_len;
+ zend_bool free_zcopy;
+ zval *zvp, zcopy;
+
+ int min_width = 0;
+ int precision = 0;
+ enum {
+ LEFT, RIGHT
+ } adjust;
+ char pad_char;
+ char prefix_char;
+
+ double fp_num;
+ wide_int i_num = (wide_int) 0;
+ u_wide_int ui_num;
+
+ char num_buf[NUM_BUF_SIZE];
+ char char_buf[2]; /* for printing %% and %<unknown> */
+
+#ifdef HAVE_LOCALE_H
+ struct lconv *lconv = NULL;
+#endif
+
+ /*
+ * Flag variables
+ */
+ length_modifier_e modifier;
+ boolean_e alternate_form;
+ boolean_e print_sign;
+ boolean_e print_blank;
+ boolean_e adjust_precision;
+ boolean_e adjust_width;
+ bool_int is_negative;
+
+ sp = odp->nextb;
+ bep = odp->buf_end;
+
+ while (*fmt) {
+ if (*fmt != '%') {
+ INS_CHAR(*fmt, sp, bep, cc);
+ } else {
+ /*
+ * Default variable settings
+ */
+ adjust = RIGHT;
+ alternate_form = print_sign = print_blank = NO;
+ pad_char = ' ';
+ prefix_char = NUL;
+ free_zcopy = 0;
+
+ fmt++;
+
+ /*
+ * Try to avoid checking for flags, width or precision
+ */
+ if (isascii((int)*fmt) && !islower((int)*fmt)) {
+ /*
+ * Recognize flags: -, #, BLANK, +
+ */
+ for (;; fmt++) {
+ if (*fmt == '-')
+ adjust = LEFT;
+ else if (*fmt == '+')
+ print_sign = YES;
+ else if (*fmt == '#')
+ alternate_form = YES;
+ else if (*fmt == ' ')
+ print_blank = YES;
+ else if (*fmt == '0')
+ pad_char = '0';
+ else
+ break;
+ }
+
+ /*
+ * Check if a width was specified
+ */
+ if (isdigit((int)*fmt)) {
+ STR_TO_DEC(fmt, min_width);
+ adjust_width = YES;
+ } else if (*fmt == '*') {
+ min_width = va_arg(ap, int);
+ fmt++;
+ adjust_width = YES;
+ if (min_width < 0) {
+ adjust = LEFT;
+ min_width = -min_width;
+ }
+ } else
+ adjust_width = NO;
+
+ /*
+ * Check if a precision was specified
+ */
+ if (*fmt == '.') {
+ adjust_precision = YES;
+ fmt++;
+ if (isdigit((int)*fmt)) {
+ STR_TO_DEC(fmt, precision);
+ } else if (*fmt == '*') {
+ precision = va_arg(ap, int);
+ fmt++;
+ if (precision < 0)
+ precision = 0;
+ } else
+ precision = 0;
+
+ if (precision > FORMAT_CONV_MAX_PRECISION && *fmt != 's' && *fmt != 'v' && *fmt != 'b') {
+ precision = FORMAT_CONV_MAX_PRECISION;
+ }
+ } else
+ adjust_precision = NO;
+ } else
+ adjust_precision = adjust_width = NO;
+
+ /*
+ * Modifier check
+ */
+ switch (*fmt) {
+ case 'L':
+ fmt++;
+ modifier = LM_LONG_DOUBLE;
+ break;
+ case 'I':
+ fmt++;
+#if SIZEOF_LONG_LONG
+ if (*fmt == '6' && *(fmt+1) == '4') {
+ fmt += 2;
+ modifier = LM_LONG_LONG;
+ } else
+#endif
+ if (*fmt == '3' && *(fmt+1) == '2') {
+ fmt += 2;
+ modifier = LM_LONG;
+ } else {
+#ifdef _WIN64
+ modifier = LM_LONG_LONG;
+#else
+ modifier = LM_LONG;
+#endif
+ }
+ break;
+ case 'l':
+ fmt++;
+#if SIZEOF_LONG_LONG
+ if (*fmt == 'l') {
+ fmt++;
+ modifier = LM_LONG_LONG;
+ } else
+#endif
+ modifier = LM_LONG;
+ break;
+ case 'z':
+ fmt++;
+ modifier = LM_SIZE_T;
+ break;
+ case 'j':
+ fmt++;
+#if SIZEOF_INTMAX_T
+ modifier = LM_INTMAX_T;
+#else
+ modifier = LM_SIZE_T;
+#endif
+ break;
+ case 't':
+ fmt++;
+#if SIZEOF_PTRDIFF_T
+ modifier = LM_PTRDIFF_T;
+#else
+ modifier = LM_SIZE_T;
+#endif
+ break;
+ case 'h':
+ fmt++;
+ if (*fmt == 'h') {
+ fmt++;
+ }
+ /* these are promoted to int, so no break */
+ default:
+ modifier = LM_STD;
+ break;
+ }
+
+ /*
+ * Argument extraction and printing.
+ * First we determine the argument type.
+ * Then, we convert the argument to a string.
+ * On exit from the switch, s points to the string that
+ * must be printed, s_len has the length of the string
+ * The precision requirements, if any, are reflected in s_len.
+ *
+ * NOTE: pad_char may be set to '0' because of the 0 flag.
+ * It is reset to ' ' by non-numeric formats
+ */
+ switch (*fmt) {
+ case 'Z':
+ zvp = (zval *) va_arg(ap, zval *);
+ free_zcopy = zend_make_printable_zval(zvp, &zcopy TSRMLS_CC);
+ if (free_zcopy) {
+ zvp = &zcopy;
+ }
+ s_len = Z_STRLEN_P(zvp);
+ s = Z_STRVAL_P(zvp);
+ if (adjust_precision && precision < s_len) {
+ s_len = precision;
+ }
+ break;
+ case 'u':
+ switch(modifier) {
+ default:
+ i_num = (wide_int) va_arg(ap, unsigned int);
+ break;
+ case LM_LONG_DOUBLE:
+ goto fmt_error;
+ case LM_LONG:
+ i_num = (wide_int) va_arg(ap, unsigned long int);
+ break;
+ case LM_SIZE_T:
+ i_num = (wide_int) va_arg(ap, size_t);
+ break;
+#if SIZEOF_LONG_LONG
+ case LM_LONG_LONG:
+ i_num = (wide_int) va_arg(ap, u_wide_int);
+ break;
+#endif
+#if SIZEOF_INTMAX_T
+ case LM_INTMAX_T:
+ i_num = (wide_int) va_arg(ap, uintmax_t);
+ break;
+#endif
+#if SIZEOF_PTRDIFF_T
+ case LM_PTRDIFF_T:
+ i_num = (wide_int) va_arg(ap, ptrdiff_t);
+ break;
+#endif
+ }
+ /*
+ * The rest also applies to other integer formats, so fall
+ * into that case.
+ */
+ case 'd':
+ case 'i':
+ /*
+ * Get the arg if we haven't already.
+ */
+ if ((*fmt) != 'u') {
+ switch(modifier) {
+ default:
+ i_num = (wide_int) va_arg(ap, int);
+ break;
+ case LM_LONG_DOUBLE:
+ goto fmt_error;
+ case LM_LONG:
+ i_num = (wide_int) va_arg(ap, long int);
+ break;
+ case LM_SIZE_T:
+#if SIZEOF_SSIZE_T
+ i_num = (wide_int) va_arg(ap, ssize_t);
+#else
+ i_num = (wide_int) va_arg(ap, size_t);
+#endif
+ break;
+#if SIZEOF_LONG_LONG
+ case LM_LONG_LONG:
+ i_num = (wide_int) va_arg(ap, wide_int);
+ break;
+#endif
+#if SIZEOF_INTMAX_T
+ case LM_INTMAX_T:
+ i_num = (wide_int) va_arg(ap, intmax_t);
+ break;
+#endif
+#if SIZEOF_PTRDIFF_T
+ case LM_PTRDIFF_T:
+ i_num = (wide_int) va_arg(ap, ptrdiff_t);
+ break;
+#endif
+ }
+ }
+ s = ap_php_conv_10(i_num, (*fmt) == 'u', &is_negative,
+ &num_buf[NUM_BUF_SIZE], &s_len);
+ FIX_PRECISION(adjust_precision, precision, s, s_len);
+
+ if (*fmt != 'u') {
+ if (is_negative) {
+ prefix_char = '-';
+ } else if (print_sign) {
+ prefix_char = '+';
+ } else if (print_blank) {
+ prefix_char = ' ';
+ }
+ }
+ break;
+
+
+ case 'o':
+ switch(modifier) {
+ default:
+ ui_num = (u_wide_int) va_arg(ap, unsigned int);
+ break;
+ case LM_LONG_DOUBLE:
+ goto fmt_error;
+ case LM_LONG:
+ ui_num = (u_wide_int) va_arg(ap, unsigned long int);
+ break;
+ case LM_SIZE_T:
+ ui_num = (u_wide_int) va_arg(ap, size_t);
+ break;
+#if SIZEOF_LONG_LONG
+ case LM_LONG_LONG:
+ ui_num = (u_wide_int) va_arg(ap, u_wide_int);
+ break;
+#endif
+#if SIZEOF_INTMAX_T
+ case LM_INTMAX_T:
+ ui_num = (u_wide_int) va_arg(ap, uintmax_t);
+ break;
+#endif
+#if SIZEOF_PTRDIFF_T
+ case LM_PTRDIFF_T:
+ ui_num = (u_wide_int) va_arg(ap, ptrdiff_t);
+ break;
+#endif
+ }
+ s = ap_php_conv_p2(ui_num, 3, *fmt, &num_buf[NUM_BUF_SIZE], &s_len);
+ FIX_PRECISION(adjust_precision, precision, s, s_len);
+ if (alternate_form && *s != '0') {
+ *--s = '0';
+ s_len++;
+ }
+ break;
+
+
+ case 'x':
+ case 'X':
+ switch(modifier) {
+ default:
+ ui_num = (u_wide_int) va_arg(ap, unsigned int);
+ break;
+ case LM_LONG_DOUBLE:
+ goto fmt_error;
+ case LM_LONG:
+ ui_num = (u_wide_int) va_arg(ap, unsigned long int);
+ break;
+ case LM_SIZE_T:
+ ui_num = (u_wide_int) va_arg(ap, size_t);
+ break;
+#if SIZEOF_LONG_LONG
+ case LM_LONG_LONG:
+ ui_num = (u_wide_int) va_arg(ap, u_wide_int);
+ break;
+#endif
+#if SIZEOF_INTMAX_T
+ case LM_INTMAX_T:
+ ui_num = (u_wide_int) va_arg(ap, uintmax_t);
+ break;
+#endif
+#if SIZEOF_PTRDIFF_T
+ case LM_PTRDIFF_T:
+ ui_num = (u_wide_int) va_arg(ap, ptrdiff_t);
+ break;
+#endif
+ }
+ s = ap_php_conv_p2(ui_num, 4, *fmt, &num_buf[NUM_BUF_SIZE], &s_len);
+ FIX_PRECISION(adjust_precision, precision, s, s_len);
+ if (alternate_form && i_num != 0) {
+ *--s = *fmt; /* 'x' or 'X' */
+ *--s = '0';
+ s_len += 2;
+ }
+ break;
+
+
+ case 's':
+ case 'v':
+ s = va_arg(ap, char *);
+ if (s != NULL) {
+ if (adjust_precision) {
+ s_len = precision;
+ } else {
+ s_len = strlen(s);
+ }
+
+ if (escape_xml) {
+ /* added: support for xml escaping */
+
+ int old_slen = s_len, i = 0;
+ char *old_s = s, *s_ptr;
+ free_s = s_ptr = s = emalloc(old_slen * 6 + 1);
+ do {
+ if (old_s[i] == '&' || old_s[i] == '"' || old_s[i] == '<') {
+ *s_ptr++ = '&';
+ switch (old_s[i]) {
+ case '"':
+ s_len += 5;
+ *s_ptr++ = 'q';
+ *s_ptr++ = 'u';
+ *s_ptr++ = 'o';
+ *s_ptr++ = 't';
+ break;
+ case '<':
+ s_len += 3;
+ *s_ptr++ = 'l';
+ *s_ptr++ = 't';
+ break;
+ case '&':
+ s_len += 4;
+ *s_ptr++ = 'a';
+ *s_ptr++ = 'm';
+ *s_ptr++ = 'p';
+ break;
+ }
+ *s_ptr++ = ';';
+ } else {
+ *s_ptr++ = old_s[i];
+ }
+ } while (i++ < old_slen);
+ }
+ } else {
+ s = S_NULL;
+ s_len = S_NULL_LEN;
+ }
+ pad_char = ' ';
+ break;
+
+
+ case 'b':
+ if (escape_xml) {
+ s = PHPDBG_G(err_buf).xml;
+ } else {
+ s = PHPDBG_G(err_buf).msg;
+ }
+
+ if (s != NULL) {
+ if (escape_xml) {
+ s_len = PHPDBG_G(err_buf).xmllen;
+ } else {
+ s_len = PHPDBG_G(err_buf).msglen;
+ }
+
+ if (adjust_precision && precision != s_len) {
+ s_len = precision;
+ }
+ } else {
+ s = "";
+ s_len = 0;
+ }
+ pad_char = ' ';
+ break;
+
+
+ case 'r':
+ if (PHPDBG_G(req_id)) {
+ s_len = spprintf(&s, 0, "req=\"%lu\"", PHPDBG_G(req_id));
+ free_s = s;
+ } else {
+ s = "";
+ s_len = 0;
+ }
+ break;
+
+
+ case 'f':
+ case 'F':
+ case 'e':
+ case 'E':
+
+ switch(modifier) {
+ case LM_LONG_DOUBLE:
+ fp_num = (double) va_arg(ap, long double);
+ break;
+ case LM_STD:
+ fp_num = va_arg(ap, double);
+ break;
+ default:
+ goto fmt_error;
+ }
+
+ if (zend_isnan(fp_num)) {
+ s = "NAN";
+ s_len = 3;
+ } else if (zend_isinf(fp_num)) {
+ s = "INF";
+ s_len = 3;
+ } else {
+#ifdef HAVE_LOCALE_H
+ if (!lconv) {
+ lconv = localeconv();
+ }
+#endif
+ s = php_conv_fp((*fmt == 'f')?'F':*fmt, fp_num, alternate_form,
+ (adjust_precision == NO) ? FLOAT_DIGITS : precision,
+ (*fmt == 'f')?LCONV_DECIMAL_POINT:'.',
+ &is_negative, &num_buf[1], &s_len);
+ if (is_negative)
+ prefix_char = '-';
+ else if (print_sign)
+ prefix_char = '+';
+ else if (print_blank)
+ prefix_char = ' ';
+ }
+ break;
+
+
+ case 'g':
+ case 'k':
+ case 'G':
+ case 'H':
+ switch(modifier) {
+ case LM_LONG_DOUBLE:
+ fp_num = (double) va_arg(ap, long double);
+ break;
+ case LM_STD:
+ fp_num = va_arg(ap, double);
+ break;
+ default:
+ goto fmt_error;
+ }
+
+ if (zend_isnan(fp_num)) {
+ s = "NAN";
+ s_len = 3;
+ break;
+ } else if (zend_isinf(fp_num)) {
+ if (fp_num > 0) {
+ s = "INF";
+ s_len = 3;
+ } else {
+ s = "-INF";
+ s_len = 4;
+ }
+ break;
+ }
+
+ if (adjust_precision == NO) {
+ precision = FLOAT_DIGITS;
+ } else if (precision == 0) {
+ precision = 1;
+ }
+ /*
+ * * We use &num_buf[ 1 ], so that we have room for the sign
+ */
+#ifdef HAVE_LOCALE_H
+ if (!lconv) {
+ lconv = localeconv();
+ }
+#endif
+ s = php_gcvt(fp_num, precision, (*fmt=='H' || *fmt == 'k') ? '.' : LCONV_DECIMAL_POINT, (*fmt == 'G' || *fmt == 'H')?'E':'e', &num_buf[1]);
+ if (*s == '-') {
+ prefix_char = *s++;
+ } else if (print_sign) {
+ prefix_char = '+';
+ } else if (print_blank) {
+ prefix_char = ' ';
+ }
+
+ s_len = strlen(s);
+
+ if (alternate_form && (strchr(s, '.')) == NULL) {
+ s[s_len++] = '.';
+ }
+ break;
+
+
+ case 'c':
+ char_buf[0] = (char) (va_arg(ap, int));
+ s = &char_buf[0];
+ s_len = 1;
+ pad_char = ' ';
+ break;
+
+
+ case '%':
+ char_buf[0] = '%';
+ s = &char_buf[0];
+ s_len = 1;
+ pad_char = ' ';
+ break;
+
+
+ case 'n':
+ *(va_arg(ap, int *)) = cc;
+ goto skip_output;
+
+ /*
+ * Always extract the argument as a "char *" pointer. We
+ * should be using "void *" but there are still machines
+ * that don't understand it.
+ * If the pointer size is equal to the size of an unsigned
+ * integer we convert the pointer to a hex number, otherwise
+ * we print "%p" to indicate that we don't handle "%p".
+ */
+ case 'p':
+ if (sizeof(char *) <= sizeof(u_wide_int)) {
+ ui_num = (u_wide_int)((size_t) va_arg(ap, char *));
+ s = ap_php_conv_p2(ui_num, 4, 'x',
+ &num_buf[NUM_BUF_SIZE], &s_len);
+ if (ui_num != 0) {
+ *--s = 'x';
+ *--s = '0';
+ s_len += 2;
+ }
+ } else {
+ s = "%p";
+ s_len = 2;
+ }
+ pad_char = ' ';
+ break;
+
+
+ case NUL:
+ /*
+ * The last character of the format string was %.
+ * We ignore it.
+ */
+ continue;
+
+
+fmt_error:
+ php_error(E_ERROR, "Illegal length modifier specified '%c' in s[np]printf call", *fmt);
+ /*
+ * The default case is for unrecognized %'s.
+ * We print %<char> to help the user identify what
+ * option is not understood.
+ * This is also useful in case the user wants to pass
+ * the output of format_converter to another function
+ * that understands some other %<char> (like syslog).
+ * Note that we can't point s inside fmt because the
+ * unknown <char> could be preceded by width etc.
+ */
+ default:
+ char_buf[0] = '%';
+ char_buf[1] = *fmt;
+ s = char_buf;
+ s_len = 2;
+ pad_char = ' ';
+ break;
+ }
+
+ if (prefix_char != NUL) {
+ *--s = prefix_char;
+ s_len++;
+ }
+ if (adjust_width && adjust == RIGHT && min_width > s_len) {
+ if (pad_char == '0' && prefix_char != NUL) {
+ INS_CHAR(*s, sp, bep, cc)
+ s++;
+ s_len--;
+ min_width--;
+ }
+ PAD(min_width, s_len, pad_char);
+ }
+ /*
+ * Print the string s.
+ */
+ for (i = s_len; i != 0; i--) {
+ INS_CHAR(*s, sp, bep, cc);
+ s++;
+ }
+
+ if (adjust_width && adjust == LEFT && min_width > s_len)
+ PAD(min_width, s_len, pad_char);
+ if (free_zcopy) {
+ zval_dtor(&zcopy);
+ }
+ }
+skip_output:
+ if (free_s) {
+ efree(free_s);
+ free_s = NULL;
+ }
+
+ fmt++;
+ }
+ odp->nextb = sp;
+ return (cc);
+}
+
+static void strx_printv(int *ccp, char *buf, size_t len, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) {
+ buffy od;
+ int cc;
+
+ /*
+ * First initialize the descriptor
+ * Notice that if no length is given, we initialize buf_end to the
+ * highest possible address.
+ */
+ if (len == 0) {
+ od.buf_end = (char *) ~0;
+ od.nextb = (char *) ~0;
+ } else {
+ od.buf_end = &buf[len-1];
+ od.nextb = buf;
+ }
+
+ /*
+ * Do the conversion
+ */
+ cc = format_converter(&od, format, escape_xml, ap TSRMLS_CC);
+ if (len != 0 && od.nextb <= od.buf_end) {
+ *(od.nextb) = '\0';
+ }
+ if (ccp) {
+ *ccp = cc;
+ }
+}
+
+static int phpdbg_xml_vsnprintf(char *buf, size_t len, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) {
+ int cc;
+
+ strx_printv(&cc, buf, len, format, escape_xml, ap TSRMLS_CC);
+ return (cc);
+}
+
+PHPDBG_API int phpdbg_xml_vasprintf(char **buf, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) {
+ va_list ap2;
+ int cc;
+
+ va_copy(ap2, ap);
+ cc = phpdbg_xml_vsnprintf(NULL, 0, format, escape_xml, ap2 TSRMLS_CC);
+ va_end(ap2);
+
+ *buf = NULL;
+
+ if (cc >= 0) {
+ if ((*buf = emalloc(++cc)) != NULL) {
+ if ((cc = phpdbg_xml_vsnprintf(*buf, cc, format, escape_xml, ap TSRMLS_CC)) < 0) {
+ efree(*buf);
+ *buf = NULL;
+ }
+ }
+ }
+
+ return cc;
+}
+/* copy end */
+
+PHPDBG_API int _phpdbg_xml_asprintf(char **buf TSRMLS_DC, const char *format, zend_bool escape_xml, ...) {
+ int ret;
+ va_list va;
+
+ va_start(va, escape_xml);
+ ret = phpdbg_xml_vasprintf(buf, format, escape_xml, va TSRMLS_CC);
+ va_end(va);
+
+ return ret;
+}
+
+PHPDBG_API int _phpdbg_asprintf(char **buf TSRMLS_DC, const char *format, ...) {
+ int ret;
+ va_list va;
+
+ va_start(va, format);
+ ret = phpdbg_xml_vasprintf(buf, format, 0, va TSRMLS_CC);
+ va_end(va);
+
+ return ret;
+}
+
+static int phpdbg_encode_xml(char **buf, char *msg, int msglen, int from, char *to) {
+ int i;
+ int tolen = to ? strlen(to) : 5;
+ char *tmp = *buf = emalloc(msglen * tolen);
+ for (i = 0; i++ < msglen; msg++) {
+ if (*msg == '&') {
+ memcpy(tmp, ZEND_STRL("&amp;"));
+ tmp += sizeof("&amp;") - 1;
+ } else if (*msg == '<') {
+ memcpy(tmp, ZEND_STRL("&lt;"));
+ tmp += sizeof("&lt;") - 1;
+ } else if (((int) *msg) == from) {
+ memcpy(tmp, to, tolen);
+ tmp += tolen;
+ } else {
+ *tmp++ = *msg;
+ }
+ }
+
+ {
+ int len = tmp - *buf;
+ *buf = erealloc(*buf, len + 1);
+ return len;
+ }
+}
+
+static void phpdbg_encode_ctrl_chars(char **buf, int *buflen) {
+ char *tmp, *tmpptr;
+ int len;
+ int i;
+
+ tmp = tmpptr = emalloc(*buflen * 5);
+
+ for (i = 0; i < *buflen; i++) {
+ if ((*buf)[i] < 0x20) {
+ *tmpptr++ = '&';
+ *tmpptr++ = '#';
+ if ((unsigned int) ((*buf)[i]) > 9) {
+ *tmpptr++ = ((*buf)[i] / 10) + '0';
+ }
+ *tmpptr++ = ((*buf)[i] % 10) + '0';
+ *tmpptr++ = ';';
+ } else {
+ *tmpptr++ = (*buf)[i];
+ }
+ }
+
+ len = tmpptr - tmp;
+
+ efree(*buf);
+ *buf = erealloc(tmp, len + 1);
+ *buflen = len;
+}
+
+static int phpdbg_process_print(int fd, int type, const char *tag, const char *msg, int msglen, const char *xml, int xmllen TSRMLS_DC) {
+ char *msgout = NULL, *buf;
+ int msgoutlen, xmloutlen, buflen;
+ const char *severity;
+
+ if ((PHPDBG_G(flags) & PHPDBG_WRITE_XML) && PHPDBG_G(in_script_xml) && PHPDBG_G(in_script_xml) != type) {
+ phpdbg_mixed_write(fd, ZEND_STRL("</stream>") TSRMLS_CC);
+ PHPDBG_G(in_script_xml) = 0;
+ }
+
+ switch (type) {
+ case P_ERROR:
+ severity = "error";
+ if (!PHPDBG_G(last_was_newline)) {
+ if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
+ phpdbg_mixed_write(fd, ZEND_STRL("<phpdbg>\n" "</phpdbg>") TSRMLS_CC);
+ } else {
+ phpdbg_mixed_write(fd, ZEND_STRL("\n") TSRMLS_CC);
+ }
+ PHPDBG_G(last_was_newline) = 1;
+ }
+ if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) {
+ msgoutlen = phpdbg_asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, msglen, msg);
+ } else {
+ msgoutlen = phpdbg_asprintf(&msgout, "[%.*s]\n", msglen, msg);
+ }
+ break;
+
+ case P_NOTICE:
+ severity = "notice";
+ if (!PHPDBG_G(last_was_newline)) {
+ if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
+ phpdbg_mixed_write(fd, ZEND_STRL("<phpdbg>\n" "</phpdbg>") TSRMLS_CC);
+ } else {
+ phpdbg_mixed_write(fd, ZEND_STRL("\n") TSRMLS_CC);
+ }
+ PHPDBG_G(last_was_newline) = 1;
+ }
+ if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) {
+ msgoutlen = phpdbg_asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, msglen, msg);
+ } else {
+ msgoutlen = phpdbg_asprintf(&msgout, "[%.*s]\n", msglen, msg);
+ }
+ break;
+
+ case P_WRITELN:
+ severity = "normal";
+ if (msg) {
+ msgoutlen = phpdbg_asprintf(&msgout, "%.*s\n", msglen, msg);
+ } else {
+ msgoutlen = 1;
+ msgout = estrdup("\n");
+ }
+ PHPDBG_G(last_was_newline) = 1;
+ break;
+
+ case P_WRITE:
+ severity = "normal";
+ if (msg) {
+ msgout = estrndup(msg, msglen);
+ msgoutlen = msglen;
+ PHPDBG_G(last_was_newline) = msg[msglen - 1] == '\n';
+ } else {
+ msgoutlen = 0;
+ msgout = estrdup("");
+ }
+ break;
+
+ case P_STDOUT:
+ case P_STDERR:
+ if (msg) {
+ PHPDBG_G(last_was_newline) = msg[msglen - 1] == '\n';
+ if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
+ zend_string *encoded;
+
+ if (PHPDBG_G(in_script_xml) != type) {
+ char *stream_buf;
+ int stream_buflen = phpdbg_asprintf(&stream_buf, "<stream type=\"%s\">", type == P_STDERR ? "stderr" : "stdout");
+ phpdbg_mixed_write(fd, stream_buf, stream_buflen TSRMLS_CC);
+ efree(stream_buf);
+ PHPDBG_G(in_script_xml) = type;
+ }
+ encoded = php_escape_html_entities((unsigned char *) msg, msglen, 0, ENT_NOQUOTES, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC);
+ buflen = encoded->len;
+ memcpy(buf = emalloc(buflen + 1), encoded->val, buflen);
+ phpdbg_encode_ctrl_chars(&buf, &buflen);
+ phpdbg_mixed_write(fd, buf, buflen TSRMLS_CC);
+ efree(buf);
+ } else {
+ phpdbg_mixed_write(fd, msg, msglen TSRMLS_CC);
+ }
+ return msglen;
+ }
+ break;
+
+ /* no formatting on logging output */
+ case P_LOG:
+ severity = "log";
+ if (msg) {
+ struct timeval tp;
+ if (gettimeofday(&tp, NULL) == SUCCESS) {
+ msgoutlen = phpdbg_asprintf(&msgout, "[%ld %.8F]: %.*s\n", tp.tv_sec, tp.tv_usec / 1000000., msglen, msg);
+ } else {
+ msgoutlen = FAILURE;
+ }
+ }
+ break;
+ }
+
+ if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
+ char *xmlout;
+
+ if (PHPDBG_G(req_id)) {
+ char *xmlbuf = NULL;
+ xmllen = phpdbg_asprintf(&xmlbuf, "req=\"%lu\" %.*s", PHPDBG_G(req_id), xmllen, xml);
+ xml = xmlbuf;
+ }
+ if (msgout) {
+ buflen = phpdbg_encode_xml(&buf, msgout, msgoutlen, '"', "&quot;");
+ xmloutlen = phpdbg_asprintf(&xmlout, "<%s severity=\"%s\" %.*s msgout=\"%.*s\" />", tag, severity, xmllen, xml, buflen, buf);
+
+ efree(buf);
+ } else {
+ xmloutlen = phpdbg_asprintf(&xmlout, "<%s severity=\"%s\" %.*s msgout=\"\" />", tag, severity, xmllen, xml);
+ }
+
+ phpdbg_encode_ctrl_chars(&xmlout, &xmloutlen);
+ phpdbg_eol_convert(&xmlout, &xmloutlen TSRMLS_CC);
+ phpdbg_mixed_write(fd, xmlout, xmloutlen TSRMLS_CC);
+ efree(xmlout);
+ } else if (msgout) {
+ phpdbg_eol_convert(&msgout, &msgoutlen TSRMLS_CC);
+ phpdbg_mixed_write(fd, msgout, msgoutlen TSRMLS_CC);
+ }
+
+ if (PHPDBG_G(req_id) && (PHPDBG_G(flags) & PHPDBG_WRITE_XML)) {
+ efree((char *) xml);
+ }
+
+ if (msgout) {
+ efree(msgout);
+ }
+
+ return msgout ? msgoutlen : xmloutlen;
+} /* }}} */
+
+PHPDBG_API int phpdbg_vprint(int type TSRMLS_DC, int fd, const char *tag, const char *xmlfmt, const char *strfmt, va_list args) {
+ char *msg = NULL, *xml = NULL;
+ int msglen = 0, xmllen = 0;
+ int len;
+ va_list argcpy;
+
+ if (strfmt != NULL && strlen(strfmt) > 0L) {
+ va_copy(argcpy, args);
+ msglen = phpdbg_xml_vasprintf(&msg, strfmt, 0, argcpy TSRMLS_CC);
+ va_end(argcpy);
+ }
+
+ if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
+ if (xmlfmt != NULL && strlen(xmlfmt) > 0L) {
+ va_copy(argcpy, args);
+ xmllen = phpdbg_xml_vasprintf(&xml, xmlfmt, 1, argcpy TSRMLS_CC);
+ va_end(argcpy);
+ } else {
+ xml = estrdup("");
+ }
+ }
+
+ if (PHPDBG_G(err_buf).active && type != P_STDOUT && type != P_STDERR) {
+ PHPDBG_G(err_buf).type = type;
+ PHPDBG_G(err_buf).fd = fd;
+ PHPDBG_G(err_buf).tag = estrdup(tag);
+ PHPDBG_G(err_buf).msg = msg;
+ PHPDBG_G(err_buf).msglen = msglen;
+ if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
+ PHPDBG_G(err_buf).xml = xml;
+ PHPDBG_G(err_buf).xmllen = xmllen;
+ }
+
+ return msglen;
+ }
+
+ len = phpdbg_process_print(fd, type, tag, msg, msglen, xml, xmllen TSRMLS_CC);
+
+ if (msg) {
+ efree(msg);
+ }
+
+ if (xml) {
+ efree(xml);
+ }
+
+ return len;
+}
+
+PHPDBG_API void phpdbg_free_err_buf(TSRMLS_D) {
+ if (PHPDBG_G(err_buf).type == 0) {
+ return;
+ }
+
+ PHPDBG_G(err_buf).type = 0;
+
+ efree(PHPDBG_G(err_buf).tag);
+ efree(PHPDBG_G(err_buf).msg);
+ if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
+ efree(PHPDBG_G(err_buf).xml);
+ }
+}
+
+PHPDBG_API void phpdbg_activate_err_buf(zend_bool active TSRMLS_DC) {
+ PHPDBG_G(err_buf).active = active;
+}
+
+PHPDBG_API int phpdbg_output_err_buf(const char *tag, const char *xmlfmt, const char *strfmt TSRMLS_DC, ...) {
+ int len;
+ va_list args;
+ int errbuf_active = PHPDBG_G(err_buf).active;
+
+ PHPDBG_G(err_buf).active = 0;
+
+#ifdef ZTS
+ va_start(args, tsrm_ls);
+#else
+ va_start(args, strfmt);
+#endif
+ len = phpdbg_vprint(PHPDBG_G(err_buf).type TSRMLS_CC, PHPDBG_G(err_buf).fd, tag ? tag : PHPDBG_G(err_buf).tag, xmlfmt, strfmt, args);
+ va_end(args);
+
+ PHPDBG_G(err_buf).active = errbuf_active;
+ phpdbg_free_err_buf(TSRMLS_C);
+
+ return len;
+}
+
+PHPDBG_API int phpdbg_print(int type TSRMLS_DC, int fd, const char *tag, const char *xmlfmt, const char *strfmt, ...) {
+ va_list args;
+ int len;
+
+ va_start(args, strfmt);
+ len = phpdbg_vprint(type TSRMLS_CC, fd, tag, xmlfmt, strfmt, args);
+ va_end(args);
+
+ return len;
+}
+
+PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...) {
+ int len = 0;
+
+ if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
+ va_list args;
+ char *buffer;
+ int buflen;
+
+ va_start(args, fmt);
+ buflen = phpdbg_xml_vasprintf(&buffer, fmt, 1, args TSRMLS_CC);
+ va_end(args);
+
+ phpdbg_encode_ctrl_chars(&buffer, &buflen);
+
+ if (PHPDBG_G(in_script_xml)) {
+ phpdbg_mixed_write(fd, ZEND_STRL("</stream>") TSRMLS_CC);
+ PHPDBG_G(in_script_xml) = 0;
+ }
+
+ len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC);
+ efree(buffer);
+ }
+
+ return len;
+}
+
+PHPDBG_API int phpdbg_log_internal(int fd TSRMLS_DC, const char *fmt, ...) {
+ va_list args;
+ char *buffer;
+ int buflen;
+ int len = 0;
+
+ va_start(args, fmt);
+ buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args TSRMLS_CC);
+ va_end(args);
+
+ len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC);
+ efree(buffer);
+
+ return len;
+}
+
+PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) {
+ va_list args;
+ char *buffer;
+ int buflen;
+ int len = 0;
+
+ va_start(args, fmt);
+ buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args TSRMLS_CC);
+ va_end(args);
+
+ if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
+ char *msg;
+ int msglen;
+
+ msglen = phpdbg_encode_xml(&msg, buffer, buflen, 256, NULL);
+ phpdbg_encode_ctrl_chars(&msg, &msglen);
+ phpdbg_eol_convert(&msg, &msglen TSRMLS_CC);
+
+ if (PHPDBG_G(in_script_xml)) {
+ phpdbg_mixed_write(fd, ZEND_STRL("</stream>") TSRMLS_CC);
+ PHPDBG_G(in_script_xml) = 0;
+ }
+
+ phpdbg_mixed_write(fd, ZEND_STRL("<phpdbg>") TSRMLS_CC);
+ len = phpdbg_mixed_write(fd, msg, msglen TSRMLS_CC);
+ phpdbg_mixed_write(fd, ZEND_STRL("</phpdbg>") TSRMLS_CC);
+ } else {
+ phpdbg_eol_convert(&buffer, &buflen TSRMLS_CC);
+ len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC);
+ }
+
+ return len;
+}
+
+
+PHPDBG_API int phpdbg_rlog_internal(int fd TSRMLS_DC, const char *fmt, ...) { /* {{{ */
+ int rc = 0;
+
+ va_list args;
+ struct timeval tp;
+
+ va_start(args, fmt);
+ if (gettimeofday(&tp, NULL) == SUCCESS) {
+ char friendly[100];
+ char *format = NULL, *buffer = NULL, *outbuf = NULL;
+ const time_t tt = tp.tv_sec;
+
+#ifdef PHP_WIN32
+ strftime(friendly, 100, "%a %b %d %H.%%04d %Y", localtime(&tt));
+#else
+ strftime(friendly, 100, "%a %b %d %T.%%04d %Y", localtime(&tt));
+#endif
+ phpdbg_asprintf(&buffer, friendly, tp.tv_usec/1000);
+ phpdbg_asprintf(&format, "[%s]: %s\n", buffer, fmt);
+ rc = phpdbg_xml_vasprintf(&outbuf, format, 0, args TSRMLS_CC);
+
+ if (outbuf) {
+ rc = phpdbg_mixed_write(fd, outbuf, rc TSRMLS_CC);
+ efree(outbuf);
+ }
+
+ efree(format);
+ efree(buffer);
+ }
+ va_end(args);
+
+ return rc;
+} /* }}} */
diff --git a/sapi/phpdbg/phpdbg_out.h b/sapi/phpdbg/phpdbg_out.h
new file mode 100644
index 0000000000..ea25b04279
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_out.h
@@ -0,0 +1,93 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef PHPDBG_OUT_H
+#define PHPDBG_OUT_H
+
+/**
+ * Error/notice/formatting helpers
+ */
+enum {
+ P_ERROR = 1,
+ P_NOTICE,
+ P_WRITELN,
+ P_WRITE,
+ P_STDOUT,
+ P_STDERR,
+ P_LOG
+};
+
+#ifdef ZTS
+PHPDBG_API int phpdbg_print(int severity TSRMLS_DC, int fd, const char *tag, const char *xmlfmt, const char *strfmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 6, 7);
+PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4);
+PHPDBG_API int phpdbg_log_internal(int fd TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4);
+PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4);
+PHPDBG_API int phpdbg_rlog_internal(int fd TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4);
+#else
+PHPDBG_API int phpdbg_print(int severity, int fd, const char *tag, const char *xmlfmt, const char *strfmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 5, 6);
+PHPDBG_API int phpdbg_xml_internal(int fd, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3);
+PHPDBG_API int phpdbg_log_internal(int fd, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3);
+PHPDBG_API int phpdbg_out_internal(int fd, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3);
+PHPDBG_API int phpdbg_rlog_internal(int fd, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3);
+#endif
+
+
+#define phpdbg_error(tag, xmlfmt, strfmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__)
+#define phpdbg_notice(tag, xmlfmt, strfmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__)
+#define phpdbg_writeln(tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__)
+#define phpdbg_write(tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__)
+#define phpdbg_script(type, fmt, ...) phpdbg_print(type TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, NULL, NULL, fmt, ##__VA_ARGS__)
+#define phpdbg_log(fmt, ...) phpdbg_log_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__)
+#define phpdbg_xml(fmt, ...) phpdbg_xml_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__)
+#define phpdbg_out(fmt, ...) phpdbg_out_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__)
+
+#define phpdbg_error_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__)
+#define phpdbg_notice_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__)
+#define phpdbg_writeln_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__)
+#define phpdbg_write_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__)
+#define phpdbg_script_ex(out, type, fmt, ...) phpdbg_print(type TSRMLS_CC, out, NULL, NULL, fmt, ##__VA_ARGS__)
+#define phpdbg_log_ex(out, fmt, ...) phpdbg_log_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__)
+#define phpdbg_xml_ex(out, fmt, ...) phpdbg_xml_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__)
+#define phpdbg_out_ex(out, fmt, ...) phpdbg_out_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__)
+
+#define phpdbg_rlog(fd, fmt, ...) phpdbg_rlog_internal(fd TSRMLS_CC, fmt, ##__VA_ARGS__)
+
+#define phpdbg_xml_asprintf(buf, ...) _phpdbg_xml_asprintf(buf TSRMLS_CC, ##__VA_ARGS__)
+PHPDBG_API int _phpdbg_xml_asprintf(char **buf TSRMLS_DC, const char *format, zend_bool escape_xml, ...);
+
+#define phpdbg_asprintf(buf, ...) _phpdbg_asprintf(buf TSRMLS_CC, ##__VA_ARGS__)
+PHPDBG_API int _phpdbg_asprintf(char **buf TSRMLS_DC, const char *format, ...);
+
+
+#if PHPDBG_DEBUG
+# define phpdbg_debug(fmt, ...) phpdbg_log_ex(PHPDBG_G(io)[PHPDBG_STDERR].fd TSRMLS_CC, fmt, ##__VA_ARGS__)
+#else
+# define phpdbg_debug(fmt, ...)
+#endif
+
+PHPDBG_API void phpdbg_free_err_buf(TSRMLS_D);
+PHPDBG_API void phpdbg_activate_err_buf(zend_bool active TSRMLS_DC);
+PHPDBG_API int phpdbg_output_err_buf(const char *tag, const char *xmlfmt, const char *strfmt TSRMLS_DC, ...);
+
+
+/* {{{ For separation */
+#define SEPARATE "------------------------------------------------" /* }}} */
+
+#endif /* PHPDBG_OUT_H */
diff --git a/sapi/phpdbg/phpdbg_parser.c b/sapi/phpdbg/phpdbg_parser.c
index e34c2f48ff..8bb9103a98 100644
--- a/sapi/phpdbg/phpdbg_parser.c
+++ b/sapi/phpdbg/phpdbg_parser.c
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 2.6.2. */
+/* A Bison parser, made by GNU Bison 2.6. */
/* Bison implementation for Yacc-like parsers in C
@@ -44,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.6.2"
+#define YYBISON_VERSION "2.6"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -69,8 +69,9 @@
#define yynerrs phpdbg_nerrs
/* Copy the first part of user declarations. */
+
/* Line 336 of yacc.c */
-#line 1 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+#line 1 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
/*
@@ -97,8 +98,9 @@ static int yyerror(void ***tsrm_ls, const char *msg);
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+
/* Line 336 of yacc.c */
-#line 102 "sapi/phpdbg/phpdbg_parser.c"
+#line 104 "sapi/phpdbg/phpdbg_parser.c"
# ifndef YY_NULL
# if defined __cplusplus && 201103L <= __cplusplus
@@ -128,8 +130,9 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
extern int phpdbg_debug;
#endif
/* "%code requires" blocks. */
+
/* Line 350 of yacc.c */
-#line 31 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+#line 31 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
#include "phpdbg.h"
#ifndef YY_TYPEDEF_YY_SCANNER_T
@@ -138,8 +141,9 @@ typedef void* yyscan_t;
#endif
+
/* Line 350 of yacc.c */
-#line 143 "sapi/phpdbg/phpdbg_parser.c"
+#line 147 "sapi/phpdbg/phpdbg_parser.c"
/* Tokens. */
#ifndef YYTOKENTYPE
@@ -164,7 +168,8 @@ typedef void* yyscan_t;
T_OPCODE = 272,
T_ID = 273,
T_INPUT = 274,
- T_UNEXPECTED = 275
+ T_UNEXPECTED = 275,
+ T_REQ_ID = 276
};
#endif
/* Tokens. */
@@ -186,6 +191,7 @@ typedef void* yyscan_t;
#define T_ID 273
#define T_INPUT 274
#define T_UNEXPECTED 275
+#define T_REQ_ID 276
@@ -215,8 +221,9 @@ int phpdbg_parse ();
/* Copy the second part of user declarations. */
+
/* Line 353 of yacc.c */
-#line 220 "sapi/phpdbg/phpdbg_parser.c"
+#line 227 "sapi/phpdbg/phpdbg_parser.c"
#ifdef short
# undef short
@@ -434,22 +441,22 @@ union yyalloc
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 25
+#define YYFINAL 26
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 42
+#define YYLAST 48
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 21
+#define YYNTOKENS 22
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 5
+#define YYNNTS 6
/* YYNRULES -- Number of rules. */
-#define YYNRULES 25
+#define YYNRULES 28
/* YYNRULES -- Number of states. */
-#define YYNSTATES 38
+#define YYNSTATES 43
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 275
+#define YYMAXUTOK 276
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -484,7 +491,7 @@ static const yytype_uint8 yytranslate[] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20
+ 15, 16, 17, 18, 19, 20, 21
};
#if YYDEBUG
@@ -492,30 +499,31 @@ static const yytype_uint8 yytranslate[] =
YYRHS. */
static const yytype_uint8 yyprhs[] =
{
- 0, 0, 3, 5, 7, 8, 10, 13, 17, 22,
- 27, 33, 37, 43, 47, 50, 52, 54, 56, 58,
- 60, 62, 64, 67, 70, 72
+ 0, 0, 3, 5, 7, 8, 10, 13, 16, 20,
+ 25, 30, 36, 40, 46, 50, 53, 55, 57, 59,
+ 61, 63, 65, 67, 69, 70, 74, 78, 81
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int8 yyrhs[] =
{
- 22, 0, -1, 23, -1, 25, -1, -1, 24, -1,
- 23, 24, -1, 18, 10, 14, -1, 18, 10, 12,
- 14, -1, 13, 18, 10, 14, -1, 13, 18, 10,
- 12, 14, -1, 18, 11, 18, -1, 18, 11, 18,
- 12, 14, -1, 18, 12, 14, -1, 6, 19, -1,
- 17, -1, 16, -1, 15, -1, 7, -1, 8, -1,
- 14, -1, 18, -1, 3, 19, -1, 5, 19, -1,
- 4, -1, 4, 19, -1
+ 23, 0, -1, 24, -1, 27, -1, -1, 25, -1,
+ 24, 25, -1, 24, 26, -1, 18, 10, 14, -1,
+ 18, 10, 12, 14, -1, 13, 18, 10, 14, -1,
+ 13, 18, 10, 12, 14, -1, 18, 11, 18, -1,
+ 18, 11, 18, 12, 14, -1, 18, 12, 14, -1,
+ 6, 19, -1, 17, -1, 16, -1, 15, -1, 7,
+ -1, 8, -1, 14, -1, 18, -1, 21, -1, -1,
+ 3, 26, 19, -1, 5, 26, 19, -1, 4, 26,
+ -1, 4, 26, 19, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
- 0, 66, 66, 67, 68, 72, 73, 77, 82, 87,
- 97, 107, 112, 118, 124, 129, 130, 131, 132, 133,
- 134, 135, 139, 144, 149, 153
+ 0, 67, 67, 68, 69, 73, 74, 75, 79, 84,
+ 89, 99, 109, 114, 120, 126, 131, 132, 133, 134,
+ 135, 136, 137, 141, 142, 146, 151, 156, 160
};
#endif
@@ -531,8 +539,9 @@ static const char *const yytname[] =
"\":: (double colon)\"", "\"# (pound sign)\"", "\"protocol (file://)\"",
"\"digits (numbers)\"", "\"literal (string)\"", "\"address\"",
"\"opcode\"", "\"identifier (command or function name)\"",
- "\"input (input string or data)\"", "\"input\"", "$accept", "input",
- "parameters", "parameter", "full_expression", YY_NULL
+ "\"input (input string or data)\"", "\"input\"",
+ "\"request id (-r %d)\"", "$accept", "input", "parameters", "parameter",
+ "req_id", "full_expression", YY_NULL
};
#endif
@@ -543,24 +552,24 @@ static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
- 275
+ 275, 276
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 21, 22, 22, 22, 23, 23, 24, 24, 24,
- 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
- 24, 24, 25, 25, 25, 25
+ 0, 22, 23, 23, 23, 24, 24, 24, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 26, 26, 27, 27, 27, 27
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const yytype_uint8 yyr2[] =
{
- 0, 2, 1, 1, 0, 1, 2, 3, 4, 4,
- 5, 3, 5, 3, 2, 1, 1, 1, 1, 1,
- 1, 1, 2, 2, 1, 2
+ 0, 2, 1, 1, 0, 1, 2, 2, 3, 4,
+ 4, 5, 3, 5, 3, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 3, 3, 2, 3
};
/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
@@ -568,33 +577,35 @@ static const yytype_uint8 yyr2[] =
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 4, 0, 24, 0, 0, 18, 19, 0, 20, 17,
- 16, 15, 21, 0, 2, 5, 3, 22, 25, 23,
- 14, 0, 0, 0, 0, 1, 6, 0, 0, 7,
- 11, 13, 0, 9, 8, 0, 10, 12
+ 4, 24, 24, 24, 0, 19, 20, 0, 21, 18,
+ 17, 16, 22, 0, 2, 5, 3, 23, 0, 27,
+ 0, 15, 0, 0, 0, 0, 1, 6, 7, 25,
+ 28, 26, 0, 0, 8, 12, 14, 0, 10, 9,
+ 0, 11, 13
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- -1, 13, 14, 15, 16
+ -1, 13, 14, 15, 18, 16
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -11
+#define YYPACT_NINF -16
static const yytype_int8 yypact[] =
{
- -3, -10, 11, 12, 13, -11, -11, 15, -11, -11,
- -11, -11, -4, 29, 10, -11, -11, -11, -11, -11,
- -11, 24, 7, 17, 22, -11, -11, 8, 23, -11,
- 26, -11, 25, -11, -11, 27, -11, -11
+ -3, -15, -15, -15, -10, -16, -16, 3, -16, -16,
+ -16, -16, 22, 29, 10, -16, -16, -16, 11, 17,
+ 19, -16, 30, 8, 21, 27, -16, -16, -16, -16,
+ -16, -16, 23, 28, -16, 31, -16, 32, -16, -16,
+ 33, -16, -16
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -11, -11, -11, 28, -11
+ -16, -16, -16, 34, 5, -16
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
@@ -603,26 +614,26 @@ static const yytype_int8 yypgoto[] =
#define YYTABLE_NINF -1
static const yytype_uint8 yytable[] =
{
- 1, 2, 3, 4, 5, 6, 22, 23, 24, 17,
+ 1, 2, 3, 4, 5, 6, 17, 19, 20, 21,
7, 8, 9, 10, 11, 12, 4, 5, 6, 28,
- 32, 29, 33, 7, 8, 9, 10, 11, 12, 25,
- 18, 19, 20, 21, 27, 30, 31, 34, 35, 36,
- 0, 37, 26
+ 33, 22, 34, 7, 8, 9, 10, 11, 12, 26,
+ 29, 17, 23, 24, 25, 37, 30, 38, 31, 35,
+ 32, 36, 39, 40, 0, 0, 41, 42, 27
};
#define yypact_value_is_default(yystate) \
- ((yystate) == (-11))
+ ((yystate) == (-16))
#define yytable_value_is_error(yytable_value) \
YYID (0)
static const yytype_int8 yycheck[] =
{
- 3, 4, 5, 6, 7, 8, 10, 11, 12, 19,
- 13, 14, 15, 16, 17, 18, 6, 7, 8, 12,
- 12, 14, 14, 13, 14, 15, 16, 17, 18, 0,
- 19, 19, 19, 18, 10, 18, 14, 14, 12, 14,
- -1, 14, 14
+ 3, 4, 5, 6, 7, 8, 21, 2, 3, 19,
+ 13, 14, 15, 16, 17, 18, 6, 7, 8, 14,
+ 12, 18, 14, 13, 14, 15, 16, 17, 18, 0,
+ 19, 21, 10, 11, 12, 12, 19, 14, 19, 18,
+ 10, 14, 14, 12, -1, -1, 14, 14, 14
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -630,9 +641,10 @@ static const yytype_int8 yycheck[] =
static const yytype_uint8 yystos[] =
{
0, 3, 4, 5, 6, 7, 8, 13, 14, 15,
- 16, 17, 18, 22, 23, 24, 25, 19, 19, 19,
- 19, 18, 10, 11, 12, 0, 24, 10, 12, 14,
- 18, 14, 12, 14, 14, 12, 14, 14
+ 16, 17, 18, 23, 24, 25, 27, 21, 26, 26,
+ 26, 19, 18, 10, 11, 12, 0, 25, 26, 19,
+ 19, 19, 10, 12, 14, 18, 14, 12, 14, 14,
+ 12, 14, 14
};
#define yyerrok (yyerrstatus = 0)
@@ -1284,6 +1296,7 @@ YYSTYPE yylval;
The wasted elements are never initialized. */
yyssp = yyss;
yyvsp = yyvs;
+
goto yysetstate;
/*------------------------------------------------------------.
@@ -1461,26 +1474,37 @@ yyreduce:
switch (yyn)
{
case 3:
-/* Line 1802 of yacc.c */
-#line 67 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+
+/* Line 1803 of yacc.c */
+#line 68 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); }
break;
case 5:
-/* Line 1802 of yacc.c */
-#line 72 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+
+/* Line 1803 of yacc.c */
+#line 73 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); }
break;
case 6:
-/* Line 1802 of yacc.c */
-#line 73 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+
+/* Line 1803 of yacc.c */
+#line 74 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(2) - (2)])); }
break;
case 7:
-/* Line 1802 of yacc.c */
-#line 77 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+
+/* Line 1803 of yacc.c */
+#line 75 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
+ { (yyval) = (yyvsp[(1) - (2)]); }
+ break;
+
+ case 8:
+
+/* Line 1803 of yacc.c */
+#line 79 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = FILE_PARAM;
(yyval).file.name = (yyvsp[(2) - (3)]).str;
@@ -1488,9 +1512,10 @@ yyreduce:
}
break;
- case 8:
-/* Line 1802 of yacc.c */
-#line 82 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+ case 9:
+
+/* Line 1803 of yacc.c */
+#line 84 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = NUMERIC_FILE_PARAM;
(yyval).file.name = (yyvsp[(1) - (4)]).str;
@@ -1498,9 +1523,10 @@ yyreduce:
}
break;
- case 9:
-/* Line 1802 of yacc.c */
-#line 87 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+ case 10:
+
+/* Line 1803 of yacc.c */
+#line 89 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = FILE_PARAM;
(yyval).file.name = malloc((yyvsp[(1) - (4)]).len + (yyvsp[(2) - (4)]).len + 1);
@@ -1513,9 +1539,10 @@ yyreduce:
}
break;
- case 10:
-/* Line 1802 of yacc.c */
-#line 97 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+ case 11:
+
+/* Line 1803 of yacc.c */
+#line 99 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = NUMERIC_FILE_PARAM;
(yyval).file.name = malloc((yyvsp[(1) - (5)]).len + (yyvsp[(2) - (5)]).len + 1);
@@ -1528,9 +1555,10 @@ yyreduce:
}
break;
- case 11:
-/* Line 1802 of yacc.c */
-#line 107 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+ case 12:
+
+/* Line 1803 of yacc.c */
+#line 109 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = METHOD_PARAM;
(yyval).method.class = (yyvsp[(1) - (3)]).str;
@@ -1538,9 +1566,10 @@ yyreduce:
}
break;
- case 12:
-/* Line 1802 of yacc.c */
-#line 112 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+ case 13:
+
+/* Line 1803 of yacc.c */
+#line 114 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = NUMERIC_METHOD_PARAM;
(yyval).method.class = (yyvsp[(1) - (5)]).str;
@@ -1549,9 +1578,10 @@ yyreduce:
}
break;
- case 13:
-/* Line 1802 of yacc.c */
-#line 118 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+ case 14:
+
+/* Line 1803 of yacc.c */
+#line 120 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = NUMERIC_FUNCTION_PARAM;
(yyval).str = (yyvsp[(1) - (3)]).str;
@@ -1560,9 +1590,10 @@ yyreduce:
}
break;
- case 14:
-/* Line 1802 of yacc.c */
-#line 124 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+ case 15:
+
+/* Line 1803 of yacc.c */
+#line 126 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = COND_PARAM;
(yyval).str = (yyvsp[(2) - (2)]).str;
@@ -1570,90 +1601,109 @@ yyreduce:
}
break;
- case 15:
-/* Line 1802 of yacc.c */
-#line 129 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
- break;
-
case 16:
-/* Line 1802 of yacc.c */
-#line 130 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+
+/* Line 1803 of yacc.c */
+#line 131 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 17:
-/* Line 1802 of yacc.c */
-#line 131 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+
+/* Line 1803 of yacc.c */
+#line 132 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 18:
-/* Line 1802 of yacc.c */
-#line 132 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+
+/* Line 1803 of yacc.c */
+#line 133 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 19:
-/* Line 1802 of yacc.c */
-#line 133 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+
+/* Line 1803 of yacc.c */
+#line 134 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 20:
-/* Line 1802 of yacc.c */
-#line 134 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+
+/* Line 1803 of yacc.c */
+#line 135 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 21:
-/* Line 1802 of yacc.c */
-#line 135 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+
+/* Line 1803 of yacc.c */
+#line 136 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 22:
-/* Line 1802 of yacc.c */
-#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+
+/* Line 1803 of yacc.c */
+#line 137 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
+ { (yyval) = (yyvsp[(1) - (1)]); }
+ break;
+
+ case 23:
+
+/* Line 1803 of yacc.c */
+#line 141 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
+ { PHPDBG_G(req_id) = (yyvsp[(1) - (1)]).num; }
+ break;
+
+ case 25:
+
+/* Line 1803 of yacc.c */
+#line 146 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = EVAL_PARAM;
- (yyval).str = (yyvsp[(2) - (2)]).str;
- (yyval).len = (yyvsp[(2) - (2)]).len;
+ (yyval).str = (yyvsp[(3) - (3)]).str;
+ (yyval).len = (yyvsp[(3) - (3)]).len;
}
break;
- case 23:
-/* Line 1802 of yacc.c */
-#line 144 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+ case 26:
+
+/* Line 1803 of yacc.c */
+#line 151 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = SHELL_PARAM;
- (yyval).str = (yyvsp[(2) - (2)]).str;
- (yyval).len = (yyvsp[(2) - (2)]).len;
+ (yyval).str = (yyvsp[(3) - (3)]).str;
+ (yyval).len = (yyvsp[(3) - (3)]).len;
}
break;
- case 24:
-/* Line 1802 of yacc.c */
-#line 149 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+ case 27:
+
+/* Line 1803 of yacc.c */
+#line 156 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = RUN_PARAM;
(yyval).len = 0;
}
break;
- case 25:
-/* Line 1802 of yacc.c */
-#line 153 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+ case 28:
+
+/* Line 1803 of yacc.c */
+#line 160 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = RUN_PARAM;
- (yyval).str = (yyvsp[(2) - (2)]).str;
- (yyval).len = (yyvsp[(2) - (2)]).len;
+ (yyval).str = (yyvsp[(3) - (3)]).str;
+ (yyval).len = (yyvsp[(3) - (3)]).len;
}
break;
-/* Line 1802 of yacc.c */
-#line 1657 "sapi/phpdbg/phpdbg_parser.c"
+
+/* Line 1803 of yacc.c */
+#line 1707 "sapi/phpdbg/phpdbg_parser.c"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1882,12 +1932,13 @@ yyreturn:
}
-/* Line 2048 of yacc.c */
-#line 160 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+
+/* Line 2049 of yacc.c */
+#line 167 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
static int yyerror(void ***tsrm_ls, const char *msg) {
- phpdbg_error("Parse Error: %s", msg);
+ phpdbg_error("command", "type=\"parseerror\" msg=\"%s\"", "Parse Error: %s", msg);
{
const phpdbg_param_t *top = PHPDBG_G(parser_stack);
@@ -1909,3 +1960,4 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC) {
return yyparse(NULL);
#endif
}
+
diff --git a/sapi/phpdbg/phpdbg_parser.h b/sapi/phpdbg/phpdbg_parser.h
index b3aadb9c62..e8ab7a6503 100644
--- a/sapi/phpdbg/phpdbg_parser.h
+++ b/sapi/phpdbg/phpdbg_parser.h
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 2.6.2. */
+/* A Bison parser, made by GNU Bison 2.6. */
/* Bison interface for Yacc-like parsers in C
@@ -40,8 +40,9 @@
extern int phpdbg_debug;
#endif
/* "%code requires" blocks. */
-/* Line 2055 of yacc.c */
-#line 31 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y"
+
+/* Line 2056 of yacc.c */
+#line 31 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
#include "phpdbg.h"
#ifndef YY_TYPEDEF_YY_SCANNER_T
@@ -50,8 +51,9 @@ typedef void* yyscan_t;
#endif
-/* Line 2055 of yacc.c */
-#line 55 "sapi/phpdbg/phpdbg_parser.h"
+
+/* Line 2056 of yacc.c */
+#line 57 "sapi/phpdbg/phpdbg_parser.h"
/* Tokens. */
#ifndef YYTOKENTYPE
@@ -76,7 +78,8 @@ typedef void* yyscan_t;
T_OPCODE = 272,
T_ID = 273,
T_INPUT = 274,
- T_UNEXPECTED = 275
+ T_UNEXPECTED = 275,
+ T_REQ_ID = 276
};
#endif
/* Tokens. */
@@ -98,6 +101,7 @@ typedef void* yyscan_t;
#define T_ID 273
#define T_INPUT 274
#define T_UNEXPECTED 275
+#define T_REQ_ID 276
diff --git a/sapi/phpdbg/phpdbg_parser.y b/sapi/phpdbg/phpdbg_parser.y
index 702bf78455..e4353976f3 100644
--- a/sapi/phpdbg/phpdbg_parser.y
+++ b/sapi/phpdbg/phpdbg_parser.y
@@ -59,6 +59,7 @@ typedef void* yyscan_t;
%token T_ID "identifier (command or function name)"
%token T_INPUT "input (input string or data)"
%token T_UNEXPECTED "input"
+%token T_REQ_ID "request id (-r %d)"
%% /* Rules */
@@ -71,6 +72,7 @@ input
parameters
: parameter { phpdbg_stack_push(PHPDBG_G(parser_stack), &$1); }
| parameters parameter { phpdbg_stack_push(PHPDBG_G(parser_stack), &$2); }
+ | parameters req_id { $$ = $1; }
;
parameter
@@ -135,32 +137,37 @@ parameter
| T_ID { $$ = $1; }
;
+req_id
+ : T_REQ_ID { PHPDBG_G(req_id) = $1.num; }
+ | /* empty */
+;
+
full_expression
- : T_EVAL T_INPUT {
+ : T_EVAL req_id T_INPUT {
$$.type = EVAL_PARAM;
- $$.str = $2.str;
- $$.len = $2.len;
+ $$.str = $3.str;
+ $$.len = $3.len;
}
- | T_SHELL T_INPUT {
+ | T_SHELL req_id T_INPUT {
$$.type = SHELL_PARAM;
- $$.str = $2.str;
- $$.len = $2.len;
+ $$.str = $3.str;
+ $$.len = $3.len;
}
- | T_RUN {
+ | T_RUN req_id {
$$.type = RUN_PARAM;
$$.len = 0;
}
- | T_RUN T_INPUT {
+ | T_RUN req_id T_INPUT {
$$.type = RUN_PARAM;
- $$.str = $2.str;
- $$.len = $2.len;
+ $$.str = $3.str;
+ $$.len = $3.len;
}
;
%%
static int yyerror(void ***tsrm_ls, const char *msg) {
- phpdbg_error("Parse Error: %s", msg);
+ phpdbg_error("command", "type=\"parseerror\" msg=\"%s\"", "Parse Error: %s", msg);
{
const phpdbg_param_t *top = PHPDBG_G(parser_stack);
diff --git a/sapi/phpdbg/phpdbg_print.c b/sapi/phpdbg/phpdbg_print.c
index eba7ed7666..62a614281d 100644
--- a/sapi/phpdbg/phpdbg_print.c
+++ b/sapi/phpdbg/phpdbg_print.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -26,25 +26,25 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-#define PHPDBG_PRINT_COMMAND_D(f, h, a, m, l, s) \
- PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[9])
+#define PHPDBG_PRINT_COMMAND_D(f, h, a, m, l, s, flags) \
+ PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[9], flags)
const phpdbg_command_t phpdbg_print_commands[] = {
- PHPDBG_PRINT_COMMAND_D(exec, "print out the instructions in the execution context", 'e', print_exec, NULL, 0),
- PHPDBG_PRINT_COMMAND_D(opline, "print out the instruction in the current opline", 'o', print_opline, NULL, 0),
- PHPDBG_PRINT_COMMAND_D(class, "print out the instructions in the specified class", 'c', print_class, NULL, "s"),
- PHPDBG_PRINT_COMMAND_D(method, "print out the instructions in the specified method", 'm', print_method, NULL, "m"),
- PHPDBG_PRINT_COMMAND_D(func, "print out the instructions in the specified function", 'f', print_func, NULL, "s"),
- PHPDBG_PRINT_COMMAND_D(stack, "print out the instructions in the current stack", 's', print_stack, NULL, 0),
+ PHPDBG_PRINT_COMMAND_D(exec, "print out the instructions in the execution context", 'e', print_exec, NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_PRINT_COMMAND_D(opline, "print out the instruction in the current opline", 'o', print_opline, NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_PRINT_COMMAND_D(class, "print out the instructions in the specified class", 'c', print_class, NULL, "s", PHPDBG_ASYNC_SAFE),
+ PHPDBG_PRINT_COMMAND_D(method, "print out the instructions in the specified method", 'm', print_method, NULL, "m", PHPDBG_ASYNC_SAFE),
+ PHPDBG_PRINT_COMMAND_D(func, "print out the instructions in the specified function", 'f', print_func, NULL, "s", PHPDBG_ASYNC_SAFE),
+ PHPDBG_PRINT_COMMAND_D(stack, "print out the instructions in the current stack", 's', print_stack, NULL, 0, PHPDBG_ASYNC_SAFE),
PHPDBG_END_COMMAND
};
PHPDBG_PRINT(opline) /* {{{ */
{
- if (EG(in_execution) && EG(current_execute_data)) {
+ if (PHPDBG_G(in_execution) && EG(current_execute_data)) {
phpdbg_print_opline(EG(current_execute_data), 1 TSRMLS_CC);
} else {
- phpdbg_error("Not Executing!");
+ phpdbg_error("inactive", "type=\"execution\"", "Not Executing!");
}
return SUCCESS;
@@ -56,38 +56,39 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC)
case ZEND_USER_FUNCTION: {
zend_op_array* op_array = &(method->op_array);
HashTable vars;
-
+
if (op_array) {
zend_op *opline = &(op_array->opcodes[0]);
uint32_t opcode = 0,
end = op_array->last-1;
if (method->common.scope) {
- phpdbg_writeln("\tL%d-%d %s::%s() %s",
- op_array->line_start, op_array->line_end,
- method->common.scope->name,
- method->common.function_name,
- op_array->filename ? op_array->filename : "unknown");
+ phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" method=\"%s::%s\" file=\"%s\"", "\tL%d-%d %s::%s() %s",
+ op_array->line_start,
+ op_array->line_end,
+ method->common.scope->name->val,
+ method->common.function_name->val,
+ op_array->filename ? op_array->filename->val : "unknown");
} else {
- phpdbg_writeln("\tL%d-%d %s() %s",
- method->common.function_name ? op_array->line_start : 0,
+ phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" function=\"%s\" file=\"%s\"", "\tL%d-%d %s() %s",
+ method->common.function_name ? op_array->line_start : 0,
method->common.function_name ? op_array->line_end : 0,
- method->common.function_name ? method->common.function_name : "{main}",
- op_array->filename ? op_array->filename : "unknown");
+ method->common.function_name ? method->common.function_name->val : "{main}",
+ op_array->filename ? op_array->filename->val : "unknown");
}
zend_hash_init(&vars, op_array->last, NULL, NULL, 0);
do {
char *decode = phpdbg_decode_opline(op_array, opline, &vars TSRMLS_CC);
if (decode != NULL) {
- phpdbg_writeln("\t\tL%u\t%p %-30s %s",
+ phpdbg_writeln("print", "line=\"%u\" opline=\"%p\" opcode=\"%s\" op=\"%s\"", "\t\tL%u\t%p %-30s %s",
opline->lineno,
- opline,
+ opline,
phpdbg_decode_opcode(opline->opcode),
decode);
free(decode);
} else {
- phpdbg_error("\tFailed to decode opline %16p", opline);
+ phpdbg_error("print", "type=\"decodefailure\" opline=\"%16p\"", "\tFailed to decode opline %16p", opline);
}
opline++;
} while (opcode++ < end);
@@ -97,9 +98,9 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC)
default: {
if (method->common.scope) {
- phpdbg_writeln("\tInternal %s::%s()", method->common.scope->name, method->common.function_name);
+ phpdbg_writeln("printoplineinfo", "type=\"Internal\" method=\"%s::%s\"", "\tInternal %s::%s()", method->common.scope->name->val, method->common.function_name->val);
} else {
- phpdbg_writeln("\tInternal %s()", method->common.function_name);
+ phpdbg_writeln("printoplineinfo", "type=\"Internal\" function=\"%s\"", "\tInternal %s()", method->common.function_name->val);
}
}
}
@@ -108,17 +109,17 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC)
PHPDBG_PRINT(exec) /* {{{ */
{
if (PHPDBG_G(exec)) {
- if (!PHPDBG_G(ops)) {
+ if (!PHPDBG_G(ops) && !(PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER)) {
phpdbg_compile(TSRMLS_C);
}
if (PHPDBG_G(ops)) {
- phpdbg_notice("Context %s", PHPDBG_G(exec));
+ phpdbg_notice("printinfo", "file=\"%s\" num=\"%d\"", "Context %s (%d ops)", PHPDBG_G(exec), PHPDBG_G(ops)->last);
phpdbg_print_function_helper((zend_function*) PHPDBG_G(ops) TSRMLS_CC);
}
} else {
- phpdbg_error("No execution context set");
+ phpdbg_error("inactive", "type=\"nocontext\"", "No execution context set");
}
return SUCCESS;
@@ -126,25 +127,24 @@ return SUCCESS;
PHPDBG_PRINT(stack) /* {{{ */
{
- zend_op_array *ops = EG(active_op_array);
-
- if (EG(in_execution) && ops) {
+ if (PHPDBG_G(in_execution) && EG(current_execute_data)) {
+ zend_op_array *ops = &EG(current_execute_data)->func->op_array;
if (ops->function_name) {
if (ops->scope) {
- phpdbg_notice("Stack in %s::%s()", ops->scope->name, ops->function_name);
+ phpdbg_notice("printinfo", "method=\"%s::%s\" num=\"%d\"", "Stack in %s::%s() (%d ops)", ops->scope->name->val, ops->function_name->val, ops->last);
} else {
- phpdbg_notice("Stack in %s()", ops->function_name);
+ phpdbg_notice("printinfo", "function=\"%s\" num=\"%d\"", "Stack in %s() (%d ops)", ops->function_name->val, ops->last);
}
} else {
if (ops->filename) {
- phpdbg_notice("Stack in %s", ops->filename);
+ phpdbg_notice("printinfo", "file=\"%s\" num=\"%d\"", "Stack in %s (%d ops)", ops->filename->val, ops->last);
} else {
- phpdbg_notice("Stack @ %p", ops);
+ phpdbg_notice("printinfo", "opline=\"%p\" num=\"%d\"", "Stack @ %p (%d ops)", ops, ops->last);
}
}
phpdbg_print_function_helper((zend_function*) ops TSRMLS_CC);
} else {
- phpdbg_error("Not Executing!");
+ phpdbg_error("inactive", "type=\"execution\"", "Not Executing!");
}
return SUCCESS;
@@ -152,32 +152,33 @@ PHPDBG_PRINT(stack) /* {{{ */
PHPDBG_PRINT(class) /* {{{ */
{
- zend_class_entry **ce;
+ zend_class_entry *ce;
- if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) {
- phpdbg_notice("%s %s: %s",
- ((*ce)->type == ZEND_USER_CLASS) ?
+ if (phpdbg_safe_class_lookup(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) {
+ phpdbg_notice("printinfo", "type=\"%s\" flag=\"%s\" class=\"%s\" num=\"%d\"", "%s %s: %s (%d methods)",
+ (ce->type == ZEND_USER_CLASS) ?
"User" : "Internal",
- ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ?
+ (ce->ce_flags & ZEND_ACC_INTERFACE) ?
"Interface" :
- ((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ?
+ (ce->ce_flags & ZEND_ACC_ABSTRACT) ?
"Abstract Class" :
"Class",
- (*ce)->name);
+ ce->name->val,
+ zend_hash_num_elements(&ce->function_table));
+
+ phpdbg_xml("<printmethods %r>");
- phpdbg_writeln("Methods (%d):", zend_hash_num_elements(&(*ce)->function_table));
- if (zend_hash_num_elements(&(*ce)->function_table)) {
- HashPosition position;
+ if (zend_hash_num_elements(&ce->function_table)) {
zend_function *method;
- for (zend_hash_internal_pointer_reset_ex(&(*ce)->function_table, &position);
- zend_hash_get_current_data_ex(&(*ce)->function_table, (void**) &method, &position) == SUCCESS;
- zend_hash_move_forward_ex(&(*ce)->function_table, &position)) {
+ ZEND_HASH_FOREACH_PTR(&ce->function_table, method) {
phpdbg_print_function_helper(method TSRMLS_CC);
- }
+ } ZEND_HASH_FOREACH_END();
}
+
+ phpdbg_xml("</printmethods>");
} else {
- phpdbg_error("The class %s could not be found", param->str);
+ phpdbg_error("print", "type=\"noclass\" class=\"%s\"", "The class %s could not be found", param->str);
}
return SUCCESS;
@@ -185,25 +186,27 @@ PHPDBG_PRINT(class) /* {{{ */
PHPDBG_PRINT(method) /* {{{ */
{
- zend_class_entry **ce;
+ zend_class_entry *ce;
- if (zend_lookup_class(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) {
+ if (phpdbg_safe_class_lookup(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) {
zend_function *fbc;
- char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name));
+ zend_string *lcname = zend_string_alloc(strlen(param->method.name), 0);
+ zend_str_tolower_copy(lcname->val, param->method.name, lcname->len);
- if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) {
- phpdbg_notice("%s Method %s",
+ if ((fbc = zend_hash_find_ptr(&ce->function_table, lcname))) {
+ phpdbg_notice("printinfo", "type=\"%s\" flags=\"Method\" symbol=\"%s\" num=\"%d\"", "%s Method %s (%d ops)",
(fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
- fbc->common.function_name);
+ fbc->common.function_name->val,
+ (fbc->type == ZEND_USER_FUNCTION) ? fbc->op_array.last : 0);
phpdbg_print_function_helper(fbc TSRMLS_CC);
} else {
- phpdbg_error("The method %s could not be found", param->method.name);
+ phpdbg_error("print", "type=\"nomethod\" method=\"%s::%s\"", "The method %s::%s could not be found", param->method.class, param->method.name);
}
- efree(lcname);
+ zend_string_release(lcname);
} else {
- phpdbg_error("The class %s could not be found", param->method.class);
+ phpdbg_error("print", "type=\"noclass\" class=\"%s\"", "The class %s could not be found", param->method.class);
}
return SUCCESS;
@@ -215,7 +218,7 @@ PHPDBG_PRINT(func) /* {{{ */
zend_function* fbc;
const char *func_name = param->str;
size_t func_name_len = param->len;
- char *lcname;
+ zend_string *lcname;
/* search active scope if begins with period */
if (func_name[0] == '.') {
if (EG(scope)) {
@@ -224,28 +227,34 @@ PHPDBG_PRINT(func) /* {{{ */
func_table = &EG(scope)->function_table;
} else {
- phpdbg_error("No active class");
+ phpdbg_error("inactive", "type=\"noclasses\"", "No active class");
return SUCCESS;
}
} else if (!EG(function_table)) {
- phpdbg_error("No function table loaded");
+ phpdbg_error("inactive", "type=\"function_table\"", "No function table loaded");
return SUCCESS;
} else {
func_table = EG(function_table);
}
- lcname = zend_str_tolower_dup(func_name, func_name_len);
+ lcname = zend_string_alloc(func_name_len, 0);
+ zend_str_tolower_copy(lcname->val, func_name, lcname->len);
- if (zend_hash_find(func_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) {
- phpdbg_notice("%s %s %s",
- (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
- (fbc->common.scope) ? "Method" : "Function",
- fbc->common.function_name);
+ phpdbg_try_access {
+ if ((fbc = zend_hash_find_ptr(func_table, lcname))) {
+ phpdbg_notice("printinfo", "type=\"%s\" flags=\"%s\" symbol=\"%s\" num=\"%d\"", "%s %s %s (%d ops)",
+ (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
+ (fbc->common.scope) ? "Method" : "Function",
+ fbc->common.function_name->val,
+ (fbc->type == ZEND_USER_FUNCTION) ? fbc->op_array.last : 0);
- phpdbg_print_function_helper(fbc TSRMLS_CC);
- } else {
- phpdbg_error("The function %s could not be found", func_name);
- }
+ phpdbg_print_function_helper(fbc TSRMLS_CC);
+ } else {
+ phpdbg_error("print", "type=\"nofunction\" function=\"%s\"", "The function %s could not be found", func_name);
+ }
+ } phpdbg_catch_access {
+ phpdbg_error("signalsegv", "function=\"%.*s\"", "Couldn't fetch function %.*s, invalid data source", (int) func_name_len, func_name);
+ } phpdbg_end_try_access();
efree(lcname);
diff --git a/sapi/phpdbg/phpdbg_print.h b/sapi/phpdbg/phpdbg_print.h
index 7bd096bf4e..ed85e965c1 100644
--- a/sapi/phpdbg/phpdbg_print.h
+++ b/sapi/phpdbg/phpdbg_print.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c
index 134ef33f6d..190907e687 100644
--- a/sapi/phpdbg/phpdbg_prompt.c
+++ b/sapi/phpdbg/phpdbg_prompt.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -22,7 +22,9 @@
#include <string.h>
#include "zend.h"
#include "zend_compile.h"
+#include "zend_exceptions.h"
#include "phpdbg.h"
+
#include "phpdbg_help.h"
#include "phpdbg_print.h"
#include "phpdbg_info.h"
@@ -37,126 +39,136 @@
#include "phpdbg_frame.h"
#include "phpdbg_lexer.h"
#include "phpdbg_parser.h"
+#include "phpdbg_wait.h"
+#include "phpdbg_eol.h"
+
+ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+
+#ifdef HAVE_LIBDL
+#ifdef PHP_WIN32
+#include "win32/param.h"
+#include "win32/winutil.h"
+#define GET_DL_ERROR() php_win_err()
+#elif defined(NETWARE)
+#include <sys/param.h>
+#define GET_DL_ERROR() dlerror()
+#else
+#include <sys/param.h>
+#define GET_DL_ERROR() DL_ERROR()
+#endif
+#endif
/* {{{ command declarations */
const phpdbg_command_t phpdbg_prompt_commands[] = {
- PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, "s"),
- PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 0),
- PHPDBG_COMMAND_D(continue,"continue execution", 'c', NULL, 0),
- PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s"),
- PHPDBG_COMMAND_D(ev, "evaluate some code", 0, NULL, "i"),
- PHPDBG_COMMAND_D(until, "continue past the current line", 'u', NULL, 0),
- PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'F', NULL, 0),
- PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0),
- PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_commands, 0),
- PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, "|*c"),
- PHPDBG_COMMAND_D(back, "show trace", 't', NULL, "|n"),
- PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, "|n"),
- PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, "*"),
- PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, "s"),
- PHPDBG_COMMAND_D(clean, "clean the execution environment", 'X', NULL, 0),
- PHPDBG_COMMAND_D(clear, "clear breakpoints", 'C', NULL, 0),
- PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, "|s"),
- PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, "s"),
- PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, "s"),
- PHPDBG_COMMAND_D(source, "execute a phpdbginit", '<', NULL, "s"),
- PHPDBG_COMMAND_D(export, "export breaks to a .phpdbginit script", '>', NULL, "s"),
- PHPDBG_COMMAND_D(sh, "shell a command", 0, NULL, "i"),
- PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0),
- PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "|ss"),
+ PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, "s", 0),
+ PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_COMMAND_D(continue,"continue execution", 'c', NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s", 0),
+ PHPDBG_COMMAND_D(ev, "evaluate some code", 0 , NULL, "i", PHPDBG_ASYNC_SAFE), /* restricted ASYNC_SAFE */
+ PHPDBG_COMMAND_D(until, "continue past the current line", 'u', NULL, 0, 0),
+ PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'F', NULL, 0, 0),
+ PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0, 0),
+ PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_commands, 0, 0),
+ PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, "|*c", 0),
+ PHPDBG_COMMAND_D(back, "show trace", 't', NULL, "|n", PHPDBG_ASYNC_SAFE),
+ PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, "|n", PHPDBG_ASYNC_SAFE),
+ PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, "*", PHPDBG_ASYNC_SAFE),
+ PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, "s", PHPDBG_ASYNC_SAFE),
+ PHPDBG_COMMAND_D(clean, "clean the execution environment", 'X', NULL, 0, 0),
+ PHPDBG_COMMAND_D(clear, "clear breakpoints", 'C', NULL, 0, 0),
+ PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, "|s", PHPDBG_ASYNC_SAFE),
+ PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, "s", PHPDBG_ASYNC_SAFE),
+ PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, "s", 0),
+ PHPDBG_COMMAND_D(source, "execute a phpdbginit", '<', NULL, "s", 0),
+ PHPDBG_COMMAND_D(export, "export breaks to a .phpdbginit script", '>', NULL, "s", PHPDBG_ASYNC_SAFE),
+ PHPDBG_COMMAND_D(sh, "shell a command", 0 , NULL, "i", 0),
+ PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_COMMAND_D(wait, "wait for other process", 'W', NULL, 0, 0),
+ PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "|ss", 0),
+ PHPDBG_COMMAND_D(eol, "set EOL", 'E', NULL, "|s", 0),
PHPDBG_END_COMMAND
}; /* }}} */
-ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-
static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ */
{
phpdbg_param_t *name = NULL;
if (stack->type == STACK_PARAM) {
+ char *lc_name;
+
name = stack->next;
-
+
if (!name || name->type != STR_PARAM) {
return FAILURE;
}
-
- if (zend_hash_exists(
- &PHPDBG_G(registered), name->str, name->len+1)) {
- zval fname, *fretval;
- zend_fcall_info fci;
+ lc_name = zend_str_tolower_dup(name->str, name->len);
- ZVAL_STRINGL(&fname, name->str, name->len, 1);
+ if (zend_hash_str_exists(&PHPDBG_G(registered), lc_name, name->len)) {
+ zval fretval;
+ zend_fcall_info fci;
memset(&fci, 0, sizeof(zend_fcall_info));
+ ZVAL_STRINGL(&fci.function_name, lc_name, name->len);
fci.size = sizeof(zend_fcall_info);
fci.function_table = &PHPDBG_G(registered);
- fci.function_name = &fname;
- fci.symbol_table = EG(active_symbol_table);
- fci.object_ptr = NULL;
- fci.retval_ptr_ptr = &fretval;
+ fci.symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
+ fci.object = NULL;
+ fci.retval = &fretval;
fci.no_separation = 1;
if (name->next) {
zval params;
phpdbg_param_t *next = name->next;
-
+
array_init(&params);
while (next) {
char *buffered = NULL;
-
+
switch (next->type) {
case OP_PARAM:
case COND_PARAM:
case STR_PARAM:
- add_next_index_stringl(
- &params,
- next->str,
- next->len, 1);
+ add_next_index_stringl(&params, next->str, next->len);
break;
-
+
case NUMERIC_PARAM:
add_next_index_long(&params, next->num);
break;
-
+
case METHOD_PARAM:
- spprintf(&buffered, 0, "%s::%s",
- next->method.class, next->method.name);
- add_next_index_string(&params, buffered, 0);
+ spprintf(&buffered, 0, "%s::%s", next->method.class, next->method.name);
+ add_next_index_string(&params, buffered);
break;
-
+
case NUMERIC_METHOD_PARAM:
- spprintf(&buffered, 0, "%s::%s#%ld",
- next->method.class, next->method.name, next->num);
- add_next_index_string(&params, buffered, 0);
+ spprintf(&buffered, 0, "%s::%s#%ld", next->method.class, next->method.name, next->num);
+ add_next_index_string(&params, buffered);
break;
-
+
case NUMERIC_FUNCTION_PARAM:
- spprintf(&buffered, 0, "%s#%ld",
- next->str, next->num);
- add_next_index_string(&params, buffered, 0);
+ spprintf(&buffered, 0, "%s#%ld", next->str, next->num);
+ add_next_index_string(&params, buffered);
break;
-
+
case FILE_PARAM:
- spprintf(&buffered, 0, "%s:%ld",
- next->file.name, next->file.line);
- add_next_index_string(&params, buffered, 0);
+ spprintf(&buffered, 0, "%s:%ld", next->file.name, next->file.line);
+ add_next_index_string(&params, buffered);
break;
-
+
case NUMERIC_FILE_PARAM:
- spprintf(&buffered, 0, "%s:#%ld",
- next->file.name, next->file.line);
- add_next_index_string(&params, buffered, 0);
+ spprintf(&buffered, 0, "%s:#%ld", next->file.name, next->file.line);
+ add_next_index_string(&params, buffered);
break;
-
+
default: {
/* not yet */
}
}
-
- next = next->next;
+
+ next = next->next;
}
zend_fcall_info_args(&fci, &params TSRMLS_CC);
@@ -165,22 +177,24 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ *
fci.param_count = 0;
}
- phpdbg_debug(
- "created %d params from arguments",
- fci.param_count);
+ phpdbg_activate_err_buf(0 TSRMLS_CC);
+ phpdbg_free_err_buf(TSRMLS_C);
- zend_call_function(&fci, NULL TSRMLS_CC);
+ phpdbg_debug("created %d params from arguments", fci.param_count);
- if (fretval) {
- zend_print_zval_r(
- fretval, 0 TSRMLS_CC);
- phpdbg_writeln(EMPTY);
+ if (zend_call_function(&fci, NULL TSRMLS_CC) == SUCCESS) {
+ zend_print_zval_r(&fretval, 0 TSRMLS_CC);
+ phpdbg_out("\n");
+ zval_ptr_dtor(&fretval);
}
- zval_dtor(&fname);
+ zval_dtor(&fci.function_name);
+ efree(lc_name);
return SUCCESS;
- }
+ }
+
+ efree(lc_name);
}
return FAILURE;
@@ -189,7 +203,7 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ *
void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */
{
struct stat sb;
-
+
if (init_file && VCWD_STAT(init_file, &sb) != -1) {
FILE *fp = fopen(init_file, "r");
if (fp) {
@@ -219,8 +233,7 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_
in_code = 0;
code[code_len] = '\0';
{
- zend_eval_stringl(
- code, code_len, NULL, "phpdbginit code" TSRMLS_CC);
+ zend_eval_stringl(code, code_len, NULL, "phpdbginit code" TSRMLS_CC);
}
free(code);
code = NULL;
@@ -243,30 +256,26 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_
}
{
- char *why = NULL;
char *input = phpdbg_read_input(cmd TSRMLS_CC);
phpdbg_param_t stack;
phpdbg_init_param(&stack, STACK_PARAM);
+ phpdbg_activate_err_buf(1 TSRMLS_CC);
+
if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) {
- switch (phpdbg_stack_execute(&stack, &why TSRMLS_CC)) {
+ switch (phpdbg_stack_execute(&stack, 1 /* allow_async_unsafe == 1 */ TSRMLS_CC)) {
case FAILURE:
-// if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
- if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
- phpdbg_error(
- "Unrecognized command in %s:%d: %s, %s!",
- init_file, line, input, why);
- }
-// }
+ phpdbg_activate_err_buf(0 TSRMLS_CC);
+ if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
+ phpdbg_output_err_buf("initfailure", "%b file=\"%s\" line=\"%d\" input=\"%s\"", "Unrecognized command in %s:%d: %s, %b!" TSRMLS_CC, init_file, line, input);
+ }
break;
}
}
- if (why) {
- free(why);
- why = NULL;
- }
+ phpdbg_activate_err_buf(0 TSRMLS_CC);
+ phpdbg_free_err_buf(TSRMLS_C);
phpdbg_stack_free(&stack);
phpdbg_destroy_input(&input TSRMLS_CC);
@@ -282,8 +291,7 @@ next_line:
fclose(fp);
} else {
- phpdbg_error(
- "Failed to open %s for initialization", init_file);
+ phpdbg_error("initfailure", "type=\"openfile\" file=\"%s\"", "Failed to open %s for initialization", init_file);
}
if (free_init) {
@@ -315,8 +323,7 @@ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TS
scan_dir[i] = 0;
}
- asprintf(
- &init_file, "%s/%s", scan_dir, PHPDBG_INIT_FILENAME);
+ asprintf(&init_file, "%s/%s", scan_dir, PHPDBG_INIT_FILENAME);
phpdbg_try_file_init(init_file, strlen(init_file), 1 TSRMLS_CC);
if (i == -1) {
break;
@@ -342,36 +349,38 @@ PHPDBG_COMMAND(exec) /* {{{ */
if ((res_len != PHPDBG_G(exec_len)) || (memcmp(res, PHPDBG_G(exec), res_len) != SUCCESS)) {
if (PHPDBG_G(exec)) {
- phpdbg_notice("Unsetting old execution context: %s", PHPDBG_G(exec));
+ phpdbg_notice("exec", "type=\"unset\" context=\"%s\"", "Unsetting old execution context: %s", PHPDBG_G(exec));
efree(PHPDBG_G(exec));
PHPDBG_G(exec) = NULL;
PHPDBG_G(exec_len) = 0L;
}
if (PHPDBG_G(ops)) {
- phpdbg_notice("Destroying compiled opcodes");
+ phpdbg_notice("exec", "type=\"unsetops\"", "Destroying compiled opcodes");
phpdbg_clean(0 TSRMLS_CC);
}
PHPDBG_G(exec) = res;
PHPDBG_G(exec_len) = res_len;
-
+
+ VCWD_CHDIR_FILE(res);
+
*SG(request_info).argv = PHPDBG_G(exec);
php_hash_environment(TSRMLS_C);
- phpdbg_notice("Set execution context: %s", PHPDBG_G(exec));
+ phpdbg_notice("exec", "type=\"set\" context=\"%s\"", "Set execution context: %s", PHPDBG_G(exec));
if (phpdbg_compile(TSRMLS_C) == FAILURE) {
- phpdbg_error("Failed to compile %s", PHPDBG_G(exec));
+ phpdbg_error("compile", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s", PHPDBG_G(exec));
}
} else {
- phpdbg_notice("Execution context not changed");
+ phpdbg_notice("exec", "type=\"unchanged\"", "Execution context not changed");
}
} else {
- phpdbg_error("Cannot use %s as execution context, not a valid file or symlink", param->str);
+ phpdbg_error("exec", "type=\"invalid\" context=\"%s\"", "Cannot use %s as execution context, not a valid file or symlink", param->str);
}
} else {
- phpdbg_error("Cannot stat %s, ensure the file exists", param->str);
+ phpdbg_error("exec", "type=\"notfound\" context=\"%s\"", "Cannot stat %s, ensure the file exists", param->str);
}
return SUCCESS;
} /* }}} */
@@ -381,27 +390,23 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */
zend_file_handle fh;
if (!PHPDBG_G(exec)) {
- phpdbg_error("No execution context");
+ phpdbg_error("inactive", "type=\"nocontext\"", "No execution context");
return SUCCESS;
}
- if (EG(in_execution)) {
- phpdbg_error("Cannot compile while in execution");
+ if (PHPDBG_G(in_execution)) {
+ phpdbg_error("inactive", "type=\"isrunning\"", "Cannot compile while in execution");
return FAILURE;
}
- phpdbg_notice("Attempting compilation of %s", PHPDBG_G(exec));
-
- if (php_stream_open_for_zend_ex(PHPDBG_G(exec), &fh,
- USE_PATH|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC) == SUCCESS) {
-
+ if (php_stream_open_for_zend_ex(PHPDBG_G(exec), &fh, USE_PATH|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC) == SUCCESS) {
PHPDBG_G(ops) = zend_compile_file(&fh, ZEND_INCLUDE TSRMLS_CC);
zend_destroy_file_handle(&fh TSRMLS_CC);
- phpdbg_notice("Success");
+ phpdbg_notice("compile", "context=\"%s\"", "Successful compilation of %s", PHPDBG_G(exec));
return SUCCESS;
} else {
- phpdbg_error("Could not open file %s", PHPDBG_G(exec));
+ phpdbg_error("compile", "type=\"openfailure\" context=\"%s\"", "Could not open file %s", PHPDBG_G(exec));
}
return FAILURE;
@@ -409,7 +414,7 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */
PHPDBG_COMMAND(step) /* {{{ */
{
- if (EG(in_execution)) {
+ if (PHPDBG_G(in_execution)) {
PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
}
@@ -423,24 +428,19 @@ PHPDBG_COMMAND(continue) /* {{{ */
PHPDBG_COMMAND(until) /* {{{ */
{
- if (!EG(in_execution)) {
- phpdbg_error("Not executing");
+ if (!PHPDBG_G(in_execution)) {
+ phpdbg_error("inactive", "type=\"noexec\"", "Not executing");
return SUCCESS;
}
PHPDBG_G(flags) |= PHPDBG_IN_UNTIL;
{
- uint32_t next = 0,
- self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes);
- zend_op *opline = &EG(active_op_array)->opcodes[self];
-
- for (next = self; next < EG(active_op_array)->last; next++) {
- if (EG(active_op_array)->opcodes[next].lineno != opline->lineno) {
- zend_hash_index_update(
- &PHPDBG_G(seek),
- (zend_ulong) &EG(active_op_array)->opcodes[next],
- &EG(active_op_array)->opcodes[next],
- sizeof(zend_op), NULL);
+ const zend_op *opline = EG(current_execute_data)->opline;
+ const zend_op_array *op_array = &EG(current_execute_data)->func->op_array;
+
+ while (++opline < op_array->opcodes + op_array->last) {
+ if (opline->lineno != EG(current_execute_data)->opline->lineno) {
+ zend_hash_index_update_ptr(&PHPDBG_G(seek), (zend_ulong) opline, (void *) opline);
break;
}
}
@@ -449,68 +449,46 @@ PHPDBG_COMMAND(until) /* {{{ */
return PHPDBG_UNTIL;
} /* }}} */
+static void phpdbg_seek_to_end(TSRMLS_D) {
+ const zend_op *opline = EG(current_execute_data)->opline;
+ const zend_op_array *op_array = &EG(current_execute_data)->func->op_array - 1;
+
+ while (++opline < op_array->opcodes + op_array->last) {
+ switch (opline->opcode) {
+ case ZEND_RETURN:
+ case ZEND_THROW:
+ case ZEND_EXIT:
+#ifdef ZEND_YIELD
+ case ZEND_YIELD:
+#endif
+ zend_hash_index_update_ptr(&PHPDBG_G(seek), (zend_ulong) opline, (void *) opline);
+ return;
+ }
+ }
+}
+
PHPDBG_COMMAND(finish) /* {{{ */
{
- if (!EG(in_execution)) {
- phpdbg_error("Not executing");
+ if (!PHPDBG_G(in_execution)) {
+ phpdbg_error("inactive", "type=\"noexec\"", "Not executing");
return SUCCESS;
}
PHPDBG_G(flags) |= PHPDBG_IN_FINISH;
- {
- uint32_t next = 0,
- self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes);
-
- for (next = self; next < EG(active_op_array)->last; next++) {
- switch (EG(active_op_array)->opcodes[next].opcode) {
- case ZEND_RETURN:
- case ZEND_THROW:
- case ZEND_EXIT:
-#ifdef ZEND_YIELD
- case ZEND_YIELD:
-#endif
- zend_hash_index_update(
- &PHPDBG_G(seek),
- (zend_ulong) &EG(active_op_array)->opcodes[next],
- &EG(active_op_array)->opcodes[next],
- sizeof(zend_op), NULL);
- break;
- }
- }
- }
+ phpdbg_seek_to_end(TSRMLS_C);
return PHPDBG_FINISH;
} /* }}} */
PHPDBG_COMMAND(leave) /* {{{ */
{
- if (!EG(in_execution)) {
- phpdbg_error("Not executing");
+ if (!PHPDBG_G(in_execution)) {
+ phpdbg_error("inactive", "type=\"noexec\"", "Not executing");
return SUCCESS;
}
PHPDBG_G(flags) |= PHPDBG_IN_LEAVE;
- {
- uint32_t next = 0,
- self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes);
-
- for (next = self; next < EG(active_op_array)->last; next++) {
- switch (EG(active_op_array)->opcodes[next].opcode) {
- case ZEND_RETURN:
- case ZEND_THROW:
- case ZEND_EXIT:
-#ifdef ZEND_YIELD
- case ZEND_YIELD:
-#endif
- zend_hash_index_update(
- &PHPDBG_G(seek),
- (zend_ulong) &EG(active_op_array)->opcodes[next],
- &EG(active_op_array)->opcodes[next],
- sizeof(zend_op), NULL);
- break;
- }
- }
- }
+ phpdbg_seek_to_end(TSRMLS_C);
return PHPDBG_LEAVE;
} /* }}} */
@@ -518,8 +496,10 @@ PHPDBG_COMMAND(leave) /* {{{ */
PHPDBG_COMMAND(frame) /* {{{ */
{
if (!param) {
- phpdbg_notice("Currently in frame #%d", PHPDBG_G(frame).num);
- } else phpdbg_switch_frame(param->num TSRMLS_CC);
+ phpdbg_notice("frame", "id=\"%d\"", "Currently in frame #%d", PHPDBG_G(frame).num);
+ } else {
+ phpdbg_switch_frame(param->num TSRMLS_CC);
+ }
return SUCCESS;
} /* }}} */
@@ -527,89 +507,65 @@ PHPDBG_COMMAND(frame) /* {{{ */
static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */
{
zend_fcall_info fci;
-
- zval fname,
- *trace,
- exception;
+ zval trace;
/* get filename and linenumber before unsetting exception */
const char *filename = zend_get_executed_filename(TSRMLS_C);
uint32_t lineno = zend_get_executed_lineno(TSRMLS_C);
- /* copy exception */
- exception = *EG(exception);
- zval_copy_ctor(&exception);
- EG(exception) = NULL;
-
- phpdbg_error(
- "Uncaught %s!",
- Z_OBJCE(exception)->name);
-
/* call __toString */
- ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring")-1, 1);
+ ZVAL_STRINGL(&fci.function_name, "__tostring", sizeof("__tostring") - 1);
fci.size = sizeof(fci);
- fci.function_table = &Z_OBJCE(exception)->function_table;
- fci.function_name = &fname;
+ fci.function_table = &EG(exception)->ce->function_table;
fci.symbol_table = NULL;
- fci.object_ptr = &exception;
- fci.retval_ptr_ptr = &trace;
+ fci.object = EG(exception);
+ fci.retval = &trace;
fci.param_count = 0;
fci.params = NULL;
fci.no_separation = 1;
- zend_call_function(&fci, NULL TSRMLS_CC);
+ if (zend_call_function(&fci, NULL TSRMLS_CC) == SUCCESS) {
+ phpdbg_writeln("exception", "name=\"%s\" trace=\"%.*s\"", "Uncaught %s!\n%.*s", EG(exception)->ce->name->val, Z_STRLEN(trace), Z_STRVAL(trace));
- if (trace) {
- phpdbg_writeln(
- "Uncaught %s", Z_STRVAL_P(trace));
- /* remember to dtor trace */
zval_ptr_dtor(&trace);
+ } else {
+ phpdbg_error("exception", "name=\"%s\"" "Uncaught %s!", EG(exception)->ce->name->val);
}
/* output useful information about address */
- phpdbg_writeln(
- "Stacked entered at %p in %s on line %u",
- EG(active_op_array)->opcodes, filename, lineno);
+ phpdbg_writeln("exception", "opline=\"%p\" file=\"%s\" line=\"%u\"", "Stack entered at %p in %s on line %u", EG(current_execute_data)->func->op_array.opcodes, filename, lineno);
- zval_dtor(&fname);
- zval_dtor(&exception);
+ zval_dtor(&fci.function_name);
+ zend_clear_exception(TSRMLS_C);
} /* }}} */
PHPDBG_COMMAND(run) /* {{{ */
{
- if (EG(in_execution)) {
- phpdbg_error("Cannot start another execution while one is in progress");
+ if (PHPDBG_G(in_execution)) {
+ phpdbg_error("inactive", "type=\"isrunning\"", "Cannot start another execution while one is in progress");
return SUCCESS;
}
if (PHPDBG_G(ops) || PHPDBG_G(exec)) {
- zend_op **orig_opline = EG(opline_ptr);
- zend_op_array *orig_op_array = EG(active_op_array);
- zval **orig_retval_ptr = EG(return_value_ptr_ptr);
- zend_bool restore = 1;
zend_execute_data *ex = EG(current_execute_data);
-
+ zend_bool restore = 1;
+
if (!PHPDBG_G(ops)) {
if (phpdbg_compile(TSRMLS_C) == FAILURE) {
- phpdbg_error("Failed to compile %s, cannot run", PHPDBG_G(exec));
+ phpdbg_error("compile", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s, cannot run", PHPDBG_G(exec));
goto out;
}
}
- EG(active_op_array) = PHPDBG_G(ops);
- EG(return_value_ptr_ptr) = &PHPDBG_G(retval);
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
-
/* clean up from last execution */
if (ex && ex->symbol_table) {
- zend_hash_clean(ex->symbol_table);
+ zend_hash_clean(&ex->symbol_table->ht);
+ } else {
+ zend_rebuild_symbol_table(TSRMLS_C);
}
/* clean seek state */
PHPDBG_G(flags) &= ~PHPDBG_SEEK_MASK;
- zend_hash_clean(
- &PHPDBG_G(seek));
+ zend_hash_clean(&PHPDBG_G(seek));
/* reset hit counters */
phpdbg_reset_breakpoints(TSRMLS_C);
@@ -619,7 +575,7 @@ PHPDBG_COMMAND(run) /* {{{ */
int argc = 0;
int i;
char *argv_str = strtok(param->str, " ");
-
+
while (argv_str) {
if (argc >= 4 && argc == (argc & -argc)) {
argv = erealloc(argv, (argc * 2 + 1) * sizeof(char *));
@@ -635,38 +591,35 @@ PHPDBG_COMMAND(run) /* {{{ */
efree(SG(request_info).argv);
SG(request_info).argv = erealloc(argv, ++argc * sizeof(char *));
SG(request_info).argc = argc;
-
+
php_hash_environment(TSRMLS_C);
}
zend_try {
- php_output_activate(TSRMLS_C);
PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE;
- zend_execute(EG(active_op_array) TSRMLS_CC);
+ zend_execute(PHPDBG_G(ops), &PHPDBG_G(retval) TSRMLS_CC);
PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE;
- php_output_deactivate(TSRMLS_C);
+ phpdbg_notice("stop", "type=\"normal\"", "Script ended normally");
} zend_catch {
- EG(active_op_array) = orig_op_array;
- EG(opline_ptr) = orig_opline;
- EG(return_value_ptr_ptr) = orig_retval_ptr;
-
+ PHPDBG_G(in_execution) = 0;
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
- phpdbg_error("Caught exit/error from VM");
+ phpdbg_error("stop", "type=\"bailout\"", "Caught exit/error from VM");
restore = 0;
}
} zend_end_try();
+ if (PHPDBG_G(socket_fd) != -1) {
+ close(PHPDBG_G(socket_fd));
+ PHPDBG_G(socket_fd) = -1;
+ }
+
if (restore) {
if (EG(exception)) {
phpdbg_handle_exception(TSRMLS_C);
}
-
- EG(active_op_array) = orig_op_array;
- EG(opline_ptr) = orig_opline;
- EG(return_value_ptr_ptr) = orig_retval_ptr;
}
} else {
- phpdbg_error("Nothing to execute!");
+ phpdbg_error("inactive", "type=\"nocontext\"", "Nothing to execute!");
}
out:
@@ -674,31 +627,56 @@ out:
return SUCCESS;
} /* }}} */
+int phpdbg_output_ev_variable(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv TSRMLS_DC) {
+ phpdbg_notice("eval", "variable=\"%.*s\"", "Printing variable %.*s", (int) len, name);
+ phpdbg_xml("<eval %r>");
+ zend_print_zval_r(zv, 0 TSRMLS_CC);
+ phpdbg_xml("</eval>");
+ phpdbg_out("\n");
+
+ efree(name);
+ efree(keyname);
+
+ return SUCCESS;
+}
+
PHPDBG_COMMAND(ev) /* {{{ */
{
- zend_bool stepping = ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING)==PHPDBG_IS_STEPPING);
+ zend_bool stepping = ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING) == PHPDBG_IS_STEPPING);
zval retval;
+ if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) {
+ phpdbg_try_access {
+ phpdbg_parse_variable(param->str, param->len, &EG(symbol_table).ht, 0, phpdbg_output_ev_variable, 0 TSRMLS_CC);
+ } phpdbg_catch_access {
+ phpdbg_error("signalsegv", "", "Could not fetch data, invalid data source");
+ } phpdbg_end_try_access();
+ return SUCCESS;
+ }
+
if (!(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) {
- PHPDBG_G(flags) &= ~ PHPDBG_IS_STEPPING;
+ PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING;
}
/* disable stepping while eval() in progress */
PHPDBG_G(flags) |= PHPDBG_IN_EVAL;
zend_try {
- if (zend_eval_stringl(param->str, param->len,
- &retval, "eval()'d code" TSRMLS_CC) == SUCCESS) {
- zend_print_zval_r(
- &retval, 0 TSRMLS_CC);
- phpdbg_writeln(EMPTY);
- zval_dtor(&retval);
+ if (zend_eval_stringl(param->str, param->len, &retval, "eval()'d code" TSRMLS_CC) == SUCCESS) {
+ phpdbg_xml("<eval %r>");
+ if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
+ zval *zvp = &retval;
+ phpdbg_xml_var_dump(zvp TSRMLS_CC);
+ }
+ zend_print_zval_r(&retval, 0 TSRMLS_CC);
+ phpdbg_xml("</eval>");
+ phpdbg_out("\n");
+ zval_ptr_dtor(&retval);
}
} zend_end_try();
PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL;
/* switch stepping back on */
- if (stepping &&
- !(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) {
+ if (stepping && !(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) {
PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
}
@@ -709,8 +687,8 @@ PHPDBG_COMMAND(ev) /* {{{ */
PHPDBG_COMMAND(back) /* {{{ */
{
- if (!EG(in_execution)) {
- phpdbg_error("Not executing!");
+ if (!PHPDBG_G(in_execution)) {
+ phpdbg_error("inactive", "type=\"noexec\"", "Not executing!");
return SUCCESS;
}
@@ -725,62 +703,54 @@ PHPDBG_COMMAND(back) /* {{{ */
PHPDBG_COMMAND(print) /* {{{ */
{
- phpdbg_writeln(SEPARATE);
- phpdbg_notice("Execution Context Information");
+ phpdbg_out("Execution Context Information\n\n");
+ phpdbg_xml("<printinfo %r>");
#ifdef HAVE_LIBREADLINE
- phpdbg_writeln("Readline\tyes");
+ phpdbg_writeln("print", "readline=\"yes\"", "Readline yes");
#else
- phpdbg_writeln("Readline\tno");
+ phpdbg_writeln("print", "readline=\"no\"", "Readline no");
#endif
#ifdef HAVE_LIBEDIT
- phpdbg_writeln("Libedit\t\tyes");
+ phpdbg_writeln("print", "libedit=\"yes\"", "Libedit yes");
#else
- phpdbg_writeln("Libedit\t\tno");
+ phpdbg_writeln("print", "libedit=\"no\"", "Libedit no");
#endif
- phpdbg_writeln("Exec\t\t%s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none");
- phpdbg_writeln("Compiled\t%s", PHPDBG_G(ops) ? "yes" : "no");
- phpdbg_writeln("Stepping\t%s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off");
- phpdbg_writeln("Quietness\t%s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off");
- phpdbg_writeln("Oplog\t\t%s", PHPDBG_G(oplog) ? "on" : "off");
+ phpdbg_writeln("print", "context=\"%s\"", "Exec %s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none");
+ phpdbg_writeln("print", "compiled=\"%s\"", "Compiled %s", PHPDBG_G(ops) ? "yes" : "no");
+ phpdbg_writeln("print", "stepping=\"%s\"", "Stepping %s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off");
+ phpdbg_writeln("print", "quiet=\"%s\"", "Quietness %s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off");
+ phpdbg_writeln("print", "oplog=\"%s\"", "Oplog %s", PHPDBG_G(oplog) ? "on" : "off");
if (PHPDBG_G(ops)) {
- phpdbg_writeln("Opcodes\t\t%d", PHPDBG_G(ops)->last);
-
- if (PHPDBG_G(ops)->last_var) {
- phpdbg_writeln("Variables\t%d", PHPDBG_G(ops)->last_var-1);
- } else {
- phpdbg_writeln("Variables\tNone");
- }
+ phpdbg_writeln("print", "ops=\"%d\"", "Opcodes %d", PHPDBG_G(ops)->last);
+ phpdbg_writeln("print", "vars=\"%d\"", "Variables %d", PHPDBG_G(ops)->last_var ? PHPDBG_G(ops)->last_var - 1 : 0);
}
- phpdbg_writeln("Executing\t%s", EG(in_execution) ? "yes" : "no");
- if (EG(in_execution)) {
- phpdbg_writeln("VM Return\t%d", PHPDBG_G(vmret));
+ phpdbg_writeln("print", "executing=\"%d\"", "Executing %s", PHPDBG_G(in_execution) ? "yes" : "no");
+ if (PHPDBG_G(in_execution)) {
+ phpdbg_writeln("print", "vmret=\"%d\"", "VM Return %d", PHPDBG_G(vmret));
}
- phpdbg_writeln("Classes\t\t%d", zend_hash_num_elements(EG(class_table)));
- phpdbg_writeln("Functions\t%d", zend_hash_num_elements(EG(function_table)));
- phpdbg_writeln("Constants\t%d", zend_hash_num_elements(EG(zend_constants)));
- phpdbg_writeln("Included\t%d", zend_hash_num_elements(&EG(included_files)));
-
- phpdbg_writeln(SEPARATE);
+ phpdbg_writeln("print", "classes=\"%d\"", "Classes %d", zend_hash_num_elements(EG(class_table)));
+ phpdbg_writeln("print", "functions=\"%d\"", "Functions %d", zend_hash_num_elements(EG(function_table)));
+ phpdbg_writeln("print", "constants=\"%d\"", "Constants %d", zend_hash_num_elements(EG(zend_constants)));
+ phpdbg_writeln("print", "includes=\"%d\"", "Included %d", zend_hash_num_elements(&EG(included_files)));
+ phpdbg_xml("</printinfo>");
return SUCCESS;
} /* }}} */
PHPDBG_COMMAND(info) /* {{{ */
{
- phpdbg_error(
- "No information command selected!");
+ phpdbg_error("info", "type=\"toofewargs\" expected=\"1\"", "No information command selected!");
return SUCCESS;
} /* }}} */
PHPDBG_COMMAND(set) /* {{{ */
{
- phpdbg_error(
- "No set command selected!");
+ phpdbg_error("set", "type=\"toofewargs\" expected=\"1\"", "No set command selected!");
return SUCCESS;
} /* }}} */
@@ -789,8 +759,8 @@ PHPDBG_COMMAND(break) /* {{{ */
{
if (!param) {
phpdbg_set_breakpoint_file(
- zend_get_executed_filename(TSRMLS_C),
- zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC);
+ zend_get_executed_filename(TSRMLS_C),
+ zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC);
} else switch (param->type) {
case ADDR_PARAM:
phpdbg_set_breakpoint_opline(param->addr TSRMLS_CC);
@@ -799,7 +769,7 @@ PHPDBG_COMMAND(break) /* {{{ */
if (PHPDBG_G(exec)) {
phpdbg_set_breakpoint_file(phpdbg_current_file(TSRMLS_C), param->num TSRMLS_CC);
} else {
- phpdbg_error("Execution context not set!");
+ phpdbg_error("inactive", "type=\"noexec\"", "Execution context not set!");
}
break;
case METHOD_PARAM:
@@ -837,42 +807,226 @@ PHPDBG_COMMAND(sh) /* {{{ */
{
FILE *fd = NULL;
if ((fd=VCWD_POPEN((char*)param->str, "w"))) {
- /* do something perhaps ?? do we want input ?? */
+ /* TODO: do something perhaps ?? do we want input ?? */
fclose(fd);
} else {
- phpdbg_error(
- "Failed to execute %s", param->str);
+ phpdbg_error("sh", "type=\"failure\" smd=\"%s\"", "Failed to execute %s", param->str);
+ }
+
+ return SUCCESS;
+} /* }}} */
+
+static int add_module_info(zend_module_entry *module TSRMLS_DC) {
+ phpdbg_write("module", "name=\"%s\"", "%s\n", module->name);
+ return 0;
+}
+
+static int add_zendext_info(zend_extension *ext TSRMLS_DC) {
+ phpdbg_write("extension", "name=\"%s\"", "%s\n", ext->name);
+ return 0;
+}
+
+PHPDBG_API const char *phpdbg_load_module_or_extension(char **path, char **name TSRMLS_DC) {
+ DL_HANDLE handle;
+ char *extension_dir;
+
+ extension_dir = INI_STR("extension_dir");
+
+ if (strchr(*path, '/') != NULL || strchr(*path, DEFAULT_SLASH) != NULL) {
+ /* path is fine */
+ } else if (extension_dir && extension_dir[0]) {
+ char *libpath;
+ int extension_dir_len = strlen(extension_dir);
+ if (IS_SLASH(extension_dir[extension_dir_len-1])) {
+ spprintf(&libpath, 0, "%s%s", extension_dir, *path); /* SAFE */
+ } else {
+ spprintf(&libpath, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, *path); /* SAFE */
+ }
+ efree(*path);
+ *path = libpath;
+ } else {
+ phpdbg_error("dl", "type=\"relpath\"", "Not a full path given or extension_dir ini setting is not set");
+
+ return NULL;
+ }
+
+ handle = DL_LOAD(*path);
+
+ if (!handle) {
+#if PHP_WIN32
+ char *err = GET_DL_ERROR();
+ if (err && *err != "") {
+ phpdbg_error("dl", "type=\"unknown\"", "%s", err);
+ LocalFree(err);
+ } else {
+ phpdbg_error("dl", "type=\"unknown\"", "Unknown reason");
+ }
+#else
+ phpdbg_error("dl", "type=\"unknown\"", "%s", GET_DL_ERROR());
+#endif
+ return NULL;
+ }
+
+#if ZEND_EXTENSIONS_SUPPORT
+ do {
+ zend_extension *new_extension;
+ zend_extension_version_info *extension_version_info;
+
+ extension_version_info = (zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "extension_version_info");
+ if (!extension_version_info) {
+ extension_version_info = (zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "_extension_version_info");
+ }
+ new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "zend_extension_entry");
+ if (!new_extension) {
+ new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "_zend_extension_entry");
+ }
+ if (!extension_version_info || !new_extension) {
+ break;
+ }
+ if (extension_version_info->zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
+ phpdbg_error("dl", "type=\"wrongapi\" extension=\"%s\" apineeded=\"%d\" apiinstalled=\"%d\"", "%s requires Zend Engine API version %d, which does not match the installed Zend Engine API version %d", new_extension->name, extension_version_info->zend_extension_api_no, ZEND_EXTENSION_API_NO);
+
+ goto quit;
+ } else if (strcmp(ZEND_EXTENSION_BUILD_ID, extension_version_info->build_id) && (!new_extension->build_id_check || new_extension->build_id_check(ZEND_EXTENSION_BUILD_ID) != SUCCESS)) {
+ phpdbg_error("dl", "type=\"wrongbuild\" extension=\"%s\" buildneeded=\"%s\" buildinstalled=\"%s\"", "%s was built with configuration %s, whereas running engine is %s", new_extension->name, extension_version_info->build_id, ZEND_EXTENSION_BUILD_ID);
+
+ goto quit;
+ }
+
+ *name = new_extension->name;
+
+ zend_register_extension(new_extension, handle TSRMLS_CC);
+
+ if (new_extension->startup) {
+ if (new_extension->startup(new_extension) != SUCCESS) {
+ phpdbg_error("dl", "type=\"startupfailure\" extension=\"%s\"", "Unable to startup Zend extension %s", new_extension->name);
+
+ goto quit;
+ }
+ zend_append_version_info(new_extension);
+ }
+
+ return "Zend extension";
+ } while (0);
+#endif
+
+ do {
+ zend_module_entry *module_entry;
+ zend_module_entry *(*get_module)(void);
+
+ get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "get_module");
+ if (!get_module) {
+ get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "_get_module");
+ }
+
+ if (!get_module) {
+ break;
+ }
+
+ module_entry = get_module();
+ *name = (char *) module_entry->name;
+
+ if (strcmp(ZEND_EXTENSION_BUILD_ID, module_entry->build_id)) {
+ phpdbg_error("dl", "type=\"wrongbuild\" module=\"%s\" buildneeded=\"%s\" buildinstalled=\"%s\"", "%s was built with configuration %s, whereas running engine is %s", module_entry->name, module_entry->build_id, ZEND_EXTENSION_BUILD_ID);
+
+ goto quit;
+ }
+
+ module_entry->type = MODULE_PERSISTENT;
+ module_entry->module_number = zend_next_free_module();
+ module_entry->handle = handle;
+
+ if ((module_entry = zend_register_module_ex(module_entry TSRMLS_CC)) == NULL) {
+ phpdbg_error("dl", "type=\"registerfailure\" module=\"%s\"", "Unable to register module %s", module_entry->name);
+
+ goto quit;
+ }
+
+ if (zend_startup_module_ex(module_entry TSRMLS_CC) == FAILURE) {
+ phpdbg_error("dl", "type=\"startupfailure\" module=\"%s\"", "Unable to startup module %s", module_entry->name);
+
+ goto quit;
+ }
+
+ if (module_entry->request_startup_func) {
+ if (module_entry->request_startup_func(MODULE_PERSISTENT, module_entry->module_number TSRMLS_CC) == FAILURE) {
+ phpdbg_error("dl", "type=\"initfailure\" module=\"%s\"", "Unable to initialize module %s", module_entry->name);
+
+ goto quit;
+ }
+ }
+
+ return "module";
+ } while (0);
+
+ phpdbg_error("dl", "type=\"nophpso\"", "This shared object is nor a Zend extension nor a module");
+
+quit:
+ DL_UNLOAD(handle);
+ return NULL;
+}
+
+PHPDBG_COMMAND(dl) /* {{{ */
+{
+ const char *type;
+ char *name, *path;
+
+ if (!param || param->type == EMPTY_PARAM) {
+ phpdbg_notice("dl", "extensiontype=\"Zend extension\"", "Zend extensions");
+ zend_llist_apply(&zend_extensions, (llist_apply_func_t) add_zendext_info TSRMLS_CC);
+ phpdbg_out("\n");
+ phpdbg_notice("dl", "extensiontype=\"module\"", "Modules");
+ zend_hash_apply(&module_registry, (apply_func_t) add_module_info TSRMLS_CC);
+ } else switch (param->type) {
+ case STR_PARAM:
+#ifdef HAVE_LIBDL
+ path = estrndup(param->str, param->len);
+
+ phpdbg_activate_err_buf(1 TSRMLS_CC);
+ if ((type = phpdbg_load_module_or_extension(&path, &name TSRMLS_CC)) == NULL) {
+ phpdbg_error("dl", "path=\"%s\" %b", "Could not load %s, not found or invalid zend extension / module: %b", path);
+ efree(name);
+ } else {
+ phpdbg_notice("dl", "extensiontype=\"%s\" name=\"%s\" path=\"%s\"", "Successfully loaded the %s %s at path %s", type, name, path);
+ }
+ phpdbg_activate_err_buf(0 TSRMLS_CC);
+ phpdbg_free_err_buf(TSRMLS_C);
+ efree(path);
+#else
+ phpdbg_error("dl", "type=\"unsupported\" path=\"%.*s\"", "Cannot dynamically load %.*s - dynamic modules are not supported", (int) param->len, param->str);
+#endif
+ break;
+
+ phpdbg_default_switch_case();
}
-
+
return SUCCESS;
} /* }}} */
PHPDBG_COMMAND(source) /* {{{ */
{
struct stat sb;
-
+
if (VCWD_STAT(param->str, &sb) != -1) {
phpdbg_try_file_init(param->str, param->len, 0 TSRMLS_CC);
} else {
- phpdbg_error(
- "Failed to stat %s, file does not exist", param->str);
+ phpdbg_error("source", "type=\"notfound\" file=\"%s\"", "Failed to stat %s, file does not exist", param->str);
}
-
+
return SUCCESS;
} /* }}} */
PHPDBG_COMMAND(export) /* {{{ */
{
FILE *handle = VCWD_FOPEN(param->str, "w+");
-
+
if (handle) {
phpdbg_export_breakpoints(handle TSRMLS_CC);
fclose(handle);
} else {
- phpdbg_error(
- "Failed to open or create %s, check path and permissions", param->str);
+ phpdbg_error("export", "type=\"openfailure\" file=\"%s\"", "Failed to open or create %s, check path and permissions", param->str);
}
-
+
return SUCCESS;
} /* }}} */
@@ -882,20 +1036,17 @@ PHPDBG_COMMAND(register) /* {{{ */
char *lcname = zend_str_tolower_dup(param->str, param->len);
size_t lcname_len = strlen(lcname);
- if (!zend_hash_exists(&PHPDBG_G(registered), lcname, lcname_len+1)) {
- if (zend_hash_find(EG(function_table), lcname, lcname_len+1, (void**) &function) == SUCCESS) {
- zend_hash_update(
- &PHPDBG_G(registered), lcname, lcname_len+1, (void*)&function, sizeof(zend_function), NULL);
+ if (!zend_hash_str_exists(&PHPDBG_G(registered), lcname, lcname_len)) {
+ if ((function = zend_hash_str_find_ptr(EG(function_table), lcname, lcname_len))) {
+ zend_hash_str_update_ptr(&PHPDBG_G(registered), lcname, lcname_len, function);
function_add_ref(function);
- phpdbg_notice(
- "Registered %s", lcname);
+ phpdbg_notice("register", "function=\"%s\"", "Registered %s", lcname);
} else {
- phpdbg_error("The requested function (%s) could not be found", param->str);
+ phpdbg_error("register", "type=\"notfoundc\" function=\"%s\"", "The requested function (%s) could not be found", param->str);
}
} else {
- phpdbg_error(
- "The requested name (%s) is already in use", lcname);
+ phpdbg_error("register", "type=\"inuse\" function=\"%s\"", "The requested name (%s) is already in use", lcname);
}
efree(lcname);
@@ -915,38 +1066,44 @@ PHPDBG_COMMAND(quit) /* {{{ */
PHPDBG_COMMAND(clean) /* {{{ */
{
- if (EG(in_execution)) {
- phpdbg_error("Cannot clean environment while executing");
+ if (PHPDBG_G(in_execution)) {
+ phpdbg_error("inactive", "type=\"isrunning\"", "Cannot clean environment while executing");
return SUCCESS;
}
- phpdbg_notice("Cleaning Execution Environment");
+ phpdbg_out("Cleaning Execution Environment\n");
+ phpdbg_xml("<cleaninfo %r>");
- phpdbg_writeln("Classes\t\t\t%d", zend_hash_num_elements(EG(class_table)));
- phpdbg_writeln("Functions\t\t%d", zend_hash_num_elements(EG(function_table)));
- phpdbg_writeln("Constants\t\t%d", zend_hash_num_elements(EG(zend_constants)));
- phpdbg_writeln("Includes\t\t%d", zend_hash_num_elements(&EG(included_files)));
+ phpdbg_writeln("clean", "classes=\"%d\"", "Classes %d", zend_hash_num_elements(EG(class_table)));
+ phpdbg_writeln("clean", "functions=\"%d\"", "Functions %d", zend_hash_num_elements(EG(function_table)));
+ phpdbg_writeln("clean", "constants=\"%d\"", "Constants %d", zend_hash_num_elements(EG(zend_constants)));
+ phpdbg_writeln("clean", "includes=\"%d\"", "Includes %d", zend_hash_num_elements(&EG(included_files)));
phpdbg_clean(1 TSRMLS_CC);
+ phpdbg_xml("</cleaninfo>");
+
return SUCCESS;
} /* }}} */
PHPDBG_COMMAND(clear) /* {{{ */
{
- phpdbg_notice("Clearing Breakpoints");
-
- phpdbg_writeln("File\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]));
- phpdbg_writeln("Functions\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]));
- phpdbg_writeln("Methods\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]));
- phpdbg_writeln("Oplines\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]));
- phpdbg_writeln("File oplines\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE]));
- phpdbg_writeln("Function oplines\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]));
- phpdbg_writeln("Method oplines\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]));
- phpdbg_writeln("Conditionals\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]));
+ phpdbg_out("Clearing Breakpoints\n");
+ phpdbg_xml("<clearinfo %r>");
+
+ phpdbg_writeln("clear", "files=\"%d\"", "File %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]));
+ phpdbg_writeln("clear", "functions=\"%d\"", "Functions %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]));
+ phpdbg_writeln("clear", "methods=\"%d\"", "Methods %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]));
+ phpdbg_writeln("clear", "oplines=\"%d\"", "Oplines %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]));
+ phpdbg_writeln("clear", "fileoplines=\"%d\"", "File oplines %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE]));
+ phpdbg_writeln("clear", "functionoplines=\"%d\"", "Function oplines %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]));
+ phpdbg_writeln("clear", "methodoplines=\"%d\"", "Method oplines %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]));
+ phpdbg_writeln("clear", "eval=\"%d\"", "Conditionals %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]));
phpdbg_clear_breakpoints(TSRMLS_C);
+ phpdbg_xml("</clearinfo>");
+
return SUCCESS;
} /* }}} */
@@ -981,7 +1138,7 @@ PHPDBG_COMMAND(watch) /* {{{ */
} else switch (param->type) {
case STR_PARAM:
if (phpdbg_create_var_watchpoint(param->str, param->len TSRMLS_CC) != FAILURE) {
- phpdbg_notice("Set watchpoint on %.*s", (int)param->len, param->str);
+ phpdbg_notice("watch", "variable=\"%.*s\"", "Set watchpoint on %.*s", (int) param->len, param->str);
}
break;
@@ -991,10 +1148,9 @@ PHPDBG_COMMAND(watch) /* {{{ */
return SUCCESS;
} /* }}} */
-int phpdbg_interactive(TSRMLS_D) /* {{{ */
+int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC) /* {{{ */
{
int ret = SUCCESS;
- char *why = NULL;
char *input = NULL;
phpdbg_param_t stack;
@@ -1007,42 +1163,49 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */
phpdbg_init_param(&stack, STACK_PARAM);
if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) {
- switch (ret = phpdbg_stack_execute(&stack, &why TSRMLS_CC)) {
+ phpdbg_activate_err_buf(1 TSRMLS_CC);
+
+#ifdef PHP_WIN32
+#define PARA ((phpdbg_param_t *)stack.next)->type
+ if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE && (RUN_PARAM == PARA || EVAL_PARAM == PARA)) {
+ sigio_watcher_start();
+ }
+#endif
+ switch (ret = phpdbg_stack_execute(&stack, allow_async_unsafe TSRMLS_CC)) {
case FAILURE:
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
- if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
- if (why) {
- phpdbg_error("%s", why);
- }
+ if (!allow_async_unsafe || phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
+ phpdbg_output_err_buf(NULL, "%b", "%b" TSRMLS_CC);
}
}
-
- if (why) {
- free(why);
- why = NULL;
- }
break;
case PHPDBG_LEAVE:
case PHPDBG_FINISH:
case PHPDBG_UNTIL:
case PHPDBG_NEXT: {
- if (!EG(in_execution) && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
- phpdbg_error("Not running");
+ phpdbg_activate_err_buf(0 TSRMLS_CC);
+ phpdbg_free_err_buf(TSRMLS_C);
+ if (!PHPDBG_G(in_execution) && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
+ phpdbg_error("command", "type=\"noexec\"", "Not running");
}
goto out;
}
}
- }
- if (why) {
- free(why);
- why = NULL;
+ phpdbg_activate_err_buf(0 TSRMLS_CC);
+ phpdbg_free_err_buf(TSRMLS_C);
+#ifdef PHP_WIN32
+ if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE && (RUN_PARAM == PARA || EVAL_PARAM == PARA)) {
+ sigio_watcher_stop();
+ }
+#undef PARA
+#endif
}
phpdbg_stack_free(&stack);
phpdbg_destroy_input(&input TSRMLS_CC);
-
+ PHPDBG_G(req_id) = 0;
} while ((input = phpdbg_read_input(NULL TSRMLS_CC)));
}
@@ -1050,13 +1213,10 @@ out:
if (input) {
phpdbg_stack_free(&stack);
phpdbg_destroy_input(&input TSRMLS_CC);
+ PHPDBG_G(req_id) = 0;
}
- if (why) {
- free(why);
- }
-
- if (EG(in_execution)) {
+ if (PHPDBG_G(in_execution)) {
phpdbg_restore_frame(TSRMLS_C);
}
@@ -1083,138 +1243,45 @@ void phpdbg_clean(zend_bool full TSRMLS_DC) /* {{{ */
}
} /* }}} */
-static inline zend_execute_data *phpdbg_create_execute_data(zend_op_array *op_array, zend_bool nested TSRMLS_DC) /* {{{ */
-{
-#if PHP_VERSION_ID >= 50500
- return zend_create_execute_data_from_op_array(op_array, nested TSRMLS_CC);
-#else
-
-#undef EX
-#define EX(element) execute_data->element
-#undef EX_CV
-#define EX_CV(var) EX(CVs)[var]
-#undef EX_CVs
-#define EX_CVs() EX(CVs)
-#undef EX_T
-#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))
-#undef EX_Ts
-#define EX_Ts() EX(Ts)
-
- zend_execute_data *execute_data = (zend_execute_data *)zend_vm_stack_alloc(
- ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) +
- ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)) +
- ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T TSRMLS_CC);
-
- EX(CVs) = (zval***)((char*)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)));
- memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
- EX(Ts) = (temp_variable *)(((char*)EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)));
- EX(fbc) = NULL;
- EX(called_scope) = NULL;
- EX(object) = NULL;
- EX(old_error_reporting) = NULL;
- EX(op_array) = op_array;
- EX(symbol_table) = EG(active_symbol_table);
- EX(prev_execute_data) = EG(current_execute_data);
- EG(current_execute_data) = execute_data;
- EX(nested) = nested;
-
- if (!op_array->run_time_cache && op_array->last_cache_slot) {
- op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
- }
-
- if (op_array->this_var != -1 && EG(This)) {
- Z_ADDREF_P(EG(This)); /* For $this pointer */
- if (!EG(active_symbol_table)) {
- EX_CV(op_array->this_var) = (zval**)EX_CVs() + (op_array->last_var + op_array->this_var);
- *EX_CV(op_array->this_var) = EG(This);
- } else {
- if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void**)&EX_CV(op_array->this_var))==FAILURE) {
- Z_DELREF_P(EG(This));
- }
- }
- }
-
- EX(opline) = op_array->opcodes;
- EG(opline_ptr) = &EX(opline);
-
- EX(function_state).function = (zend_function *) op_array;
- EX(function_state).arguments = NULL;
-
- return execute_data;
-#endif
-} /* }}} */
+#define DO_INTERACTIVE(allow_async_unsafe) do { \
+ if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) { \
+ const char *file_char = zend_get_executed_filename(TSRMLS_C); \
+ zend_string *file = zend_string_init(file_char, strlen(file_char), 0); \
+ phpdbg_list_file(file, 3, zend_get_executed_lineno(TSRMLS_C)-1, zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC); \
+ efree(file); \
+ } \
+ \
+ switch (phpdbg_interactive(allow_async_unsafe TSRMLS_CC)) { \
+ case PHPDBG_LEAVE: \
+ case PHPDBG_FINISH: \
+ case PHPDBG_UNTIL: \
+ case PHPDBG_NEXT:{ \
+ goto next; \
+ } \
+ } \
+} while (0)
-#if PHP_VERSION_ID >= 50500
void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
{
-#else
-void phpdbg_execute_ex(zend_op_array *op_array TSRMLS_DC) /* {{{ */
-{
- long long flags = 0;
- zend_ulong address = 0L;
- zend_execute_data *execute_data;
- zend_bool nested = 0;
-#endif
- zend_bool original_in_execution = EG(in_execution);
+ zend_bool original_in_execution = PHPDBG_G(in_execution);
HashTable vars;
-#if PHP_VERSION_ID < 50500
- if (EG(exception)) {
- return;
- }
-#endif
+ zend_hash_init(&vars, execute_data->func->op_array.last, NULL, NULL, 0);
- EG(in_execution) = 1;
-
-#if PHP_VERSION_ID >= 50500
- if (0) {
-zend_vm_enter:
- execute_data = phpdbg_create_execute_data(EG(active_op_array), 1 TSRMLS_CC);
- }
- zend_hash_init(&vars, EG(active_op_array)->last, NULL, NULL, 0);
-#else
-zend_vm_enter:
- execute_data = phpdbg_create_execute_data(op_array, nested TSRMLS_CC);
- nested = 1;
- zend_hash_init(&vars, EG(active_op_array)->last, NULL, NULL, 0);
-#endif
+ PHPDBG_G(in_execution) = 1;
while (1) {
-
if ((PHPDBG_G(flags) & PHPDBG_BP_RESOLVE_MASK)) {
/* resolve nth opline breakpoints */
- phpdbg_resolve_op_array_breaks(EG(active_op_array) TSRMLS_CC);
+ phpdbg_resolve_op_array_breaks(&execute_data->func->op_array TSRMLS_CC);
}
-
+
#ifdef ZEND_WIN32
if (EG(timed_out)) {
zend_timeout(0);
}
#endif
-#define DO_INTERACTIVE() do { \
- if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) { \
- phpdbg_list_file( \
- zend_get_executed_filename(TSRMLS_C), \
- 3, \
- zend_get_executed_lineno(TSRMLS_C)-1, \
- zend_get_executed_lineno(TSRMLS_C) \
- TSRMLS_CC \
- ); \
- } \
- \
-/* do { */\
- switch (phpdbg_interactive(TSRMLS_C)) { \
- case PHPDBG_LEAVE: \
- case PHPDBG_FINISH: \
- case PHPDBG_UNTIL: \
- case PHPDBG_NEXT:{ \
- goto next; \
- } \
- } \
-/* } while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); */\
-} while (0)
-
/* allow conditional breakpoints and
initialization to access the vm uninterrupted */
if ((PHPDBG_G(flags) & PHPDBG_IN_COND_BP) ||
@@ -1232,8 +1299,7 @@ zend_vm_enter:
if (PHPDBG_G(flags) & PHPDBG_IN_UNTIL) {
if (zend_hash_index_exists(&PHPDBG_G(seek), address)) {
PHPDBG_G(flags) &= ~PHPDBG_IN_UNTIL;
- zend_hash_clean(
- &PHPDBG_G(seek));
+ zend_hash_clean(&PHPDBG_G(seek));
} else {
/* skip possible breakpoints */
goto next;
@@ -1244,8 +1310,7 @@ zend_vm_enter:
if (PHPDBG_G(flags) & PHPDBG_IN_FINISH) {
if (zend_hash_index_exists(&PHPDBG_G(seek), address)) {
PHPDBG_G(flags) &= ~PHPDBG_IN_FINISH;
- zend_hash_clean(
- &PHPDBG_G(seek));
+ zend_hash_clean(&PHPDBG_G(seek));
}
/* skip possible breakpoints */
goto next;
@@ -1255,14 +1320,12 @@ zend_vm_enter:
if (PHPDBG_G(flags) & PHPDBG_IN_LEAVE) {
if (zend_hash_index_exists(&PHPDBG_G(seek), address)) {
PHPDBG_G(flags) &= ~PHPDBG_IN_LEAVE;
- zend_hash_clean(
- &PHPDBG_G(seek));
- phpdbg_notice(
- "Breaking for leave at %s:%u",
+ zend_hash_clean(&PHPDBG_G(seek));
+ phpdbg_notice("breakpoint", "id=\"leave\" file=\"%s\" line=\"%u\"", "Breaking for leave at %s:%u",
zend_get_executed_filename(TSRMLS_C),
zend_get_executed_lineno(TSRMLS_C)
);
- DO_INTERACTIVE();
+ DO_INTERACTIVE(1);
} else {
/* skip possible breakpoints */
goto next;
@@ -1271,18 +1334,17 @@ zend_vm_enter:
}
/* not while in conditionals */
- phpdbg_print_opline_ex(
- execute_data, &vars, 0 TSRMLS_CC);
+ phpdbg_print_opline_ex(execute_data, &vars, 0 TSRMLS_CC);
if (PHPDBG_G(flags) & PHPDBG_IS_STEPPING && (PHPDBG_G(flags) & PHPDBG_STEP_OPCODE || execute_data->opline->lineno != PHPDBG_G(last_line))) {
PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING;
- DO_INTERACTIVE();
+ DO_INTERACTIVE(1);
}
/* check if some watchpoint was hit */
{
if (phpdbg_print_changed_zvals(TSRMLS_C) == SUCCESS) {
- DO_INTERACTIVE();
+ DO_INTERACTIVE(1);
}
}
@@ -1294,42 +1356,82 @@ zend_vm_enter:
&& (brake = phpdbg_find_breakpoint(execute_data TSRMLS_CC))
&& (brake->type != PHPDBG_BREAK_FILE || execute_data->opline->lineno != PHPDBG_G(last_line))) {
phpdbg_hit_breakpoint(brake, 1 TSRMLS_CC);
- DO_INTERACTIVE();
+ DO_INTERACTIVE(1);
}
}
-next:
if (PHPDBG_G(flags) & PHPDBG_IS_SIGNALED) {
- phpdbg_writeln(EMPTY);
- phpdbg_notice("Program received signal SIGINT");
PHPDBG_G(flags) &= ~PHPDBG_IS_SIGNALED;
- DO_INTERACTIVE();
+
+ phpdbg_out("\n");
+ phpdbg_notice("signal", "type=\"SIGINT\"", "Program received signal SIGINT");
+ DO_INTERACTIVE(1);
}
+next:
+
PHPDBG_G(last_line) = execute_data->opline->lineno;
+ /* stupid hack to make zend_do_fcall_common_helper return ZEND_VM_ENTER() instead of recursively calling zend_execute() and eventually segfaulting */
+ if (execute_data->opline->opcode == ZEND_DO_FCALL && execute_data->func->type == ZEND_USER_FUNCTION) {
+ zend_execute_ex = execute_ex;
+ }
PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC);
+ zend_execute_ex = phpdbg_execute_ex;
- if (PHPDBG_G(vmret) > 0) {
- switch (PHPDBG_G(vmret)) {
- case 1:
- EG(in_execution) = original_in_execution;
- zend_hash_destroy(&vars);
- return;
- case 2:
-#if PHP_VERSION_ID < 50500
- op_array = EG(active_op_array);
-#endif
- zend_hash_destroy(&vars);
- goto zend_vm_enter;
- break;
- case 3:
- execute_data = EG(current_execute_data);
- break;
- default:
- break;
+ if (PHPDBG_G(vmret) != 0) {
+ if (PHPDBG_G(vmret) < 0) {
+ zend_hash_destroy(&vars);
+ PHPDBG_G(in_execution) = original_in_execution;
+ return;
+ } else {
+ execute_data = EG(current_execute_data);
}
}
}
zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
} /* }}} */
+
+/* only if *not* interactive and while executing */
+void phpdbg_force_interruption(TSRMLS_D) {
+ zend_execute_data *data = EG(current_execute_data); /* should be always readable if not NULL */
+
+ PHPDBG_G(flags) |= PHPDBG_IN_SIGNAL_HANDLER;
+
+ if (data) {
+ if (data->func) {
+ phpdbg_notice("hardinterrupt", "opline=\"%p\" num=\"%lu\" file=\"%s\" line=\"%u\"", "Current opline: %p (op #%lu) in %s:%u", data->opline, (data->opline - data->func->op_array.opcodes) / sizeof(data->opline), data->func->op_array.filename, data->opline->lineno);
+ } else {
+ phpdbg_notice("hardinterrupt", "opline=\"%p\"", "Current opline: %p (op_array information unavailable)", data->opline);
+ }
+ } else {
+ phpdbg_notice("hardinterrupt", "", "No information available about executing context");
+ }
+
+ DO_INTERACTIVE(0);
+
+next:
+ PHPDBG_G(flags) &= ~PHPDBG_IN_SIGNAL_HANDLER;
+
+ if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) {
+ zend_bailout();
+ }
+}
+
+PHPDBG_COMMAND(eol) /* {{{ */
+{
+ if (!param || param->type == EMPTY_PARAM) {
+ phpdbg_notice("eol", "argument required", "argument required");
+ } else switch (param->type) {
+ case STR_PARAM:
+ if (FAILURE == phpdbg_eol_global_update(param->str TSRMLS_CC)) {
+ phpdbg_notice("eol", "unknown EOL name '%s', give crlf, lf, cr", "unknown EOL name '%s', give crlf, lf, cr", param->str);
+ }
+ break;
+
+ phpdbg_default_switch_case();
+ }
+
+ return SUCCESS;
+} /* }}} */
+
diff --git a/sapi/phpdbg/phpdbg_prompt.h b/sapi/phpdbg/phpdbg_prompt.h
index 0bd03f03bb..94e24df833 100644
--- a/sapi/phpdbg/phpdbg_prompt.h
+++ b/sapi/phpdbg/phpdbg_prompt.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -24,9 +24,11 @@
/* {{{ */
void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TSRMLS_DC);
void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC);
-int phpdbg_interactive(TSRMLS_D);
+int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC);
int phpdbg_compile(TSRMLS_D);
-void phpdbg_clean(zend_bool full TSRMLS_DC); /* }}} */
+void phpdbg_clean(zend_bool full TSRMLS_DC);
+void phpdbg_force_interruption(TSRMLS_D);
+/* }}} */
/* {{{ phpdbg command handlers */
PHPDBG_COMMAND(exec);
@@ -47,12 +49,15 @@ PHPDBG_COMMAND(clean);
PHPDBG_COMMAND(clear);
PHPDBG_COMMAND(help);
PHPDBG_COMMAND(sh);
+PHPDBG_COMMAND(dl);
PHPDBG_COMMAND(set);
PHPDBG_COMMAND(source);
PHPDBG_COMMAND(export);
PHPDBG_COMMAND(register);
PHPDBG_COMMAND(quit);
-PHPDBG_COMMAND(watch); /* }}} */
+PHPDBG_COMMAND(watch);
+PHPDBG_COMMAND(eol);
+PHPDBG_COMMAND(wait); /* }}} */
/* {{{ prompt commands */
extern const phpdbg_command_t phpdbg_prompt_commands[]; /* }}} */
diff --git a/sapi/phpdbg/phpdbg_rinit_hook.c b/sapi/phpdbg/phpdbg_rinit_hook.c
new file mode 100644
index 0000000000..1bf891654d
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_rinit_hook.c
@@ -0,0 +1,101 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Bob Weinand <bwoebi@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "phpdbg_rinit_hook.h"
+#include "php_ini.h"
+#include <errno.h>
+
+ZEND_DECLARE_MODULE_GLOBALS(phpdbg_webhelper);
+
+PHP_INI_BEGIN()
+ STD_PHP_INI_ENTRY("phpdbg.auth", "", PHP_INI_SYSTEM | PHP_INI_PERDIR, OnUpdateString, auth, zend_phpdbg_webhelper_globals, phpdbg_webhelper_globals)
+ STD_PHP_INI_ENTRY("phpdbg.path", "", PHP_INI_SYSTEM | PHP_INI_PERDIR, OnUpdateString, path, zend_phpdbg_webhelper_globals, phpdbg_webhelper_globals)
+PHP_INI_END()
+
+static inline void php_phpdbg_webhelper_globals_ctor(zend_phpdbg_webhelper_globals *pg) /* {{{ */
+{
+} /* }}} */
+
+static PHP_MINIT_FUNCTION(phpdbg_webhelper) /* {{{ */
+{
+ if (!strcmp(sapi_module.name, PHPDBG_NAME)) {
+ return SUCCESS;
+ }
+
+ ZEND_INIT_MODULE_GLOBALS(phpdbg_webhelper, php_phpdbg_webhelper_globals_ctor, NULL);
+ REGISTER_INI_ENTRIES();
+
+ return SUCCESS;
+} /* }}} */
+
+static PHP_RINIT_FUNCTION(phpdbg_webhelper) /* {{{ */
+{
+ zval cookies = PG(http_globals)[TRACK_VARS_COOKIE];
+ zval *auth;
+
+ if (Z_TYPE(cookies) == IS_ARRAY || (auth = zend_hash_str_find(Z_ARRVAL(cookies), PHPDBG_NAME "_AUTH_COOKIE", sizeof(PHPDBG_NAME "_AUTH_COOKIE"))) || Z_STRLEN_P(auth) != strlen(PHPDBG_WG(auth)) || strcmp(Z_STRVAL_P(auth), PHPDBG_WG(auth))) {
+ return SUCCESS;
+ }
+
+#ifndef _WIN32
+ {
+ struct sockaddr_un sock;
+ int s = socket(AF_UNIX, SOCK_STREAM, 0);
+ int len = strlen(PHPDBG_WG(path)) + sizeof(sock.sun_family);
+ char buf[(1 << 8) + 1];
+ int buflen;
+ sock.sun_family = AF_UNIX;
+ strcpy(sock.sun_path, PHPDBG_WG(path));
+
+ if (connect(s, (struct sockaddr *)&sock, len) == -1) {
+ zend_error(E_ERROR, "Unable to connect to UNIX domain socket at %s defined by phpdbg.path ini setting. Reason: %s", PHPDBG_WG(path), strerror(errno));
+ }
+
+ char *msg = NULL;
+ char msglen[5] = {0};
+ phpdbg_webdata_compress(&msg, (int *)msglen TSRMLS_CC);
+
+ send(s, msglen, 4, 0);
+ send(s, msg, *(int *) msglen, 0);
+
+ while ((buflen = recv(s, buf, sizeof(buf) - 1, 0)) > 0) {
+ php_write(buf, buflen TSRMLS_CC);
+ }
+
+ close(s);
+
+ php_output_flush_all(TSRMLS_C);
+ zend_bailout();
+ }
+#endif
+
+ return SUCCESS;
+} /* }}} */
+
+zend_module_entry phpdbg_webhelper_module_entry = {
+ STANDARD_MODULE_HEADER,
+ "phpdbg_webhelper",
+ NULL,
+ PHP_MINIT(phpdbg_webhelper),
+ NULL,
+ PHP_RINIT(phpdbg_webhelper),
+ NULL,
+ NULL,
+ PHPDBG_VERSION,
+ STANDARD_MODULE_PROPERTIES
+};
diff --git a/sapi/phpdbg/phpdbg_rinit_hook.h b/sapi/phpdbg/phpdbg_rinit_hook.h
new file mode 100644
index 0000000000..d28be10f8c
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_rinit_hook.h
@@ -0,0 +1,41 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef PHPDBG_WEBHELPER_H
+#define PHPDBG_WEBHELPER_H
+
+#include "phpdbg_webdata_transfer.h"
+
+extern zend_module_entry phpdbg_webhelper_module_entry;
+#define phpext_phpdbg_webhelper_ptr &phpdbg_webhelper_module_entry
+
+#ifdef ZTS
+# define PHPDBG_WG(v) TSRMG(phpdbg_webhelper_globals_id, zend_phpdbg_webhelper_globals *, v)
+#else
+# define PHPDBG_WG(v) (phpdbg_webhelper_globals.v)
+#endif
+
+/* {{{ structs */
+ZEND_BEGIN_MODULE_GLOBALS(phpdbg_webhelper)
+ char *auth;
+ char *path;
+ZEND_END_MODULE_GLOBALS(phpdbg_webhelper) /* }}} */
+
+#endif /* PHPDBG_WEBHELPER_H */
diff --git a/sapi/phpdbg/phpdbg_set.c b/sapi/phpdbg/phpdbg_set.c
index 3d3eced705..82b9f69f7a 100644
--- a/sapi/phpdbg/phpdbg_set.c
+++ b/sapi/phpdbg/phpdbg_set.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -27,30 +27,32 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-#define PHPDBG_SET_COMMAND_D(f, h, a, m, l, s) \
- PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[18])
+#define PHPDBG_SET_COMMAND_D(f, h, a, m, l, s, flags) \
+ PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[18], flags)
const phpdbg_command_t phpdbg_set_commands[] = {
- PHPDBG_SET_COMMAND_D(prompt, "usage: set prompt [<string>]", 'p', set_prompt, NULL, "|s"),
+ PHPDBG_SET_COMMAND_D(prompt, "usage: set prompt [<string>]", 'p', set_prompt, NULL, "|s", 0),
#ifndef _WIN32
- PHPDBG_SET_COMMAND_D(color, "usage: set color <element> <color>", 'c', set_color, NULL, "ss"),
- PHPDBG_SET_COMMAND_D(colors, "usage: set colors [<on|off>]", 'C', set_colors, NULL, "|b"),
+ PHPDBG_SET_COMMAND_D(color, "usage: set color <element> <color>", 'c', set_color, NULL, "ss", PHPDBG_ASYNC_SAFE),
+ PHPDBG_SET_COMMAND_D(colors, "usage: set colors [<on|off>]", 'C', set_colors, NULL, "|b", PHPDBG_ASYNC_SAFE),
#endif
- PHPDBG_SET_COMMAND_D(oplog, "usage: set oplog [<output>]", 'O', set_oplog, NULL, "|s"),
- PHPDBG_SET_COMMAND_D(break, "usage: set break id [<on|off>]", 'b', set_break, NULL, "l|b"),
- PHPDBG_SET_COMMAND_D(breaks, "usage: set breaks [<on|off>]", 'B', set_breaks, NULL, "|b"),
- PHPDBG_SET_COMMAND_D(quiet, "usage: set quiet [<on|off>]", 'q', set_quiet, NULL, "|b"),
- PHPDBG_SET_COMMAND_D(stepping, "usage: set stepping [<line|op>]", 's', set_stepping, NULL, "|s"),
- PHPDBG_SET_COMMAND_D(refcount, "usage: set refcount [<on|off>]", 'r', set_refcount, NULL, "|b"),
+ PHPDBG_SET_COMMAND_D(oplog, "usage: set oplog [<output>]", 'O', set_oplog, NULL, "|s", 0),
+ PHPDBG_SET_COMMAND_D(break, "usage: set break id [<on|off>]", 'b', set_break, NULL, "l|b", PHPDBG_ASYNC_SAFE),
+ PHPDBG_SET_COMMAND_D(breaks, "usage: set breaks [<on|off>]", 'B', set_breaks, NULL, "|b", PHPDBG_ASYNC_SAFE),
+ PHPDBG_SET_COMMAND_D(quiet, "usage: set quiet [<on|off>]", 'q', set_quiet, NULL, "|b", PHPDBG_ASYNC_SAFE),
+ PHPDBG_SET_COMMAND_D(stepping, "usage: set stepping [<line|op>]", 's', set_stepping, NULL, "|s", PHPDBG_ASYNC_SAFE),
+ PHPDBG_SET_COMMAND_D(refcount, "usage: set refcount [<on|off>]", 'r', set_refcount, NULL, "|b", PHPDBG_ASYNC_SAFE),
PHPDBG_END_COMMAND
};
PHPDBG_SET(prompt) /* {{{ */
{
if (!param || param->type == EMPTY_PARAM) {
- phpdbg_writeln("%s", phpdbg_get_prompt(TSRMLS_C));
- } else phpdbg_set_prompt(param->str TSRMLS_CC);
-
+ phpdbg_writeln("setprompt", "str=\"%s\"", "Current prompt: %s", phpdbg_get_prompt(TSRMLS_C));
+ } else {
+ phpdbg_set_prompt(param->str TSRMLS_CC);
+ }
+
return SUCCESS;
} /* }}} */
@@ -61,21 +63,21 @@ PHPDBG_SET(break) /* {{{ */
if (param->next) {
if (param->next->num) {
phpdbg_enable_breakpoint(param->num TSRMLS_CC);
- } else phpdbg_disable_breakpoint(param->num TSRMLS_CC);
+ } else {
+ phpdbg_disable_breakpoint(param->num TSRMLS_CC);
+ }
} else {
phpdbg_breakbase_t *brake = phpdbg_find_breakbase(param->num TSRMLS_CC);
if (brake) {
- phpdbg_writeln(
- "%s", brake->disabled ? "off" : "on");
+ phpdbg_writeln("setbreak", "id=\"%ld\" active=\"%s\"", "Breakpoint #%ld %s", param->num, brake->disabled ? "off" : "on");
} else {
- phpdbg_error("Failed to find breakpoint #%ld", param->num);
+ phpdbg_error("setbreak", "type=\"nobreak\" id=\"%ld\"", "Failed to find breakpoint #%ld", param->num);
}
}
} break;
default:
- phpdbg_error(
- "set break used incorrectly: set break [id] <on|off>");
+ phpdbg_error("setbreak", "type=\"wrongargs\"", "set break used incorrectly: set break [id] <on|off>");
}
return SUCCESS;
@@ -84,18 +86,18 @@ PHPDBG_SET(break) /* {{{ */
PHPDBG_SET(breaks) /* {{{ */
{
if (!param || param->type == EMPTY_PARAM) {
- phpdbg_writeln("%s",
- PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED ? "on" : "off");
- } else switch (param->type) {
+ phpdbg_writeln("setbreaks", "active=\"%s\"", "Breakpoints %s",PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED ? "on" : "off");
+ } else switch (param->type) {
case NUMERIC_PARAM: {
if (param->num) {
phpdbg_enable_breakpoints(TSRMLS_C);
- } else phpdbg_disable_breakpoints(TSRMLS_C);
+ } else {
+ phpdbg_disable_breakpoints(TSRMLS_C);
+ }
} break;
default:
- phpdbg_error(
- "set break used incorrectly: set break [id] <on|off>");
+ phpdbg_error("setbreaks", "type=\"wrongargs\"", "set breaks used incorrectly: set breaks <on|off>");
}
return SUCCESS;
@@ -104,41 +106,35 @@ PHPDBG_SET(breaks) /* {{{ */
#ifndef _WIN32
PHPDBG_SET(color) /* {{{ */
{
- const phpdbg_color_t *color = phpdbg_get_color(
- param->next->str, param->next->len TSRMLS_CC);
-
+ const phpdbg_color_t *color = phpdbg_get_color(param->next->str, param->next->len TSRMLS_CC);
+
if (!color) {
- phpdbg_error(
- "Failed to find the requested color (%s)", param->next->str);
+ phpdbg_error("setcolor", "type=\"nocolor\"", "Failed to find the requested color (%s)", param->next->str);
return SUCCESS;
}
-
+
switch (phpdbg_get_element(param->str, param->len TSRMLS_CC)) {
case PHPDBG_COLOR_PROMPT:
- phpdbg_notice(
- "setting prompt color to %s (%s)", color->name, color->code);
+ phpdbg_notice("setcolor", "type=\"prompt\" color=\"%s\" code=\"%s\"", "setting prompt color to %s (%s)", color->name, color->code);
if (PHPDBG_G(prompt)[1]) {
free(PHPDBG_G(prompt)[1]);
PHPDBG_G(prompt)[1]=NULL;
}
phpdbg_set_color(PHPDBG_COLOR_PROMPT, color TSRMLS_CC);
break;
-
+
case PHPDBG_COLOR_ERROR:
- phpdbg_notice(
- "setting error color to %s (%s)", color->name, color->code);
+ phpdbg_notice("setcolor", "type=\"error\" color=\"%s\" code=\"%s\"", "setting error color to %s (%s)", color->name, color->code);
phpdbg_set_color(PHPDBG_COLOR_ERROR, color TSRMLS_CC);
break;
-
+
case PHPDBG_COLOR_NOTICE:
- phpdbg_notice(
- "setting notice color to %s (%s)", color->name, color->code);
+ phpdbg_notice("setcolor", "type=\"notice\" color=\"%s\" code=\"%s\"", "setting notice color to %s (%s)", color->name, color->code);
phpdbg_set_color(PHPDBG_COLOR_NOTICE, color TSRMLS_CC);
break;
-
+
default:
- phpdbg_error(
- "Failed to find the requested element (%s)", param->str);
+ phpdbg_error("setcolor", "type=\"invalidtype\"", "Failed to find the requested element (%s)", param->str);
}
return SUCCESS;
@@ -147,7 +143,7 @@ PHPDBG_SET(color) /* {{{ */
PHPDBG_SET(colors) /* {{{ */
{
if (!param || param->type == EMPTY_PARAM) {
- phpdbg_writeln("%s", PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "on" : "off");
+ phpdbg_writeln("setcolors", "active=\"%s\"", "Colors %s", PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "on" : "off");
} else switch (param->type) {
case NUMERIC_PARAM: {
if (param->num) {
@@ -156,10 +152,9 @@ PHPDBG_SET(colors) /* {{{ */
PHPDBG_G(flags) &= ~PHPDBG_IS_COLOURED;
}
} break;
-
+
default:
- phpdbg_error(
- "set colors used incorrectly: set colors <on|off>");
+ phpdbg_error("setcolors", "type=\"wrongargs\"", "set colors used incorrectly: set colors <on|off>");
}
return SUCCESS;
@@ -169,7 +164,7 @@ PHPDBG_SET(colors) /* {{{ */
PHPDBG_SET(oplog) /* {{{ */
{
if (!param || param->type == EMPTY_PARAM) {
- phpdbg_notice("Oplog %s", PHPDBG_G(oplog) ? "enabled" : "disabled");
+ phpdbg_notice("setoplog", "active=\"%s\"", "Oplog %s", PHPDBG_G(oplog) ? "on" : "off");
} else switch (param->type) {
case STR_PARAM: {
/* open oplog */
@@ -177,14 +172,15 @@ PHPDBG_SET(oplog) /* {{{ */
PHPDBG_G(oplog) = fopen(param->str, "w+");
if (!PHPDBG_G(oplog)) {
- phpdbg_error("Failed to open %s for oplog", param->str);
+ phpdbg_error("setoplog", "type=\"openfailure\" file=\"%s\"", "Failed to open %s for oplog", param->str);
PHPDBG_G(oplog) = old;
} else {
if (old) {
- phpdbg_notice("Closing previously open oplog");
+ phpdbg_notice("setoplog", "type=\"closingold\"", "Closing previously open oplog");
fclose(old);
}
- phpdbg_notice("Successfully opened oplog %s", param->str);
+
+ phpdbg_notice("setoplog", "file=\"%s\"", "Successfully opened oplog %s", param->str);
}
} break;
@@ -197,8 +193,7 @@ PHPDBG_SET(oplog) /* {{{ */
PHPDBG_SET(quiet) /* {{{ */
{
if (!param || param->type == EMPTY_PARAM) {
- phpdbg_writeln("Quietness %s",
- PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off");
+ phpdbg_writeln("setquiet", "active=\"%s\"", "Quietness %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off");
} else switch (param->type) {
case NUMERIC_PARAM: {
if (param->num) {
@@ -217,18 +212,15 @@ PHPDBG_SET(quiet) /* {{{ */
PHPDBG_SET(stepping) /* {{{ */
{
if (!param || param->type == EMPTY_PARAM) {
- phpdbg_writeln("Stepping %s",
- PHPDBG_G(flags) & PHPDBG_STEP_OPCODE ? "opcode" : "line");
+ phpdbg_writeln("setstepping", "type=\"%s\"", "Stepping %s", PHPDBG_G(flags) & PHPDBG_STEP_OPCODE ? "opcode" : "line");
} else switch (param->type) {
- case STR_PARAM: {
- if ((param->len == sizeof("opcode")-1) &&
- (memcmp(param->str, "opcode", sizeof("opcode")) == SUCCESS)) {
+ case STR_PARAM: {
+ if (param->len == sizeof("opcode") - 1 && !memcmp(param->str, "opcode", sizeof("opcode"))) {
PHPDBG_G(flags) |= PHPDBG_STEP_OPCODE;
- } else if ((param->len == sizeof("line")-1) &&
- (memcmp(param->str, "line", sizeof("line")) == SUCCESS)) {
+ } else if (param->len == sizeof("line") - 1 && !memcmp(param->str, "line", sizeof("line"))) {
PHPDBG_G(flags) &= ~PHPDBG_STEP_OPCODE;
} else {
- phpdbg_error("usage set stepping [<opcode|line>]");
+ phpdbg_error("setstepping", "type=\"wrongargs\"", "usage set stepping [<opcode|line>]");
}
} break;
@@ -241,7 +233,7 @@ PHPDBG_SET(stepping) /* {{{ */
PHPDBG_SET(refcount) /* {{{ */
{
if (!param || param->type == EMPTY_PARAM) {
- phpdbg_writeln("Refcount %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off");
+ phpdbg_writeln("setrefcount", "active=\"%s\"", "Showing refcounts %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off");
} else switch (param->type) {
case NUMERIC_PARAM: {
if (param->num) {
diff --git a/sapi/phpdbg/phpdbg_set.h b/sapi/phpdbg/phpdbg_set.h
index 18618cd007..dea61ed382 100644
--- a/sapi/phpdbg/phpdbg_set.h
+++ b/sapi/phpdbg/phpdbg_set.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
diff --git a/sapi/phpdbg/phpdbg_sigio_win32.c b/sapi/phpdbg/phpdbg_sigio_win32.c
new file mode 100644
index 0000000000..24e9ac0e0a
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_sigio_win32.c
@@ -0,0 +1,120 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 7-4 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: Anatol Belski <ab@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+
+#include <signal.h>
+
+#include "phpdbg.h"
+#include "phpdbg_sigio_win32.h"
+
+
+ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+
+
+VOID
+SigIoWatcherThread(VOID *p)
+{
+ zend_uchar sig;
+ struct win32_sigio_watcher_data *swd = (struct win32_sigio_watcher_data *)p;
+#ifdef ZTS
+ void ***tsrm_ls = swd->tsrm_ls;
+top:
+ (void)phpdbg_consume_bytes(swd->fd, &sig, 1, -1, tsrm_ls);
+#else
+top:
+ (void)phpdbg_consume_bytes(swd->fd, &sig, 1, -1);
+#endif
+
+
+ if (3 == sig) {
+ printf("signaled, got %d", sig);
+ /* XXX completely not sure it is done right here */
+ if (swd->flags & PHPDBG_IS_INTERACTIVE) {
+ if (raise(sig)) {
+ /* just out*/
+ exit(0);
+ }
+ }
+ if (swd->flags & PHPDBG_IS_SIGNALED) {
+ phpdbg_set_sigsafe_mem(&sig TSRMLS_CC);
+ zend_try {
+ phpdbg_force_interruption(TSRMLS_C);
+ } zend_end_try();
+ phpdbg_clear_sigsafe_mem(TSRMLS_C);
+ }
+ /* XXX set signaled flag to the caller thread, question is - whether it's needed */
+ ExitThread(sig);
+ } else {
+ goto top;
+ }
+}
+
+
+/* Start this only for the time of the run or eval command,
+for so long that the main thread is busy serving some debug
+session. */
+void
+sigio_watcher_start(void)
+{
+ TSRMLS_FETCH();
+
+ PHPDBG_G(swd).fd = PHPDBG_G(io)[PHPDBG_STDIN].fd;
+ PHPDBG_G(swd).running = 1;
+ PHPDBG_G(swd).flags = PHPDBG_G(flags);
+#ifdef ZTS
+ PHPDBG_G(swd).tsrm_ls = tsrm_ls;
+#endif
+
+ PHPDBG_G(sigio_watcher_thread) = CreateThread(
+ NULL,
+ 0,
+ (LPTHREAD_START_ROUTINE)SigIoWatcherThread,
+ &PHPDBG_G(swd),
+ 0,
+ NULL);
+}
+
+void
+sigio_watcher_stop(void)
+{
+ DWORD waited;
+ TSRMLS_FETCH();
+
+ if (INVALID_HANDLE_VALUE == PHPDBG_G(sigio_watcher_thread)) {
+ /* it probably did bail out already */
+ return;
+ }
+
+ waited = WaitForSingleObject(PHPDBG_G(sigio_watcher_thread), 300);
+
+ if (WAIT_OBJECT_0 != waited) {
+ if (!CancelSynchronousIo(PHPDBG_G(sigio_watcher_thread))) {
+ /* error out */
+ }
+
+ if (!TerminateThread(PHPDBG_G(sigio_watcher_thread), 0)) {
+ /* error out */
+ }
+ }
+
+ PHPDBG_G(swd).fd = -1;
+ PHPDBG_G(swd).running = 0;
+ PHPDBG_G(swd).flags = 0;
+ PHPDBG_G(sigio_watcher_thread) = INVALID_HANDLE_VALUE;
+}
+
diff --git a/sapi/phpdbg/phpdbg_sigio_win32.h b/sapi/phpdbg/phpdbg_sigio_win32.h
new file mode 100644
index 0000000000..796b477f93
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_sigio_win32.h
@@ -0,0 +1,42 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 7-4 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: Anatol Belski <ab@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+
+#ifndef PHPDBG_SIGIO_WIN32_H
+#define PHPDBG_SIGIO_WIN32_H
+
+#include "phpdbg.h"
+#include "phpdbg_prompt.h"
+#include "phpdbg_io.h"
+
+struct win32_sigio_watcher_data {
+ zend_ulong flags;
+#ifdef ZTS
+ void ***tsrm_ls;
+#endif
+ int fd;
+ zend_uchar running;
+};
+
+void
+sigio_watcher_start(void);
+
+void
+sigio_watcher_stop(void);
+
+#endif /* PHPDBG_SIGIO_WIN32_H */
diff --git a/sapi/phpdbg/phpdbg_sigsafe.c b/sapi/phpdbg/phpdbg_sigsafe.c
new file mode 100644
index 0000000000..1ca7bf230c
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_sigsafe.c
@@ -0,0 +1,56 @@
+#include "phpdbg_sigsafe.h"
+#include "phpdbg.h"
+
+ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+
+#define STR(x) #x
+#define EXP_STR(x) STR(x)
+
+static void* zend_mm_mem_alloc(zend_mm_storage *storage, size_t size, size_t alignment) {
+ TSRMLS_FETCH();
+
+ if (EXPECTED(size == PHPDBG_SIGSAFE_MEM_SIZE && !PHPDBG_G(sigsafe_mem).allocated)) {
+ PHPDBG_G(sigsafe_mem).allocated = 1;
+ return PHPDBG_G(sigsafe_mem).mem;
+ }
+
+ 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);
+ }
+
+ write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Bailed out without a bailout address in signal handler!\n"));
+
+ return NULL;
+}
+
+static void zend_mm_mem_free(zend_mm_storage *storage, void *ptr, size_t size) {
+}
+
+void phpdbg_set_sigsafe_mem(char *buffer TSRMLS_DC) {
+ phpdbg_signal_safe_mem *mem = &PHPDBG_G(sigsafe_mem);
+ mem->mem = buffer;
+ mem->allocated = 0;
+
+ mem->storage.chunk_alloc = zend_mm_mem_alloc;
+ mem->storage.chunk_free = zend_mm_mem_free;
+
+ mem->heap = zend_mm_startup_ex(&mem->storage);
+
+ mem->old_heap = zend_mm_set_heap(mem->heap TSRMLS_CC);
+}
+
+zend_mm_heap *phpdbg_original_heap_sigsafe_mem(TSRMLS_D) {
+ return PHPDBG_G(sigsafe_mem).old_heap;
+}
+
+void phpdbg_clear_sigsafe_mem(TSRMLS_D) {
+ zend_mm_set_heap(phpdbg_original_heap_sigsafe_mem(TSRMLS_C) TSRMLS_CC);
+ PHPDBG_G(sigsafe_mem).mem = NULL;
+}
+
+zend_bool phpdbg_active_sigsafe_mem(TSRMLS_D) {
+ return !!PHPDBG_G(sigsafe_mem).mem;
+}
+
diff --git a/sapi/phpdbg/phpdbg_sigsafe.h b/sapi/phpdbg/phpdbg_sigsafe.h
new file mode 100644
index 0000000000..9ef723fdca
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_sigsafe.h
@@ -0,0 +1,28 @@
+#ifndef PHPDBG_SIGSAFE_H
+#define PHPDBG_SIGSAFE_H
+
+//#include "zend_mm_structs.h"
+
+#define PHPDBG_SIGSAFE_MEM_SIZE ZEND_MM_CHUNK_SIZE
+//(1 << 20)
+
+#include "zend.h"
+
+typedef struct {
+ char *mem;
+ zend_bool allocated;
+ zend_mm_heap *heap;
+ zend_mm_heap *old_heap;
+ zend_mm_storage storage;
+} phpdbg_signal_safe_mem;
+
+#include "phpdbg.h"
+
+zend_bool phpdbg_active_sigsafe_mem(TSRMLS_D);
+
+void phpdbg_set_sigsafe_mem(char *mem TSRMLS_DC);
+void phpdbg_clear_sigsafe_mem(TSRMLS_D);
+
+zend_mm_heap *phpdbg_original_heap_sigsafe_mem(TSRMLS_D);
+
+#endif
diff --git a/sapi/phpdbg/phpdbg_utils.c b/sapi/phpdbg/phpdbg_utils.c
index b57986b55c..bff971d4cf 100644
--- a/sapi/phpdbg/phpdbg_utils.c
+++ b/sapi/phpdbg/phpdbg_utils.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -18,19 +18,14 @@
+----------------------------------------------------------------------+
*/
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
#include "zend.h"
+
#include "php.h"
-#include "spprintf.h"
#include "phpdbg.h"
#include "phpdbg_opcode.h"
#include "phpdbg_utils.h"
-#ifdef _WIN32
-# include "win32/time.h"
-#elif defined(HAVE_SYS_IOCTL_H)
+#if defined(HAVE_SYS_IOCTL_H)
# include "sys/ioctl.h"
# ifndef GWINSZ_IN_SYS_IOCTL
# include <termios.h>
@@ -128,12 +123,12 @@ PHPDBG_API int phpdbg_is_class_method(const char *str, size_t len, char **class,
}
if (class != NULL) {
-
+
if (str[0] == '\\') {
str++;
len--;
}
-
+
*class = estrndup(str, sep - str);
(*class)[sep - str] = 0;
}
@@ -170,27 +165,25 @@ PHPDBG_API const char *phpdbg_current_file(TSRMLS_D) /* {{{ */
PHPDBG_API const zend_function *phpdbg_get_function(const char *fname, const char *cname TSRMLS_DC) /* {{{ */
{
zend_function *func = NULL;
- size_t fname_len = strlen(fname);
- char *lcname = zend_str_tolower_dup(fname, fname_len);
+ zend_string *lfname = zend_string_alloc(strlen(fname), 0);
+ memcpy(lfname->val, zend_str_tolower_dup(fname, lfname->len), lfname->len + 1);
if (cname) {
- zend_class_entry **ce;
- size_t cname_len = strlen(cname);
- char *lc_cname = zend_str_tolower_dup(cname, cname_len);
- int ret = zend_lookup_class(lc_cname, cname_len, &ce TSRMLS_CC);
+ zend_class_entry *ce;
+ zend_string *lcname = zend_string_alloc(strlen(cname), 0);
+ memcpy(lcname->val, zend_str_tolower_dup(cname, lcname->len), lcname->len + 1);
+ ce = zend_lookup_class(lcname TSRMLS_CC);
- efree(lc_cname);
+ efree(lcname);
- if (ret == SUCCESS) {
- zend_hash_find(&(*ce)->function_table, lcname, fname_len+1,
- (void**)&func);
+ if (ce) {
+ func = zend_hash_find_ptr(&ce->function_table, lfname);
}
} else {
- zend_hash_find(EG(function_table), lcname, fname_len+1,
- (void**)&func);
+ func = zend_hash_find_ptr(EG(function_table), lfname);
}
- efree(lcname);
+ efree(lfname);
return func;
} /* }}} */
@@ -224,103 +217,6 @@ PHPDBG_API char *phpdbg_trim(const char *str, size_t len, size_t *new_len) /* {{
} /* }}} */
-PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, ...) /* {{{ */
-{
- int rc = 0;
- char *buffer = NULL;
- va_list args;
-
- if (format != NULL && strlen(format) > 0L) {
- va_start(args, format);
- vspprintf(&buffer, 0, format, args);
- va_end(args);
- }
-
- /* TODO(anyone) colours */
-
- switch (type) {
- case P_ERROR:
- if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) {
- rc = fprintf(fp,
- "\033[%sm[%s]\033[0m\n",
- PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, buffer);
- } else {
- rc = fprintf(fp, "[%s]\n", buffer);
- }
- break;
-
- case P_NOTICE:
- if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) {
- rc = fprintf(fp,
- "\033[%sm[%s]\033[0m\n",
- PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, buffer);
- } else {
- rc = fprintf(fp, "[%s]\n", buffer);
- }
- break;
-
- case P_WRITELN: {
- if (buffer) {
- rc = fprintf(fp, "%s\n", buffer);
- } else {
- rc = fprintf(fp, "\n");
- }
- } break;
-
- case P_WRITE:
- if (buffer) {
- rc = fprintf(fp, "%s", buffer);
- }
- break;
-
- /* no formatting on logging output */
- case P_LOG:
- if (buffer) {
- struct timeval tp;
- if (gettimeofday(&tp, NULL) == SUCCESS) {
- rc = fprintf(fp, "[%ld %.8F]: %s\n", tp.tv_sec, tp.tv_usec / 1000000.00, buffer);
- } else {
- rc = FAILURE;
- }
- }
- break;
- }
-
- if (buffer) {
- efree(buffer);
- }
-
- return rc;
-} /* }}} */
-
-PHPDBG_API int phpdbg_rlog(FILE *fp, const char *fmt, ...) { /* {{{ */
- int rc = 0;
-
- va_list args;
- struct timeval tp;
-
- va_start(args, fmt);
- if (gettimeofday(&tp, NULL) == SUCCESS) {
- char friendly[100];
- char *format = NULL, *buffer = NULL;
- const time_t tt = tp.tv_sec;
-
- strftime(friendly, 100, "%a %b %d %T.%%04d %Y", localtime(&tt));
- asprintf(
- &buffer, friendly, tp.tv_usec/1000);
- asprintf(
- &format, "[%s]: %s\n", buffer, fmt);
- rc = vfprintf(
- fp, format, args);
-
- free(format);
- free(buffer);
- }
- va_end(args);
-
- return rc;
-} /* }}} */
-
PHPDBG_API const phpdbg_color_t *phpdbg_get_color(const char *name, size_t name_length TSRMLS_DC) /* {{{ */
{
const phpdbg_color_t *color = colors;
@@ -328,15 +224,13 @@ PHPDBG_API const phpdbg_color_t *phpdbg_get_color(const char *name, size_t name_
while (color && color->name) {
if (name_length == color->name_length &&
memcmp(name, color->name, name_length) == SUCCESS) {
- phpdbg_debug(
- "phpdbg_get_color(%s, %lu): %s", name, name_length, color->code);
+ phpdbg_debug("phpdbg_get_color(%s, %lu): %s", name, name_length, color->code);
return color;
}
++color;
}
- phpdbg_debug(
- "phpdbg_get_color(%s, %lu): failed", name, name_length);
+ phpdbg_debug("phpdbg_get_color(%s, %lu): failed", name, name_length);
return NULL;
} /* }}} */
@@ -362,7 +256,7 @@ PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D) /* {{{ */
PHPDBG_API int phpdbg_get_element(const char *name, size_t len TSRMLS_DC) {
const phpdbg_element_t *element = elements;
-
+
while (element && element->name) {
if (len == element->name_length) {
if (strncasecmp(name, element->name, len) == SUCCESS) {
@@ -371,7 +265,7 @@ PHPDBG_API int phpdbg_get_element(const char *name, size_t len TSRMLS_DC) {
}
element++;
}
-
+
return PHPDBG_COLOR_INVALID;
}
@@ -419,18 +313,14 @@ PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D) /* {{{ */
} /* }}} */
int phpdbg_rebuild_symtable(TSRMLS_D) {
- if (!EG(active_op_array)) {
- phpdbg_error("No active op array!");
+ if (!EG(current_execute_data) || !EG(current_execute_data)->func) {
+ phpdbg_error("inactive", "type=\"op_array\"", "No active op array!");
return FAILURE;
}
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
-
- if (!EG(active_symbol_table)) {
- phpdbg_error("No active symbol table!");
- return FAILURE;
- }
+ if (!zend_rebuild_symbol_table(TSRMLS_C)) {
+ phpdbg_error("inactive", "type=\"symbol_table\"", "No active symbol table!");
+ return FAILURE;
}
return SUCCESS;
@@ -438,13 +328,13 @@ int phpdbg_rebuild_symtable(TSRMLS_D) {
PHPDBG_API int phpdbg_get_terminal_width(TSRMLS_D) /* {{{ */
{
- int columns;
+ int columns;
#ifdef _WIN32
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
-#elif defined(HAVE_SYS_IOCTL_H) && defined (TIOCGWINSZ)
+#elif defined(HAVE_SYS_IOCTL_H) && defined(TIOCGWINSZ)
struct winsize w;
columns = ioctl(fileno(stdout), TIOCGWINSZ, &w) == 0 ? w.ws_col : 80;
@@ -453,3 +343,328 @@ PHPDBG_API int phpdbg_get_terminal_width(TSRMLS_D) /* {{{ */
#endif
return columns;
} /* }}} */
+
+PHPDBG_API void phpdbg_set_async_io(int fd) {
+#ifndef _WIN32
+ int flags;
+ fcntl(STDIN_FILENO, F_SETOWN, getpid());
+ flags = fcntl(STDIN_FILENO, F_GETFL);
+ fcntl(STDIN_FILENO, F_SETFL, flags | FASYNC);
+#endif
+}
+
+int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry **ce TSRMLS_DC) {
+ if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) {
+ char *lc_name, *lc_free;
+ int lc_length;
+
+ if (name == NULL || !name_length) {
+ return FAILURE;
+ }
+
+ lc_free = lc_name = emalloc(name_length + 1);
+ zend_str_tolower_copy(lc_name, name, name_length);
+ lc_length = name_length + 1;
+
+ if (lc_name[0] == '\\') {
+ lc_name += 1;
+ lc_length -= 1;
+ }
+
+ phpdbg_try_access {
+ *ce = zend_hash_str_find_ptr(EG(class_table), lc_name, lc_length);
+ } phpdbg_catch_access {
+ phpdbg_error("signalsegv", "class=\"%.*s\"", "Could not fetch class %.*s, invalid data source", name_length, name);
+ } phpdbg_end_try_access();
+
+ efree(lc_free);
+ } else {
+ zend_string *str_name = zend_string_init(name, name_length, 0);
+ *ce = zend_lookup_class(str_name TSRMLS_CC);
+ efree(str_name);
+ }
+
+ return ce ? SUCCESS : FAILURE;
+}
+
+char *phpdbg_get_property_key(char *key) {
+ if (*key != 0) {
+ return key;
+ }
+ return strchr(key + 1, 0) + 1;
+}
+
+static int phpdbg_parse_variable_arg_wrapper(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv, phpdbg_parse_var_func callback TSRMLS_DC) {
+ return callback(name, len, keyname, keylen, parent, zv TSRMLS_CC);
+}
+
+PHPDBG_API int phpdbg_parse_variable(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_func callback, zend_bool silent TSRMLS_DC) {
+ return phpdbg_parse_variable_with_arg(input, len, parent, i, (phpdbg_parse_var_with_arg_func) phpdbg_parse_variable_arg_wrapper, silent, callback TSRMLS_CC);
+}
+
+PHPDBG_API int phpdbg_parse_variable_with_arg(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_with_arg_func callback, zend_bool silent, void *arg TSRMLS_DC) {
+ int ret = FAILURE;
+ zend_bool new_index = 1;
+ char *last_index;
+ size_t index_len = 0;
+ zval *zv;
+
+ if (len < 2 || *input != '$') {
+ goto error;
+ }
+
+ while (i++ < len) {
+ if (i == len) {
+ new_index = 1;
+ } else {
+ switch (input[i]) {
+ case '[':
+ new_index = 1;
+ break;
+ case ']':
+ break;
+ case '>':
+ if (last_index[index_len - 1] == '-') {
+ new_index = 1;
+ index_len--;
+ }
+ break;
+
+ default:
+ if (new_index) {
+ last_index = input + i;
+ new_index = 0;
+ }
+ if (input[i - 1] == ']') {
+ goto error;
+ }
+ index_len++;
+ }
+ }
+
+ if (new_index && index_len == 0) {
+ zend_ulong numkey;
+ zend_string *strkey;
+ ZEND_HASH_FOREACH_KEY_PTR(parent, numkey, strkey, zv) {
+ while (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+
+ if (i == len || (i == len - 1 && input[len - 1] == ']')) {
+ char *key, *propkey;
+ size_t namelen, keylen;
+ char *name;
+ char *keyname = estrndup(last_index, index_len);
+ if (strkey) {
+ key = strkey->val;
+ keylen = strkey->len;
+ } else {
+ keylen = spprintf(&key, 0, "%llu", numkey);
+ }
+ propkey = phpdbg_get_property_key(key);
+ name = emalloc(i + keylen + 2);
+ namelen = sprintf(name, "%.*s%.*s%s", (int) i, input, keylen - (propkey - key), propkey, input[len - 1] == ']'?"]":"");
+ if (!strkey) {
+ efree(key);
+ }
+
+ ret = callback(name, namelen, keyname, index_len, parent, zv, arg TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE;
+ } else if (Z_TYPE_P(zv) == IS_OBJECT) {
+ phpdbg_parse_variable_with_arg(input, len, Z_OBJPROP_P(zv), i, callback, silent, arg TSRMLS_CC);
+ } else if (Z_TYPE_P(zv) == IS_ARRAY) {
+ phpdbg_parse_variable_with_arg(input, len, Z_ARRVAL_P(zv), i, callback, silent, arg TSRMLS_CC);
+ } else {
+ /* Ignore silently */
+ }
+ } ZEND_HASH_FOREACH_END();
+ return ret;
+ } else if (new_index) {
+ char last_chr = last_index[index_len];
+ last_index[index_len] = 0;
+ if (!(zv = zend_symtable_str_find(parent, last_index, index_len))) {
+ if (!silent) {
+ phpdbg_error("variable", "type=\"undefined\" variable=\"%.*s\"", "%.*s is undefined", (int) i, input);
+ }
+ return FAILURE;
+ }
+ while (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+
+ last_index[index_len] = last_chr;
+ if (i == len) {
+ char *name = estrndup(input, len);
+ char *keyname = estrndup(last_index, index_len);
+
+ ret = callback(name, len, keyname, index_len, parent, zv, arg TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE;
+ } else if (Z_TYPE_P(zv) == IS_OBJECT) {
+ parent = Z_OBJPROP_P(zv);
+ } else if (Z_TYPE_P(zv) == IS_ARRAY) {
+ parent = Z_ARRVAL_P(zv);
+ } else {
+ phpdbg_error("variable", "type=\"notiterable\" variable=\"%.*s\"", "%.*s is nor an array nor an object", (int) i, input);
+ return FAILURE;
+ }
+ index_len = 0;
+ }
+ }
+
+ return ret;
+ error:
+ phpdbg_error("variable", "type=\"invalidinput\"", "Malformed input");
+ return FAILURE;
+}
+
+int phpdbg_is_auto_global(char *name, int len TSRMLS_DC) {
+ int ret;
+ zend_string *str = zend_string_init(name, len, 0);
+ ret = zend_is_auto_global(str TSRMLS_CC);
+ efree(str);
+ return ret;
+}
+
+static int phpdbg_xml_array_element_dump(zval *zv, zend_string *key, zend_ulong num TSRMLS_DC) {
+ phpdbg_xml("<element");
+
+ phpdbg_try_access {
+ if (key) { /* string key */
+ phpdbg_xml(" name=\"%.*s\"", key->len, key->val);
+ } else { /* numeric key */
+ phpdbg_xml(" name=\"%ld\"", num);
+ }
+ } phpdbg_catch_access {
+ phpdbg_xml(" severity=\"error\" ></element>");
+ return 0;
+ } phpdbg_end_try_access();
+
+ phpdbg_xml(">");
+
+ phpdbg_xml_var_dump(zv TSRMLS_CC);
+
+ phpdbg_xml("</element>");
+
+ return 0;
+}
+
+static int phpdbg_xml_object_property_dump(zval *zv, zend_string *key, zend_ulong num TSRMLS_DC) {
+ phpdbg_xml("<property");
+
+ phpdbg_try_access {
+ if (key) { /* string key */
+ const char *prop_name, *class_name;
+ int unmangle = zend_unmangle_property_name(key, &class_name, &prop_name);
+
+ if (class_name && unmangle == SUCCESS) {
+ phpdbg_xml(" name=\"%s\"", prop_name);
+ if (class_name[0] == '*') {
+ phpdbg_xml(" protection=\"protected\"");
+ } else {
+ phpdbg_xml(" class=\"%s\" protection=\"private\"", class_name);
+ }
+ } else {
+ phpdbg_xml(" name=\"%.*s\" protection=\"public\"", key->len, key->val);
+ }
+ } else { /* numeric key */
+ phpdbg_xml(" name=\"%ld\" protection=\"public\"", num);
+ }
+ } phpdbg_catch_access {
+ phpdbg_xml(" severity=\"error\" ></property>");
+ return 0;
+ } phpdbg_end_try_access();
+
+ phpdbg_xml(">");
+
+ phpdbg_xml_var_dump(zv TSRMLS_CC);
+
+ phpdbg_xml("</property>");
+
+ return 0;
+}
+
+#define COMMON (is_ref ? "&" : "")
+
+PHPDBG_API void phpdbg_xml_var_dump(zval *zv TSRMLS_DC) {
+ HashTable *myht;
+ zend_string *class_name, *key;
+ zend_ulong num;
+ zval *val;
+ int (*element_dump_func)(zval *zv, zend_string *key, zend_ulong num TSRMLS_DC);
+ zend_bool is_ref = 0;
+
+ int is_temp;
+
+ phpdbg_try_access {
+ is_ref = Z_ISREF_P(zv) && GC_REFCOUNT(Z_COUNTED_P(zv)) > 1;
+ ZVAL_DEREF(zv);
+
+ switch (Z_TYPE_P(zv)) {
+ case IS_TRUE:
+ phpdbg_xml("<bool refstatus=\"%s\" value=\"true\" />", COMMON);
+ break;
+ case IS_FALSE:
+ phpdbg_xml("<bool refstatus=\"%s\" value=\"false\" />", COMMON);
+ break;
+ case IS_NULL:
+ phpdbg_xml("<null refstatus=\"%s\" />", COMMON);
+ break;
+ case IS_LONG:
+ phpdbg_xml("<int refstatus=\"%s\" value=\"" ZEND_LONG_FMT "\" />", COMMON, Z_LVAL_P(zv));
+ break;
+ case IS_DOUBLE:
+ phpdbg_xml("<float refstatus=\"%s\" value=\"%.*G\" />", COMMON, (int) EG(precision), Z_DVAL_P(zv));
+ break;
+ case IS_STRING:
+ phpdbg_xml("<string refstatus=\"%s\" length=\"%d\" value=\"%.*s\" />", COMMON, Z_STRLEN_P(zv), Z_STRLEN_P(zv), Z_STRVAL_P(zv));
+ break;
+ case IS_ARRAY:
+ myht = Z_ARRVAL_P(zv);
+ if (ZEND_HASH_APPLY_PROTECTION(myht) && ++myht->u.v.nApplyCount > 1) {
+ phpdbg_xml("<recursion />");
+ --myht->u.v.nApplyCount;
+ break;
+ }
+ phpdbg_xml("<array refstatus=\"%s\" num=\"%d\">", COMMON, zend_hash_num_elements(myht));
+ element_dump_func = phpdbg_xml_array_element_dump;
+ is_temp = 0;
+ goto head_done;
+ case IS_OBJECT:
+ myht = Z_OBJDEBUG_P(zv, is_temp);
+ if (myht && ++myht->u.v.nApplyCount > 1) {
+ phpdbg_xml("<recursion />");
+ --myht->u.v.nApplyCount;
+ break;
+ }
+
+ class_name = Z_OBJ_HANDLER_P(zv, get_class_name)(Z_OBJ_P(zv) TSRMLS_CC);
+ phpdbg_xml("<object refstatus=\"%s\" class=\"%.*s\" id=\"%d\" num=\"%d\">", COMMON, class_name->len, class_name->val, Z_OBJ_HANDLE_P(zv), myht ? zend_hash_num_elements(myht) : 0);
+ zend_string_release(class_name);
+
+ element_dump_func = phpdbg_xml_object_property_dump;
+head_done:
+ if (myht) {
+ ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) {
+ element_dump_func(val, key, num TSRMLS_CC);
+ } ZEND_HASH_FOREACH_END();
+ zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) element_dump_func, 0);
+ --myht->u.v.nApplyCount;
+ if (is_temp) {
+ zend_hash_destroy(myht);
+ efree(myht);
+ }
+ }
+ if (Z_TYPE_P(zv) == IS_ARRAY) {
+ phpdbg_xml("</array>");
+ } else {
+ phpdbg_xml("</object>");
+ }
+ break;
+ case IS_RESOURCE: {
+ const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(zv) TSRMLS_CC);
+ phpdbg_xml("<resource refstatus=\"%s\" id=\"%pd\" type=\"%ld\" />", COMMON, Z_RES_P(zv)->handle, type_name ? type_name : "unknown");
+ break;
+ }
+ default:
+ break;
+ }
+ } phpdbg_end_try_access();
+}
diff --git a/sapi/phpdbg/phpdbg_utils.h b/sapi/phpdbg/phpdbg_utils.h
index 0edc40a262..83dc8e9694 100644
--- a/sapi/phpdbg/phpdbg_utils.h
+++ b/sapi/phpdbg/phpdbg_utils.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -33,52 +33,6 @@ PHPDBG_API char *phpdbg_resolve_path(const char* TSRMLS_DC);
PHPDBG_API char *phpdbg_trim(const char*, size_t, size_t*);
PHPDBG_API const zend_function *phpdbg_get_function(const char*, const char* TSRMLS_DC);
-/**
- * Error/notice/formatting helpers
- */
-enum {
- P_ERROR = 1,
- P_NOTICE,
- P_WRITELN,
- P_WRITE,
- P_LOG
-};
-
-#ifdef ZTS
-PHPDBG_API int phpdbg_print(int TSRMLS_DC, FILE*, const char*, ...) PHP_ATTRIBUTE_FORMAT(printf, 4, 5);
-#else
-PHPDBG_API int phpdbg_print(int TSRMLS_DC, FILE*, const char*, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4);
-#endif
-
-PHPDBG_API int phpdbg_rlog(FILE *stream, const char *fmt, ...);
-
-#define phpdbg_error(fmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__)
-#define phpdbg_notice(fmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__)
-#define phpdbg_writeln(fmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__)
-#define phpdbg_write(fmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__)
-#define phpdbg_log(fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__)
-
-#define phpdbg_error_ex(out, fmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, out, fmt, ##__VA_ARGS__)
-#define phpdbg_notice_ex(out, fmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, out, fmt, ##__VA_ARGS__)
-#define phpdbg_writeln_ex(out, fmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, out, fmt, ##__VA_ARGS__)
-#define phpdbg_write_ex(out, fmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, out, fmt, ##__VA_ARGS__)
-#define phpdbg_log_ex(out, fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, out, fmt, ##__VA_ARGS__)
-
-#if PHPDBG_DEBUG
-# define phpdbg_debug(fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDERR], fmt, ##__VA_ARGS__)
-#else
-# define phpdbg_debug(fmt, ...)
-#endif
-
-/* {{{ For writing blank lines */
-#define EMPTY NULL /* }}} */
-
-/* {{{ For prompt lines */
-#define PROMPT "phpdbg>" /* }}} */
-
-/* {{{ For separation */
-#define SEPARATE "------------------------------------------------" /* }}} */
-
/* {{{ Color Management */
#define PHPDBG_COLOR_LEN 12
#define PHPDBG_COLOR_D(color, code) \
@@ -112,7 +66,7 @@ typedef struct _phpdbg_element_t {
PHPDBG_API const phpdbg_color_t *phpdbg_get_color(const char *name, size_t name_length TSRMLS_DC);
PHPDBG_API void phpdbg_set_color(int element, const phpdbg_color_t *color TSRMLS_DC);
PHPDBG_API void phpdbg_set_color_ex(int element, const char *name, size_t name_length TSRMLS_DC);
-PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D);
+PHPDBG_API const phpdbg_color_t *phpdbg_get_colors(TSRMLS_D);
PHPDBG_API int phpdbg_get_element(const char *name, size_t len TSRMLS_DC); /* }}} */
/* {{{ Prompt Management */
@@ -122,26 +76,22 @@ PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D); /* }}} */
/* {{{ Console Width */
PHPDBG_API int phpdbg_get_terminal_width(TSRMLS_D); /* }}} */
+PHPDBG_API void phpdbg_set_async_io(int fd);
+
int phpdbg_rebuild_symtable(TSRMLS_D);
-#if PHP_VERSION_ID < 50500
-/* copy from zend_hash.c PHP 5.5 for 5.4 compatibility */
-static void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos) {
- Bucket *p;
-
- p = pos ? (*pos) : ht->pInternalPointer;
-
- if (!p) {
- Z_TYPE_P(key) = IS_NULL;
- } else if (p->nKeyLength) {
- Z_TYPE_P(key) = IS_STRING;
- Z_STRVAL_P(key) = IS_INTERNED(p->arKey) ? (char*)p->arKey : estrndup(p->arKey, p->nKeyLength - 1);
- Z_STRLEN_P(key) = p->nKeyLength - 1;
- } else {
- Z_TYPE_P(key) = IS_LONG;
- Z_LVAL_P(key) = p->h;
- }
-}
-#endif
+int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry **ce TSRMLS_DC);
+
+char *phpdbg_get_property_key(char *key);
+
+typedef int (*phpdbg_parse_var_func)(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv TSRMLS_DC);
+typedef int (*phpdbg_parse_var_with_arg_func)(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv, void *arg TSRMLS_DC);
+
+PHPDBG_API int phpdbg_parse_variable(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_func callback, zend_bool silent TSRMLS_DC);
+PHPDBG_API int phpdbg_parse_variable_with_arg(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_with_arg_func callback, zend_bool silent, void *arg TSRMLS_DC);
+
+int phpdbg_is_auto_global(char *name, int len TSRMLS_DC);
+
+PHPDBG_API void phpdbg_xml_var_dump(zval *zv TSRMLS_DC);
#endif /* PHPDBG_UTILS_H */
diff --git a/sapi/phpdbg/phpdbg_wait.c b/sapi/phpdbg/phpdbg_wait.c
new file mode 100644
index 0000000000..9051ca379f
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_wait.c
@@ -0,0 +1,400 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Bob Weinand <bwoebi@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "phpdbg_wait.h"
+#include "phpdbg_prompt.h"
+#include "ext/json/JSON_parser.h"
+#include "ext/standard/basic_functions.h"
+
+ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+ZEND_EXTERN_MODULE_GLOBALS(json);
+
+static void phpdbg_rebuild_http_globals_array(int type, const char *name TSRMLS_DC) {
+ zval *zvp;
+ if (Z_TYPE(PG(http_globals)[type]) != IS_UNDEF) {
+ zval_dtor(&PG(http_globals)[type]);
+ }
+ if ((zvp = zend_hash_str_find(&EG(symbol_table).ht, name, strlen(name)))) {
+ Z_ADDREF_P(zvp);
+ PG(http_globals)[type] = *zvp;
+ }
+}
+
+
+static int phpdbg_dearm_autoglobals(zend_auto_global *auto_global TSRMLS_DC) {
+ if (auto_global->name->len != sizeof("GLOBALS") - 1 || memcmp(auto_global->name->val, "GLOBALS", sizeof("GLOBALS") - 1)) {
+ auto_global->armed = 0;
+ }
+
+ return ZEND_HASH_APPLY_KEEP;
+}
+
+typedef struct {
+ HashTable *ht[2];
+ HashPosition pos[2];
+} phpdbg_intersect_ptr;
+
+static int phpdbg_array_data_compare(const void *a, const void *b TSRMLS_DC) {
+ Bucket *f, *s;
+ zval result;
+ zval *first, *second;
+
+ f = *((Bucket **) a);
+ s = *((Bucket **) b);
+
+ first = &f->val;
+ second = &s->val;
+
+ if (string_compare_function(&result, first, second TSRMLS_CC) == FAILURE) {
+ return 0;
+ }
+
+ if (Z_LVAL(result) < 0) {
+ return -1;
+ } else if (Z_LVAL(result) > 0) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static void phpdbg_array_intersect_init(phpdbg_intersect_ptr *info, HashTable *ht1, HashTable *ht2 TSRMLS_DC) {
+ info->ht[0] = ht1;
+ info->ht[1] = ht2;
+
+ zend_hash_sort(info->ht[0], zend_qsort, (compare_func_t) phpdbg_array_data_compare, 0 TSRMLS_CC);
+ zend_hash_sort(info->ht[1], zend_qsort, (compare_func_t) phpdbg_array_data_compare, 0 TSRMLS_CC);
+
+ zend_hash_internal_pointer_reset_ex(info->ht[0], &info->pos[0]);
+ zend_hash_internal_pointer_reset_ex(info->ht[1], &info->pos[1]);
+}
+
+/* -1 => first array, 0 => both arrays equal, 1 => second array */
+static int phpdbg_array_intersect(phpdbg_intersect_ptr *info, zval **ptr) {
+ int ret;
+ zval *zvp[2];
+ int invalid = !info->ht[0] + !info->ht[1];
+
+ if (invalid > 0) {
+ invalid = !info->ht[0];
+
+ if (!(*ptr = zend_hash_get_current_data_ex(info->ht[invalid], &info->pos[invalid]))) {
+ return 0;
+ }
+
+ zend_hash_move_forward_ex(info->ht[invalid], &info->pos[invalid]);
+
+ return invalid ? 1 : -1;
+ }
+
+ if (!(zvp[0] = zend_hash_get_current_data_ex(info->ht[0], &info->pos[0]))) {
+ info->ht[0] = NULL;
+ return phpdbg_array_intersect(info, ptr);
+ }
+ if (!(zvp[1] = zend_hash_get_current_data_ex(info->ht[1], &info->pos[1]))) {
+ info->ht[1] = NULL;
+ return phpdbg_array_intersect(info, ptr);
+ }
+
+ ret = zend_binary_zval_strcmp(zvp[0], zvp[1]);
+
+ if (ret <= 0) {
+ *ptr = zvp[0];
+ zend_hash_move_forward_ex(info->ht[0], &info->pos[0]);
+ }
+ if (ret >= 0) {
+ *ptr = zvp[1];
+ zend_hash_move_forward_ex(info->ht[1], &info->pos[1]);
+ }
+
+ return ret;
+}
+
+void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) {
+#ifdef HAVE_JSON
+ zval *free_zv = NULL;
+ zval zv, *zvp;
+ HashTable *ht;
+ php_json_decode(&zv, msg, len, 1, 1000 /* enough */ TSRMLS_CC);
+
+ if (JSON_G(error_code) != PHP_JSON_ERROR_NONE) {
+ phpdbg_error("wait", "type=\"invaliddata\" import=\"fail\"", "Malformed JSON was sent to this socket, arborting");
+ return;
+ }
+
+ ht = Z_ARRVAL(zv);
+
+ /* Reapply symbol table */
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("GLOBALS"))) && Z_TYPE_P(zvp) == IS_ARRAY) {
+ {
+ zval *srv;
+ if ((srv = zend_hash_str_find(Z_ARRVAL_P(zvp), ZEND_STRL("_SERVER"))) && Z_TYPE_P(srv) == IS_ARRAY) {
+ zval *script;
+ if ((script = zend_hash_str_find(Z_ARRVAL_P(srv), ZEND_STRL("SCRIPT_FILENAME"))) && Z_TYPE_P(script) == IS_STRING) {
+ phpdbg_param_t param;
+ param.str = Z_STRVAL_P(script);
+ PHPDBG_COMMAND_HANDLER(exec)(&param TSRMLS_CC);
+ }
+ }
+ }
+
+ PG(auto_globals_jit) = 0;
+ zend_hash_apply(CG(auto_globals), (apply_func_t) phpdbg_dearm_autoglobals TSRMLS_CC);
+
+ zend_hash_clean(&EG(symbol_table).ht);
+ EG(symbol_table) = *Z_ARR_P(zvp);
+
+ /* Rebuild cookies, env vars etc. from GLOBALS (PG(http_globals)) */
+ phpdbg_rebuild_http_globals_array(TRACK_VARS_POST, "_POST" TSRMLS_CC);
+ phpdbg_rebuild_http_globals_array(TRACK_VARS_GET, "_GET" TSRMLS_CC);
+ phpdbg_rebuild_http_globals_array(TRACK_VARS_COOKIE, "_COOKIE" TSRMLS_CC);
+ phpdbg_rebuild_http_globals_array(TRACK_VARS_SERVER, "_SERVER" TSRMLS_CC);
+ phpdbg_rebuild_http_globals_array(TRACK_VARS_ENV, "_ENV" TSRMLS_CC);
+ phpdbg_rebuild_http_globals_array(TRACK_VARS_FILES, "_FILES" TSRMLS_CC);
+
+ Z_ADDREF_P(zvp);
+ free_zv = zvp;
+ }
+
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("input"))) && Z_TYPE_P(zvp) == IS_STRING) {
+ if (SG(request_info).request_body) {
+ php_stream_close(SG(request_info).request_body);
+ }
+ SG(request_info).request_body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir));
+ php_stream_truncate_set_size(SG(request_info).request_body, 0);
+ php_stream_write(SG(request_info).request_body, Z_STRVAL_P(zvp), Z_STRLEN_P(zvp));
+ }
+
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("cwd"))) && Z_TYPE_P(zvp) == IS_STRING) {
+ if (VCWD_CHDIR(Z_STRVAL_P(zvp)) == SUCCESS) {
+ if (BG(CurrentStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentStatFile), strlen(BG(CurrentStatFile)))) {
+ efree(BG(CurrentStatFile));
+ BG(CurrentStatFile) = NULL;
+ }
+ if (BG(CurrentLStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentLStatFile), strlen(BG(CurrentLStatFile)))) {
+ efree(BG(CurrentLStatFile));
+ BG(CurrentLStatFile) = NULL;
+ }
+ }
+ }
+
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("sapi_name"))) && (Z_TYPE_P(zvp) == IS_STRING || Z_TYPE_P(zvp) == IS_NULL)) {
+ if (PHPDBG_G(sapi_name_ptr)) {
+ free(PHPDBG_G(sapi_name_ptr));
+ }
+ if (Z_TYPE_P(zvp) == IS_STRING) {
+ PHPDBG_G(sapi_name_ptr) = sapi_module.name = strdup(Z_STRVAL_P(zvp));
+ } else {
+ PHPDBG_G(sapi_name_ptr) = sapi_module.name = NULL;
+ }
+ }
+
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("modules"))) && Z_TYPE_P(zvp) == IS_ARRAY) {
+ phpdbg_intersect_ptr pos;
+ zval *module;
+ zend_module_entry *mod;
+ HashTable zv_registry;
+
+ /* intersect modules, unregister modules loaded "too much", announce not yet registered modules (phpdbg_notice) */
+
+ zend_hash_init(&zv_registry, zend_hash_num_elements(&module_registry), 0, ZVAL_PTR_DTOR, 0);
+ ZEND_HASH_FOREACH_PTR(&module_registry, mod) {
+ if (mod->name) {
+ zval value;
+ ZVAL_NEW_STR(&value, zend_string_init(mod->name, strlen(mod->name), 0));
+ zend_hash_next_index_insert(&zv_registry, &value);
+ }
+ } ZEND_HASH_FOREACH_END();
+
+ phpdbg_array_intersect_init(&pos, &zv_registry, Z_ARRVAL_P(zvp) TSRMLS_CC);
+ do {
+ int mode = phpdbg_array_intersect(&pos, &module);
+ if (mode < 0) {
+ // loaded module, but not needed
+ if (strcmp(PHPDBG_NAME, Z_STRVAL_P(module))) {
+ zend_hash_del(&module_registry, Z_STR_P(module));
+ }
+ } else if (mode > 0) {
+ // not loaded module
+ if (!sapi_module.name || strcmp(sapi_module.name, Z_STRVAL_P(module))) {
+ phpdbg_notice("wait", "missingmodule=\"%.*s\"", "The module %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/module/%.*s.so", Z_STRLEN_P(module), Z_STRVAL_P(module), Z_STRLEN_P(module), Z_STRVAL_P(module));
+ }
+ }
+ } while (module);
+
+ zend_hash_clean(&zv_registry);
+ }
+
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("extensions"))) && Z_TYPE_P(zvp) == IS_ARRAY) {
+ zend_extension *extension;
+ zend_llist_position pos;
+ zval *name = NULL;
+ zend_string *strkey;
+
+ extension = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &pos);
+ while (extension) {
+ extension = (zend_extension *) zend_llist_get_next_ex(&zend_extensions, &pos);
+
+ /* php_serach_array() body should be in some ZEND_API function... */
+ ZEND_HASH_FOREACH_STR_KEY_PTR(Z_ARRVAL_P(zvp), strkey, name) {
+ if (Z_TYPE_P(name) == IS_STRING && !zend_binary_strcmp(extension->name, strlen(extension->name), Z_STRVAL_P(name), Z_STRLEN_P(name))) {
+ break;
+ }
+ name = NULL;
+ } ZEND_HASH_FOREACH_END();
+
+ if (name) {
+ /* sigh, breaking the encapsulation, there aren't any functions manipulating the llist at the place of the zend_llist_position */
+ zend_llist_element *elm = pos;
+ if (elm->prev) {
+ elm->prev->next = elm->next;
+ } else {
+ zend_extensions.head = elm->next;
+ }
+ if (elm->next) {
+ elm->next->prev = elm->prev;
+ } else {
+ zend_extensions.tail = elm->prev;
+ }
+#if ZEND_EXTENSIONS_SUPPORT
+ if (extension->shutdown) {
+ extension->shutdown(extension);
+ }
+#endif
+ if (zend_extensions.dtor) {
+ zend_extensions.dtor(elm->data);
+ }
+ pefree(elm, zend_extensions.persistent);
+ zend_extensions.count--;
+ } else {
+/* zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &hpos);
+ if (Z_TYPE(key) == IS_LONG) {
+ zend_hash_index_del(Z_ARRVAL_PP(zvpp), Z_LVAL(key));
+ }
+*/
+ zend_hash_del(Z_ARRVAL_P(zvp), strkey);
+ }
+ }
+
+ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zvp), name) {
+ if (Z_TYPE_P(name) == IS_STRING) {
+ phpdbg_notice("wait", "missingextension=\"%.*s\"", "The Zend extension %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/extension.so", Z_STRLEN_P(name), Z_STRVAL_P(name));
+ }
+ } ZEND_HASH_FOREACH_END();
+ }
+
+ zend_ini_deactivate(TSRMLS_C);
+
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("systemini"))) && Z_TYPE_P(zvp) == IS_ARRAY) {
+ zval *ini_entry;
+ zend_ini_entry *original_ini;
+ zend_string *key;
+
+ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zvp), key, ini_entry) {
+ if (key && Z_TYPE_P(ini_entry) == IS_STRING) {
+ if ((original_ini = zend_hash_find_ptr(EG(ini_directives), key))) {
+ if (!original_ini->on_modify || original_ini->on_modify(original_ini, Z_STR_P(ini_entry), original_ini->mh_arg1, original_ini->mh_arg2, original_ini->mh_arg3, ZEND_INI_STAGE_ACTIVATE TSRMLS_CC) == SUCCESS) {
+ if (original_ini->modified && original_ini->orig_value != original_ini->value) {
+ efree(original_ini->value);
+ }
+ original_ini->value = Z_STR_P(ini_entry);
+ Z_ADDREF_P(ini_entry); /* don't free the string */
+ }
+ }
+ }
+ } ZEND_HASH_FOREACH_END();
+ }
+
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("userini"))) && Z_TYPE_P(zvp) == IS_ARRAY) {
+ zval *ini_entry;
+ zend_string *key;
+
+ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zvp), key, ini_entry) {
+ if (key && Z_TYPE_P(ini_entry) == IS_STRING) {
+ zend_alter_ini_entry_ex(key, Z_STR_P(ini_entry), ZEND_INI_PERDIR, ZEND_INI_STAGE_HTACCESS, 1 TSRMLS_CC);
+ }
+ } ZEND_HASH_FOREACH_END();
+ }
+
+ zval_dtor(&zv);
+ if (free_zv) {
+ /* separate freeing to not dtor the symtable too, just the container zval... */
+ efree(free_zv);
+ }
+
+ /* Reapply raw input */
+ /* ??? */
+#endif
+}
+
+PHPDBG_COMMAND(wait) /* {{{ */
+{
+#ifdef HAVE_JSON
+ struct sockaddr_un local, remote;
+ int rlen, sr, sl;
+ unlink(PHPDBG_G(socket_path));
+ if (PHPDBG_G(socket_server_fd) == -1) {
+ int len;
+ PHPDBG_G(socket_server_fd) = sl = socket(AF_UNIX, SOCK_STREAM, 0);
+
+ local.sun_family = AF_UNIX;
+ strcpy(local.sun_path, PHPDBG_G(socket_path));
+ len = strlen(local.sun_path) + sizeof(local.sun_family);
+ if (bind(sl, (struct sockaddr *)&local, len) == -1) {
+ phpdbg_error("wait", "type=\"nosocket\" import=\"fail\"", "Unable to connect to UNIX domain socket at %s defined by phpdbg.path ini setting", PHPDBG_G(socket_path));
+ return FAILURE;
+ }
+
+ chmod(PHPDBG_G(socket_path), 0666);
+
+ listen(sl, 2);
+ } else {
+ sl = PHPDBG_G(socket_server_fd);
+ }
+
+ rlen = sizeof(remote);
+ sr = accept(sl, (struct sockaddr *) &remote, (socklen_t *) &rlen);
+
+ char msglen[5];
+ int recvd = 4;
+
+ do {
+ recvd -= recv(sr, &(msglen[4 - recvd]), recvd, 0);
+ } while (recvd > 0);
+
+ recvd = *(size_t *) msglen;
+ char *data = emalloc(recvd);
+
+ do {
+ recvd -= recv(sr, &(data[(*(int *) msglen) - recvd]), recvd, 0);
+ } while (recvd > 0);
+
+ phpdbg_webdata_decompress(data, *(int *) msglen TSRMLS_CC);
+
+ if (PHPDBG_G(socket_fd) != -1) {
+ close(PHPDBG_G(socket_fd));
+ }
+ PHPDBG_G(socket_fd) = sr;
+
+ efree(data);
+
+ phpdbg_notice("wait", "import=\"success\"", "Successfully imported request data, stopped before executing");
+
+ return SUCCESS;
+#endif
+} /* }}} */
diff --git a/sapi/phpdbg/phpdbg_wait.h b/sapi/phpdbg/phpdbg_wait.h
new file mode 100644
index 0000000000..7cf95919cc
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_wait.h
@@ -0,0 +1,29 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Bob Weinand <bwoebi@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef PHPDBG_WAIT_H
+#define PHPDBG_WAIT_H
+
+#include "zend.h"
+#include "phpdbg.h"
+
+PHPDBG_COMMAND(wait);
+
+void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC);
+
+#endif /* PHPDBG_WAIT_H */
diff --git a/sapi/phpdbg/phpdbg_watch.c b/sapi/phpdbg/phpdbg_watch.c
index 054bea6d00..7a39d3ee1a 100644
--- a/sapi/phpdbg/phpdbg_watch.c
+++ b/sapi/phpdbg/phpdbg_watch.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -30,6 +30,15 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+const phpdbg_command_t phpdbg_watch_commands[] = {
+ PHPDBG_COMMAND_D_EX(array, "create watchpoint on an array", 'a', watch_array, NULL, "s", 0),
+ PHPDBG_COMMAND_D_EX(delete, "delete watchpoint", 'd', watch_delete, NULL, "s", 0),
+ PHPDBG_COMMAND_D_EX(recursive, "create recursive watchpoints", 'r', watch_recursive, NULL, "s", 0),
+ PHPDBG_END_COMMAND
+};
+
+//#define HT_FROM_WATCH(watch) (watch->type == WATCH_ON_OBJECT ? watch->addr.obj->handlers->get_properties(watch->parent_container.zv TSRMLS_CC) : watch->type == WATCH_ON_ARRAY ? &watch->addr.arr->ht : NULL)
+#define HT_FROM_ZVP(zvp) (Z_TYPE_P(zvp) == IS_OBJECT ? Z_OBJPROP_P(zvp) : Z_TYPE_P(zvp) == IS_ARRAY ? Z_ARRVAL_P(zvp) : NULL)
typedef struct {
void *page;
@@ -53,7 +62,7 @@ static phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *addr TSRMLS_DC) {
watch = result->ptr;
/* check if that addr is in a mprotect()'ed memory area */
- if ((char *)phpdbg_get_page_boundary(watch->addr.ptr) > (char *)addr || (char *)phpdbg_get_page_boundary(watch->addr.ptr) + phpdbg_get_total_page_size(watch->addr.ptr, watch->size) < (char *)addr) {
+ if ((char *) phpdbg_get_page_boundary(watch->addr.ptr) > (char *) addr || (char *) phpdbg_get_page_boundary(watch->addr.ptr) + phpdbg_get_total_page_size(watch->addr.ptr, watch->size) < (char *) addr) {
/* failure */
return NULL;
}
@@ -62,10 +71,8 @@ static phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *addr TSRMLS_DC) {
}
static void phpdbg_change_watchpoint_access(phpdbg_watchpoint_t *watch, int access TSRMLS_DC) {
- int m;
-
/* pagesize is assumed to be in the range of 2^x */
- m = mprotect(phpdbg_get_page_boundary(watch->addr.ptr), phpdbg_get_total_page_size(watch->addr.ptr, watch->size), access);
+ mprotect(phpdbg_get_page_boundary(watch->addr.ptr), phpdbg_get_total_page_size(watch->addr.ptr, watch->size), access);
}
static inline void phpdbg_activate_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
@@ -77,11 +84,11 @@ static inline void phpdbg_deactivate_watchpoint(phpdbg_watchpoint_t *watch TSRML
}
static inline void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
- phpdbg_btree_insert(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr, watch);
+ phpdbg_btree_insert(&PHPDBG_G(watchpoint_tree), (zend_ulong) watch->addr.ptr, watch);
}
static inline void phpdbg_remove_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
- phpdbg_btree_delete(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr);
+ phpdbg_btree_delete(&PHPDBG_G(watchpoint_tree), (zend_ulong) watch->addr.ptr);
}
void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) {
@@ -99,17 +106,95 @@ void phpdbg_create_ht_watchpoint(HashTable *ht, phpdbg_watchpoint_t *watch) {
watch->type = WATCH_ON_HASHTABLE;
}
-void phpdbg_watch_HashTable_dtor(zval **ptr);
+void phpdbg_watch_HashTable_dtor(zval *ptr);
+
+static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC);
+static void phpdbg_delete_ht_watchpoints_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC);
+static void phpdbg_delete_zval_watchpoints_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC);
+static void phpdbg_delete_watchpoints_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC);
+
+/* TODO: Store all the possible watches the refcounted may refer to (for displaying & deleting by identifier) */
+
+static phpdbg_watchpoint_t *phpdbg_create_refcounted_watchpoint(phpdbg_watchpoint_t *parent, zend_refcounted *ref) {
+ phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t));
+ watch->flags = parent->flags;
+ watch->parent = parent;
+ phpdbg_create_addr_watchpoint(&ref->refcount, sizeof(uint32_t), watch);
+ watch->type = WATCH_ON_REFCOUNTED;
+
+ return watch;
+}
+
+static void phpdbg_add_watch_collision(phpdbg_watchpoint_t *watch TSRMLS_DC) {
+ phpdbg_watch_collision *cur;
+ if ((cur = zend_hash_index_find_ptr(&PHPDBG_G(watch_collisions), (zend_ulong) watch->addr.ref))) {
+ cur->num++;
+ if (watch->flags == PHPDBG_WATCH_RECURSIVE) {
+ cur->refs++;
+ }
+ } else {
+ phpdbg_watch_collision coll;
+ coll.num = 1;
+ coll.refs = watch->flags == PHPDBG_WATCH_RECURSIVE;
+ coll.watch = *watch;
+ zend_hash_init(&coll.watches, 8, NULL, NULL, 0);
+ cur = zend_hash_index_add_mem(&PHPDBG_G(watch_collisions), (zend_ulong) watch->addr.ref, &coll, sizeof(phpdbg_watch_collision));
+ phpdbg_store_watchpoint(&cur->watch TSRMLS_CC);
+ phpdbg_activate_watchpoint(&cur->watch TSRMLS_CC);
+ }
+
+ zend_hash_str_add_ptr(&cur->watches, watch->parent->str, watch->parent->str_len, watch->parent);
+}
+
+static void phpdbg_remove_watch_collision(zend_refcounted *ref TSRMLS_DC) {
+ phpdbg_watch_collision *cur;
+ if ((cur = zend_hash_index_find_ptr(&PHPDBG_G(watch_collisions), (zend_ulong) ref))) {
+ phpdbg_watchpoint_t *watch = cur->watch.parent;
+
+ if (watch->flags == PHPDBG_WATCH_RECURSIVE && !--cur->refs) {
+ phpdbg_delete_watchpoints_recursive(watch TSRMLS_CC);
+ }
+
+ zend_hash_str_del(&cur->watches, watch->str, watch->str_len);
+
+ if (!--cur->num) {
+ phpdbg_deactivate_watchpoint(&cur->watch TSRMLS_CC);
+ phpdbg_remove_watchpoint(&cur->watch TSRMLS_CC);
+
+ phpdbg_delete_watchpoint(watch TSRMLS_CC);
+
+ zend_hash_index_del(&PHPDBG_G(watch_collisions), (zend_ulong) ref);
+ }
+ }
+}
static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
watch->flags |= PHPDBG_WATCH_SIMPLE;
phpdbg_store_watchpoint(watch TSRMLS_CC);
- zend_hash_add(&PHPDBG_G(watchpoints), watch->str, watch->str_len, &watch, sizeof(phpdbg_watchpoint_t *), NULL);
+ zend_hash_str_add_ptr(&PHPDBG_G(watchpoints), watch->str, watch->str_len, watch);
+
+ if (watch->parent && watch->parent->type == WATCH_ON_ZVAL && Z_REFCOUNTED_P(watch->parent->addr.zv)) {
+ phpdbg_add_watch_collision(phpdbg_create_refcounted_watchpoint(watch, Z_COUNTED_P(watch->parent->addr.zv)) TSRMLS_CC);
+ }
if (watch->type == WATCH_ON_ZVAL) {
- phpdbg_btree_insert(&PHPDBG_G(watch_HashTables), (zend_ulong)watch->parent_container, watch->parent_container->pDestructor);
- watch->parent_container->pDestructor = (dtor_func_t)phpdbg_watch_HashTable_dtor;
+ if (watch->parent_container) {
+ phpdbg_btree_insert(&PHPDBG_G(watch_HashTables), (zend_ulong) watch->parent_container, watch->parent_container->pDestructor);
+ watch->parent_container->pDestructor = (dtor_func_t) phpdbg_watch_HashTable_dtor;
+ }
+
+ if (Z_ISREF_P(watch->addr.zv)) {
+ phpdbg_watchpoint_t *ref = emalloc(sizeof(phpdbg_watchpoint_t));
+ ref->flags = watch->flags;
+ ref->str = watch->str;
+ ref->str_len = watch->str_len;
+ ref->parent = watch;
+ ref->parent_container = NULL;
+ phpdbg_create_zval_watchpoint(Z_REFVAL_P(watch->addr.zv), ref);
+
+ phpdbg_create_watchpoint(ref TSRMLS_CC);
+ }
}
phpdbg_activate_watchpoint(watch TSRMLS_CC);
@@ -117,36 +202,35 @@ static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
return SUCCESS;
}
-static int phpdbg_create_array_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
- HashTable *ht;
+static int phpdbg_create_array_watchpoint(phpdbg_watchpoint_t *zv_watch TSRMLS_DC) {
+ zval *zv = zv_watch->addr.zv;
+ phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t));
+ HashTable *ht = HT_FROM_ZVP(zv);
- switch (Z_TYPE_P(watch->addr.zv)) {
- case IS_ARRAY:
- ht = Z_ARRVAL_P(watch->addr.zv);
- break;
- case IS_OBJECT:
- ht = Z_OBJPROP_P(watch->addr.zv);
- break;
- default:
- return FAILURE;
+ watch->parent = zv_watch;
+
+ if (!ht) {
+ return FAILURE;
}
phpdbg_create_ht_watchpoint(ht, watch);
phpdbg_create_watchpoint(watch TSRMLS_CC);
- return SUCCESS;
-}
-
-static char *phpdbg_get_property_key(char *key) {
- if (*key != 0) {
- return key;
+ if (Z_TYPE_P(zv) == IS_ARRAY) {
+ watch->flags |= PHPDBG_WATCH_ARRAY;
+ } else {
+ watch->flags |= PHPDBG_WATCH_OBJECT;
}
- return strchr(key + 1, 0) + 1;
+
+ phpdbg_add_watch_collision(phpdbg_create_refcounted_watchpoint(watch, Z_COUNTED_P(zv)) TSRMLS_CC);
+
+ return SUCCESS;
}
static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
HashTable *ht;
+ zval *zvp = watch->addr.zv;
if (watch->type != WATCH_ON_ZVAL) {
return FAILURE;
@@ -155,25 +239,18 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_
watch->flags |= PHPDBG_WATCH_RECURSIVE;
phpdbg_create_watchpoint(watch TSRMLS_CC);
- switch (Z_TYPE_P(watch->addr.zv)) {
- case IS_ARRAY:
- ht = Z_ARRVAL_P(watch->addr.zv);
- break;
- case IS_OBJECT:
- ht = Z_OBJPROP_P(watch->addr.zv);
- break;
- default:
- return SUCCESS;
+ ZVAL_DEREF(zvp);
+
+ if (!(ht = HT_FROM_ZVP(zvp))) {
+ return SUCCESS;
}
{
HashPosition position;
- zval **zv;
+ zval *zv;
zval key;
- for (zend_hash_internal_pointer_reset_ex(ht, &position);
- zend_hash_get_current_data_ex(ht, (void **)&zv, &position) == SUCCESS;
- zend_hash_move_forward_ex(ht, &position)) {
+ ZEND_HASH_FOREACH_VAL(ht, zv) {
phpdbg_watchpoint_t *new_watch = emalloc(sizeof(phpdbg_watchpoint_t));
new_watch->flags = PHPDBG_WATCH_RECURSIVE;
@@ -182,19 +259,21 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_
zend_hash_get_current_key_zval_ex(ht, &key, &position);
if (Z_TYPE(key) == IS_STRING) {
- new_watch->name_in_parent = zend_strndup(Z_STRVAL(key), Z_STRLEN(key));
+ new_watch->name_in_parent = estrndup(Z_STRVAL(key), Z_STRLEN(key));
new_watch->name_in_parent_len = Z_STRLEN(key);
} else {
- new_watch->name_in_parent = NULL;
- new_watch->name_in_parent_len = asprintf(&new_watch->name_in_parent, "%ld", Z_LVAL(key));
+ new_watch->name_in_parent_len = spprintf(&new_watch->name_in_parent, 0, "%lld", Z_LVAL(key));
}
- new_watch->str = NULL;
- new_watch->str_len = asprintf(&new_watch->str, "%.*s%s%s%s", (int)watch->str_len, watch->str, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"[":"->", phpdbg_get_property_key(new_watch->name_in_parent), Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"]":"");
+ new_watch->str_len = spprintf(&new_watch->str, 0, "%.*s%s%s%s", (int) watch->str_len, watch->str, Z_TYPE_P(zvp) == IS_ARRAY ? "[" : "->", phpdbg_get_property_key(new_watch->name_in_parent), Z_TYPE_P(zvp) == IS_ARRAY ? "]" : "");
+
+ while (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
- phpdbg_create_zval_watchpoint(*zv, new_watch);
+ phpdbg_create_zval_watchpoint(zv, new_watch);
phpdbg_create_recursive_watchpoint(new_watch TSRMLS_CC);
- }
+ } ZEND_HASH_FOREACH_END();
}
{
@@ -202,12 +281,18 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_
new_watch->parent = watch;
new_watch->parent_container = watch->parent_container;
- new_watch->name_in_parent = zend_strndup(watch->name_in_parent, watch->name_in_parent_len);
+ new_watch->name_in_parent = estrndup(watch->name_in_parent, watch->name_in_parent_len);
new_watch->name_in_parent_len = watch->name_in_parent_len;
new_watch->str = NULL;
- new_watch->str_len = asprintf(&new_watch->str, "%.*s[]", (int)watch->str_len, watch->str);
+ new_watch->str_len = spprintf(&new_watch->str, 0, "%.*s[]", (int) watch->str_len, watch->str);
new_watch->flags = PHPDBG_WATCH_RECURSIVE;
+ if (Z_TYPE_P(zvp) == IS_ARRAY) {
+ new_watch->flags |= PHPDBG_WATCH_ARRAY;
+ } else {
+ new_watch->flags |= PHPDBG_WATCH_OBJECT;
+ }
+
phpdbg_create_ht_watchpoint(ht, new_watch);
phpdbg_create_watchpoint(new_watch TSRMLS_CC);
}
@@ -216,52 +301,58 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_
}
static int phpdbg_delete_watchpoint_recursive(phpdbg_watchpoint_t *watch, zend_bool user_request TSRMLS_DC) {
- if (watch->type == WATCH_ON_HASHTABLE || (watch->type == WATCH_ON_ZVAL && (Z_TYPE_P(watch->addr.zv) == IS_ARRAY || Z_TYPE_P(watch->addr.zv) == IS_OBJECT))) {
+ if (watch->type == WATCH_ON_HASHTABLE) {
HashTable *ht;
phpdbg_btree_result *result;
if (watch->type == WATCH_ON_HASHTABLE && user_request) {
- HashPosition position;
- zval **zv;
- zval key;
- char *str;
- int str_len;
- phpdbg_watchpoint_t **watchpoint;
-
- ht = watch->addr.ht;
-
- for (zend_hash_internal_pointer_reset_ex(ht, &position);
- zend_hash_get_current_data_ex(ht, (void **)&zv, &position) == SUCCESS;
- zend_hash_move_forward_ex(ht, &position)) {
- zend_hash_get_current_key_zval_ex(ht, &key, &position);
- str = NULL;
- if (Z_TYPE(key) == IS_STRING) {
- str_len = asprintf(&str, "%.*s%s%s%s", (int)watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", phpdbg_get_property_key(Z_STRVAL(key)), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":"");
- } else {
- str_len = asprintf(&str, "%.*s%s%li%s", (int)watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", Z_LVAL(key), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":"");
- }
-
- if (zend_hash_find(&PHPDBG_G(watchpoints), str, str_len, (void **) &watchpoint) == SUCCESS) {
- phpdbg_delete_watchpoint_recursive(*watchpoint, 1 TSRMLS_CC);
- }
- }
+ phpdbg_delete_ht_watchpoints_recursive(watch TSRMLS_CC);
} else {
- switch (Z_TYPE_P(watch->addr.zv)) {
- case IS_ARRAY:
- ht = Z_ARRVAL_P(watch->addr.zv);
- break;
- case IS_OBJECT:
- ht = Z_OBJPROP_P(watch->addr.zv);
- break;
- }
+ ht = HT_FROM_ZVP(watch->addr.zv);
if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong) ht))) {
phpdbg_delete_watchpoint_recursive((phpdbg_watchpoint_t *) result->ptr, user_request TSRMLS_CC);
}
}
+ } else if (watch->type == WATCH_ON_ZVAL) {
+ phpdbg_delete_zval_watchpoints_recursive(watch TSRMLS_CC);
+ }
+
+ return zend_hash_str_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
+}
+
+static void phpdbg_delete_ht_watchpoints_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC) {
+ zend_string *strkey;
+ zend_long numkey;
+ char *str;
+ int str_len;
+ phpdbg_watchpoint_t *watchpoint;
+
+ ZEND_HASH_FOREACH_KEY(watch->addr.ht, numkey, strkey) {
+ if (strkey) {
+ str_len = asprintf(&str, "%.*s%s%s%s", (int) watch->str_len, watch->str, (watch->flags & PHPDBG_WATCH_ARRAY) ? "[" : "->", phpdbg_get_property_key(strkey->val), (watch->flags & PHPDBG_WATCH_ARRAY) ? "]" : "");
+ } else {
+ str_len = asprintf(&str, "%.*s%s%lli%s", (int) watch->str_len, watch->str, (watch->flags & PHPDBG_WATCH_ARRAY) ? "[" : "->", numkey, (watch->flags & PHPDBG_WATCH_ARRAY) ? "]" : "");
+ }
+
+ if ((watchpoint = zend_hash_str_find_ptr(&PHPDBG_G(watchpoints), str, str_len))) {
+ phpdbg_delete_watchpoint_recursive(watchpoint, 1 TSRMLS_CC);
+ }
+ } ZEND_HASH_FOREACH_END();
+}
+
+static void phpdbg_delete_zval_watchpoints_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC) {
+ if (Z_REFCOUNTED_P(watch->addr.zv)) {
+ phpdbg_remove_watch_collision(Z_COUNTED_P(watch->addr.zv) TSRMLS_CC);
}
+}
- return zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
+static void phpdbg_delete_watchpoints_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC) {
+ if (watch->type == WATCH_ON_ZVAL) {
+ phpdbg_delete_zval_watchpoints_recursive(watch TSRMLS_CC);
+ } else if (watch->type == WATCH_ON_HASHTABLE) {
+ phpdbg_delete_ht_watchpoints_recursive(watch TSRMLS_CC);
+ }
}
static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC) {
@@ -269,7 +360,7 @@ static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC) {
phpdbg_watchpoint_t *watch;
phpdbg_btree_result *result;
- if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)tmp_watch->addr.ptr)) == NULL) {
+ if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong) tmp_watch->addr.ptr)) == NULL) {
return FAILURE;
}
@@ -278,133 +369,52 @@ static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC) {
if (watch->flags & PHPDBG_WATCH_RECURSIVE) {
ret = phpdbg_delete_watchpoint_recursive(watch, 1 TSRMLS_CC);
} else {
- ret = zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
+ ret = zend_hash_str_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
}
- free(tmp_watch->str);
+ efree(tmp_watch->str);
+ efree(tmp_watch->name_in_parent);
efree(tmp_watch);
return ret;
}
-static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, size_t i, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC), zend_bool silent TSRMLS_DC) {
- int ret = FAILURE;
- zend_bool new_index = 1;
- char *last_index;
- int index_len = 0;
- zval **zv;
-
- if (len < 2 || *input != '$') {
- goto error;
- }
-
- while (i++ < len) {
- if (i == len) {
- new_index = 1;
- } else {
- switch (input[i]) {
- case '[':
- new_index = 1;
- break;
- case ']':
- break;
- case '>':
- if (last_index[index_len - 1] == '-') {
- new_index = 1;
- index_len--;
- }
- break;
-
- default:
- if (new_index) {
- last_index = input + i;
- new_index = 0;
- }
- if (input[i - 1] == ']') {
- goto error;
- }
- index_len++;
- }
- }
-
- if (new_index && index_len == 0) {
- HashPosition position;
- for (zend_hash_internal_pointer_reset_ex(parent, &position);
- zend_hash_get_current_data_ex(parent, (void **)&zv, &position) == SUCCESS;
- zend_hash_move_forward_ex(parent, &position)) {
- if (i == len || (i == len - 1 && input[len - 1] == ']')) {
- zval *key = emalloc(sizeof(zval));
- phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t));
- watch->flags = 0;
- zend_hash_get_current_key_zval_ex(parent, key, &position);
- convert_to_string(key);
- watch->str = malloc(i + Z_STRLEN_P(key) + 2);
- watch->str_len = sprintf(watch->str, "%.*s%s%s", (int)i, input, phpdbg_get_property_key(Z_STRVAL_P(key)), input[len - 1] == ']'?"]":"");
- efree(key);
- watch->name_in_parent = zend_strndup(last_index, index_len);
- watch->name_in_parent_len = index_len;
- watch->parent_container = parent;
- phpdbg_create_zval_watchpoint(*zv, watch);
-
- ret = callback(watch TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE;
- } else if (Z_TYPE_PP(zv) == IS_OBJECT) {
- phpdbg_watchpoint_parse_input(input, len, Z_OBJPROP_PP(zv), i, callback, silent TSRMLS_CC);
- } else if (Z_TYPE_PP(zv) == IS_ARRAY) {
- phpdbg_watchpoint_parse_input(input, len, Z_ARRVAL_PP(zv), i, callback, silent TSRMLS_CC);
- } else {
- /* Ignore silently */
- }
- }
- return ret;
- } else if (new_index) {
- char last_chr = last_index[index_len];
- last_index[index_len] = 0;
- if (zend_symtable_find(parent, last_index, index_len + 1, (void **)&zv) == FAILURE) {
- if (!silent) {
- phpdbg_error("%.*s is undefined", (int)i, input);
- }
- return FAILURE;
- }
- last_index[index_len] = last_chr;
- if (i == len) {
- phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t));
- watch->flags = 0;
- watch->str = zend_strndup(input, len);
- watch->str_len = len;
- watch->name_in_parent = zend_strndup(last_index, index_len);
- watch->name_in_parent_len = index_len;
- watch->parent_container = parent;
- phpdbg_create_zval_watchpoint(*zv, watch);
-
- ret = callback(watch TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE;
- } else if (Z_TYPE_PP(zv) == IS_OBJECT) {
- parent = Z_OBJPROP_PP(zv);
- } else if (Z_TYPE_PP(zv) == IS_ARRAY) {
- parent = Z_ARRVAL_PP(zv);
- } else {
- phpdbg_error("%.*s is nor an array nor an object", (int)i, input);
- return FAILURE;
- }
- index_len = 0;
- }
+static int phpdbg_watchpoint_parse_wrapper(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) {
+ int ret;
+ phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t));
+ watch->flags = 0;
+ watch->str = name;
+ watch->str_len = len;
+ watch->name_in_parent = keyname;
+ watch->name_in_parent_len = keylen;
+ watch->parent_container = parent;
+ phpdbg_create_zval_watchpoint(zv, watch);
+
+ ret = callback(watch TSRMLS_CC);
+
+ if (ret != SUCCESS) {
+ efree(watch);
+ efree(name);
+ efree(keyname);
}
return ret;
- error:
- phpdbg_error("Malformed input");
- return FAILURE;
+}
+
+PHPDBG_API int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, size_t i, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC), zend_bool silent TSRMLS_DC) {
+ return phpdbg_parse_variable_with_arg(input, len, parent, i, (phpdbg_parse_var_with_arg_func) phpdbg_watchpoint_parse_wrapper, 0, callback TSRMLS_CC);
}
static int phpdbg_watchpoint_parse_symtables(char *input, size_t len, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) {
- if (EG(This) && len >= 5 && !memcmp("$this", input, 5)) {
- zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL);
+ if (EG(scope) && len >= 5 && !memcmp("$this", input, 5)) {
+ zend_hash_str_add(&EG(current_execute_data)->symbol_table->ht, ZEND_STRL("this"), &EG(current_execute_data)->This);
}
- if (zend_is_auto_global(input, len TSRMLS_CC) && phpdbg_watchpoint_parse_input(input, len, &EG(symbol_table), 0, callback, 1 TSRMLS_CC) != FAILURE) {
+ if (phpdbg_is_auto_global(input, len TSRMLS_CC) && phpdbg_watchpoint_parse_input(input, len, &EG(symbol_table).ht, 0, callback, 1 TSRMLS_CC) != FAILURE) {
return SUCCESS;
}
- return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0, callback, 0 TSRMLS_CC);
+ return phpdbg_watchpoint_parse_input(input, len, &EG(current_execute_data)->symbol_table->ht, 0, callback, 0 TSRMLS_CC);
}
PHPDBG_WATCH(delete) /* {{{ */
@@ -412,9 +422,9 @@ PHPDBG_WATCH(delete) /* {{{ */
switch (param->type) {
case STR_PARAM:
if (phpdbg_delete_var_watchpoint(param->str, param->len TSRMLS_CC) == FAILURE) {
- phpdbg_error("Nothing was deleted, no corresponding watchpoint found");
+ phpdbg_error("watchdelete", "type=\"nowatch\"", "Nothing was deleted, no corresponding watchpoint found");
} else {
- phpdbg_notice("Removed watchpoint %.*s", (int)param->len, param->str);
+ phpdbg_notice("watchdelete", "variable=\"%.*s\"", "Removed watchpoint %.*s", (int) param->len, param->str);
}
break;
@@ -433,7 +443,7 @@ PHPDBG_WATCH(recursive) /* {{{ */
switch (param->type) {
case STR_PARAM:
if (phpdbg_watchpoint_parse_symtables(param->str, param->len, phpdbg_create_recursive_watchpoint TSRMLS_CC) != FAILURE) {
- phpdbg_notice("Set recursive watchpoint on %.*s", (int)param->len, param->str);
+ phpdbg_notice("watchrecursive", "variable=\"%.*s\"", "Set recursive watchpoint on %.*s", (int)param->len, param->str);
}
break;
@@ -452,7 +462,7 @@ PHPDBG_WATCH(array) /* {{{ */
switch (param->type) {
case STR_PARAM:
if (phpdbg_watchpoint_parse_symtables(param->str, param->len, phpdbg_create_array_watchpoint TSRMLS_CC) != FAILURE) {
- phpdbg_notice("Set array watchpoint on %.*s", (int)param->len, param->str);
+ phpdbg_notice("watcharray", "variable=\"%.*s\"", "Set array watchpoint on %.*s", (int)param->len, param->str);
}
break;
@@ -462,23 +472,23 @@ PHPDBG_WATCH(array) /* {{{ */
return SUCCESS;
} /* }}} */
-void phpdbg_watch_HashTable_dtor(zval **zv) {
+void phpdbg_watch_HashTable_dtor(zval *zv) {
phpdbg_btree_result *result;
TSRMLS_FETCH();
zval_ptr_dtor_wrapper(zv);
- if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)*zv))) {
+ if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong) zv))) {
phpdbg_watchpoint_t *watch = result->ptr;
PHPDBG_G(watchpoint_hit) = 1;
- phpdbg_notice("%.*s was removed, removing watchpoint%s", (int)watch->str_len, watch->str, (watch->flags & PHPDBG_WATCH_RECURSIVE)?" recursively":"");
+ phpdbg_notice("watchdelete", "variable=\"%.*s\" recursive=\"%s\"", "%.*s was removed, removing watchpoint%s", (int) watch->str_len, watch->str, (watch->flags & PHPDBG_WATCH_RECURSIVE) ? " recursively" : "");
if (watch->flags & PHPDBG_WATCH_RECURSIVE) {
phpdbg_delete_watchpoint_recursive(watch, 0 TSRMLS_CC);
} else {
- zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
+ zend_hash_str_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
}
}
}
@@ -543,27 +553,26 @@ void phpdbg_watchpoints_clean(TSRMLS_D) {
zend_hash_clean(&PHPDBG_G(watchpoints));
}
-static void phpdbg_watch_dtor(void *pDest) {
- phpdbg_watchpoint_t *watch = *(phpdbg_watchpoint_t **)pDest;
+static void phpdbg_watch_dtor(zval *pDest) {
+ phpdbg_watchpoint_t *watch = (phpdbg_watchpoint_t *) Z_PTR_P(pDest);
TSRMLS_FETCH();
phpdbg_deactivate_watchpoint(watch TSRMLS_CC);
phpdbg_remove_watchpoint(watch TSRMLS_CC);
- free(watch->str);
- free(watch->name_in_parent);
- efree(watch);
+ efree(watch->str);
+ efree(watch->name_in_parent);
}
static void phpdbg_watch_mem_dtor(void *llist_data) {
- phpdbg_watch_memdump *dump = *(phpdbg_watch_memdump **)llist_data;
+ phpdbg_watch_memdump *dump = *(phpdbg_watch_memdump **) llist_data;
/* Disble writing again */
if (dump->reenable_writing) {
mprotect(dump->page, dump->size, PROT_READ);
}
- free(*(void **)llist_data);
+ free(*(void **) llist_data);
}
void phpdbg_setup_watchpoints(TSRMLS_D) {
@@ -580,131 +589,145 @@ void phpdbg_setup_watchpoints(TSRMLS_D) {
zend_llist_init(&PHPDBG_G(watchlist_mem), sizeof(void *), phpdbg_watch_mem_dtor, 1);
phpdbg_btree_init(&PHPDBG_G(watchpoint_tree), sizeof(void *) * 8);
phpdbg_btree_init(&PHPDBG_G(watch_HashTables), sizeof(void *) * 8);
- zend_hash_init(&PHPDBG_G(watchpoints), 8, NULL, phpdbg_watch_dtor, 0 ZEND_FILE_LINE_CC);
+ zend_hash_init(&PHPDBG_G(watchpoints), 8, NULL, phpdbg_watch_dtor, 0);
+ zend_hash_init(&PHPDBG_G(watch_collisions), 8, NULL, NULL, 0);
}
static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) {
/* fetch all changes between dump->page and dump->page + dump->size */
- phpdbg_btree_position pos = phpdbg_btree_find_between(&PHPDBG_G(watchpoint_tree), (zend_ulong)dump->page, (zend_ulong)dump->page + dump->size);
- phpdbg_btree_result *result, *htresult;
+ phpdbg_btree_position pos = phpdbg_btree_find_between(&PHPDBG_G(watchpoint_tree), (zend_ulong) dump->page, (zend_ulong) dump->page + dump->size);
+ phpdbg_btree_result *result;
int elementDiff;
void *curTest;
dump->reenable_writing = 0;
while ((result = phpdbg_btree_next(&pos))) {
- phpdbg_watchpoint_t *watch = result->ptr, *htwatch;
- void *oldPtr = (char *)&dump->data + ((size_t)watch->addr.ptr - (size_t)dump->page);
+ phpdbg_watchpoint_t *watch = result->ptr;
+ void *oldPtr = (char *) &dump->data + ((size_t) watch->addr.ptr - (size_t) dump->page);
char reenable = 1;
+ int removed = 0;
- if ((size_t)watch->addr.ptr < (size_t)dump->page || (size_t)watch->addr.ptr + watch->size > (size_t)dump->page + dump->size) {
+ if ((size_t) watch->addr.ptr < (size_t) dump->page || (size_t) watch->addr.ptr + watch->size > (size_t) dump->page + dump->size) {
continue;
}
/* Test if the zval was separated and if necessary move the watchpoint */
- if (zend_hash_find(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1, &curTest) == SUCCESS) {
- if (watch->type == WATCH_ON_HASHTABLE) {
- switch (Z_TYPE_PP((zval **)curTest)) {
- case IS_ARRAY:
- curTest = (void *)Z_ARRVAL_PP((zval **)curTest);
- break;
- case IS_OBJECT:
- curTest = (void *)Z_OBJPROP_PP((zval **)curTest);
- break;
+ if ((watch->type == WATCH_ON_HASHTABLE || watch->type == WATCH_ON_ZVAL) && watch->parent_container) {
+ if ((curTest = zend_hash_str_find(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len))) {
+ while (Z_TYPE_P((zval *) curTest) == IS_INDIRECT) {
+ curTest = Z_INDIRECT_P((zval *) curTest);
}
- } else {
- curTest = *(void **)curTest;
- }
- if (curTest != watch->addr.ptr) {
- phpdbg_deactivate_watchpoint(watch TSRMLS_CC);
- phpdbg_remove_watchpoint(watch TSRMLS_CC);
- watch->addr.ptr = curTest;
- phpdbg_store_watchpoint(watch TSRMLS_CC);
- phpdbg_activate_watchpoint(watch TSRMLS_CC);
+ if (watch->type == WATCH_ON_HASHTABLE) {
+ switch (Z_TYPE_P((zval *) curTest)) {
+ case IS_ARRAY:
+ curTest = (void *) Z_ARRVAL_P((zval *) curTest);
+ break;
+ case IS_OBJECT:
+ curTest = (void *) Z_OBJPROP_P((zval *) curTest);
+ break;
+ }
+ }
- reenable = 0;
+ if (curTest != watch->addr.ptr) {
+ phpdbg_deactivate_watchpoint(watch TSRMLS_CC);
+ phpdbg_remove_watchpoint(watch TSRMLS_CC);
+ watch->addr.ptr = curTest;
+ phpdbg_store_watchpoint(watch TSRMLS_CC);
+ phpdbg_activate_watchpoint(watch TSRMLS_CC);
+
+ reenable = 0;
+ }
+ } else {
+ removed = 1;
}
}
/* Show to the user what changed and delete watchpoint upon removal */
if (memcmp(oldPtr, watch->addr.ptr, watch->size) != SUCCESS) {
- if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS || (watch->type == WATCH_ON_ZVAL && memcmp(oldPtr, watch->addr.zv, sizeof(zvalue_value))) || (watch->type == WATCH_ON_HASHTABLE
-#if ZEND_DEBUG
- && !watch->addr.ht->inconsistent
-#endif
- && zend_hash_num_elements((HashTable *)oldPtr) != zend_hash_num_elements(watch->addr.ht))) {
+ zend_bool do_break = 0;
+
+ switch (watch->type) {
+ case WATCH_ON_ZVAL:
+ do_break = memcmp(oldPtr, watch->addr.zv, sizeof(zend_value) + sizeof(uint32_t) /* value + typeinfo */);
+ break;
+ case WATCH_ON_HASHTABLE:
+ do_break = zend_hash_num_elements((HashTable *) oldPtr) != zend_hash_num_elements(watch->addr.ht);
+ break;
+ case WATCH_ON_REFCOUNTED:
+ if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS) {
+ do_break = memcmp(oldPtr, watch->addr.ref, sizeof(uint32_t) /* no zend_refcounted metadata info */);
+ }
+ break;
+ }
+
+
+ if (do_break) {
PHPDBG_G(watchpoint_hit) = 1;
- phpdbg_notice("Breaking on watchpoint %s", watch->str);
+ phpdbg_notice("watchhit", "variable=\"%s\"", "Breaking on watchpoint %.*s", (int) watch->str_len, watch->str);
+ phpdbg_xml("<watchdata %r>");
}
switch (watch->type) {
case WATCH_ON_ZVAL: {
- int removed = ((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc && !zend_symtable_exists(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1);
- int show_value = memcmp(oldPtr, watch->addr.zv, sizeof(zvalue_value));
- int show_ref = ((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc || ((zval *)oldPtr)->is_ref__gc != watch->addr.zv->is_ref__gc;
+ int show_value = memcmp(oldPtr, watch->addr.zv, sizeof(zval) - sizeof(uint32_t) /* no metadata info */);
if (removed || show_value) {
- phpdbg_write("Old value: ");
- if ((Z_TYPE_P((zval *)oldPtr) == IS_ARRAY || Z_TYPE_P((zval *)oldPtr) == IS_OBJECT) && removed) {
- phpdbg_writeln("Value inaccessible, HashTable already destroyed");
+ if (removed && (Z_TYPE_P((zval *) oldPtr) == IS_ARRAY || Z_TYPE_P((zval *) oldPtr) == IS_OBJECT)) {
+ phpdbg_writeln("watchvalue", "type=\"old\" inaccessible=\"inaccessible\"", "Old value inaccessible, array or object (HashTable) already destroyed");
} else {
- zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC);
- phpdbg_writeln("");
+ phpdbg_out("Old value: ");
+ phpdbg_xml("<watchvalue %r type=\"old\">");
+ zend_print_flat_zval_r((zval *) oldPtr TSRMLS_CC);
+ phpdbg_xml("</watchvalue>");
+ phpdbg_out("\n");
}
}
- if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && (removed || show_ref)) {
- phpdbg_writeln("Old refcount: %d; Old is_ref: %d", ((zval *)oldPtr)->refcount__gc, ((zval *)oldPtr)->is_ref__gc);
- }
/* check if zval was removed */
if (removed) {
- phpdbg_notice("Watchpoint %s was unset, removing watchpoint", watch->str);
- zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
+ phpdbg_notice("watchdelete", "variable=\"%.*s\"", "Watchpoint %.*s was unset, removing watchpoint", (int) watch->str_len, watch->str);
+ zend_hash_str_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
reenable = 0;
- if (Z_TYPE_P((zval *)oldPtr) == IS_ARRAY || Z_TYPE_P((zval *)oldPtr) == IS_OBJECT) {
- goto remove_ht_watch;
+ if (Z_REFCOUNTED_P((zval *) oldPtr)) {
+ phpdbg_remove_watch_collision(Z_COUNTED_P((zval *) oldPtr) TSRMLS_CC);
}
-
break;
}
if (show_value) {
- phpdbg_write("New value: ");
+ phpdbg_out("New value: ");
+ phpdbg_xml("<watchvalue %r type=\"new\">");
zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC);
- phpdbg_writeln("");
- }
- if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && show_ref) {
- phpdbg_writeln("New refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc);
+ phpdbg_xml("</watchvalue>");
+ phpdbg_out("\n");
}
- if ((Z_TYPE_P(watch->addr.zv) == IS_ARRAY && Z_ARRVAL_P(watch->addr.zv) != Z_ARRVAL_P((zval *)oldPtr)) || (Z_TYPE_P(watch->addr.zv) != IS_OBJECT && Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *)oldPtr))) {
- /* add new watchpoints if necessary */
- if (watch->flags & PHPDBG_WATCH_RECURSIVE) {
- phpdbg_create_recursive_watchpoint(watch TSRMLS_CC);
+ /* add new watchpoints if necessary */
+ if (Z_PTR_P(watch->addr.zv) != Z_PTR_P((zval *) oldPtr)) {
+ if (Z_REFCOUNTED_P((zval *) oldPtr)) {
+ phpdbg_remove_watch_collision(Z_COUNTED_P((zval *) oldPtr) TSRMLS_CC);
+ }
+ if (Z_REFCOUNTED_P(watch->addr.zv)) {
+ if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS) {
+ phpdbg_writeln("watchrefcount", "type=\"new\" refcount=\"%d\"", "New refcount: %d", Z_COUNTED_P(watch->addr.zv)->refcount);
+ }
+ if (watch->flags & PHPDBG_WATCH_RECURSIVE) {
+ phpdbg_create_recursive_watchpoint(watch TSRMLS_CC);
+ }
}
- }
-
- if ((Z_TYPE_P((zval *)oldPtr) != IS_ARRAY || Z_ARRVAL_P(watch->addr.zv) == Z_ARRVAL_P((zval *)oldPtr)) && (Z_TYPE_P((zval *)oldPtr) != IS_OBJECT || Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *)oldPtr))) {
- break;
- }
-
-remove_ht_watch:
- if ((htresult = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)Z_ARRVAL_P((zval *)oldPtr)))) {
- htwatch = htresult->ptr;
- zend_hash_del(&PHPDBG_G(watchpoints), htwatch->str, htwatch->str_len);
}
break;
}
case WATCH_ON_HASHTABLE:
-
-#if ZEND_DEBUG
- if (watch->addr.ht->inconsistent) {
- phpdbg_notice("Watchpoint %s was unset, removing watchpoint", watch->str);
+#if 0 && ZEND_DEBUG
+ if (watch->addr.arr->ht->inconsistent) {
+ phpdbg_notice("watchdelete", "variable=\"%.*s\"", "Watchpoint %.*s was unset, removing watchpoint", (int) watch->str_len, watch->str);
zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
reenable = 0;
@@ -712,13 +735,12 @@ remove_ht_watch:
break;
}
#endif
-
- elementDiff = zend_hash_num_elements((HashTable *)oldPtr) - zend_hash_num_elements(watch->addr.ht);
+ elementDiff = zend_hash_num_elements((HashTable *) oldPtr) - zend_hash_num_elements(watch->addr.ht);
if (elementDiff) {
if (elementDiff > 0) {
- phpdbg_writeln("%d elements were removed from the array", elementDiff);
+ phpdbg_writeln("watchsize", "removed=\"%d\"", "%d elements were removed from the array", elementDiff);
} else {
- phpdbg_writeln("%d elements were added to the array", -elementDiff);
+ phpdbg_writeln("watchsize", "added=\"%d\"", "%d elements were added to the array", -elementDiff);
/* add new watchpoints if necessary */
if (watch->flags & PHPDBG_WATCH_RECURSIVE) {
@@ -726,10 +748,25 @@ remove_ht_watch:
}
}
}
- if (((HashTable *)oldPtr)->pInternalPointer != watch->addr.ht->pInternalPointer) {
- phpdbg_writeln("Internal pointer of array was changed");
+ if (watch->addr.ht->nInternalPointer != ((HashTable *) oldPtr)->nInternalPointer) {
+ phpdbg_writeln("watcharrayptr", "", "Internal pointer of array was changed");
+ }
+ break;
+ case WATCH_ON_REFCOUNTED: {
+ if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS) {
+ phpdbg_writeln("watchrefcount", "type=\"old\" refcount=\"%d\"", "Old refcount: %d", ((zend_refcounted *) oldPtr)->refcount);
+
+ if (!removed) {
+ phpdbg_writeln("watchrefcount", "type=\"old\" refcount=\"%d\"", "Old refcount: %d", ((zend_refcounted *) oldPtr)->refcount);
+ }
}
+
break;
+ }
+ }
+
+ if (do_break) {
+ phpdbg_xml("</watchdata>");
}
}
@@ -746,42 +783,46 @@ int phpdbg_print_changed_zvals(TSRMLS_D) {
return FAILURE;
}
- dump = (phpdbg_watch_memdump **)zend_llist_get_last_ex(&PHPDBG_G(watchlist_mem), &pos);
+ dump = (phpdbg_watch_memdump **) zend_llist_get_last_ex(&PHPDBG_G(watchlist_mem), &pos);
do {
phpdbg_print_changed_zval(*dump TSRMLS_CC);
- } while ((dump = (phpdbg_watch_memdump **)zend_llist_get_prev_ex(&PHPDBG_G(watchlist_mem), &pos)));
+ } while ((dump = (phpdbg_watch_memdump **) zend_llist_get_prev_ex(&PHPDBG_G(watchlist_mem), &pos)));
zend_llist_clean(&PHPDBG_G(watchlist_mem));
- ret = PHPDBG_G(watchpoint_hit)?SUCCESS:FAILURE;
+ ret = PHPDBG_G(watchpoint_hit) ? SUCCESS : FAILURE;
PHPDBG_G(watchpoint_hit) = 0;
return ret;
}
void phpdbg_list_watchpoints(TSRMLS_D) {
- HashPosition position;
- phpdbg_watchpoint_t **watch;
+ phpdbg_watchpoint_t *watch;
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(watchpoints), &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(watchpoints), (void**) &watch, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(watchpoints), &position)) {
- phpdbg_writeln("%.*s", (int)(*watch)->str_len, (*watch)->str);
- }
+ phpdbg_xml("<watchlist %r>");
+
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(watchpoints), watch) {
+ phpdbg_writeln("watchvariable", "variable=\"%.*s\" on=\"%s\" type=\"%s\"", "%.*s (%s, %s)", (int) watch->str_len, watch->str, watch->type == WATCH_ON_HASHTABLE ? "array" : watch->type == WATCH_ON_REFCOUNTED ? "refcount" : "variable", watch->flags == PHPDBG_WATCH_RECURSIVE ? "recursive" : "simple");
+ } ZEND_HASH_FOREACH_END();
+
+ phpdbg_xml("</watchlist>");
}
void phpdbg_watch_efree(void *ptr) {
phpdbg_btree_result *result;
TSRMLS_FETCH();
- result = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong)ptr);
+ result = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong) ptr);
if (result) {
phpdbg_watchpoint_t *watch = result->ptr;
- if ((size_t)watch->addr.ptr + watch->size > (size_t)ptr) {
- zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
+ if ((size_t) watch->addr.ptr + watch->size > (size_t) ptr) {
+ if (watch->type == WATCH_ON_ZVAL) {
+ phpdbg_remove_watch_collision(Z_COUNTED_P(watch->addr.zv) TSRMLS_CC);
+ }
+ zend_hash_str_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
}
}
diff --git a/sapi/phpdbg/phpdbg_watch.h b/sapi/phpdbg/phpdbg_watch.h
index 7a4e49ec8f..35cab10dc1 100644
--- a/sapi/phpdbg/phpdbg_watch.h
+++ b/sapi/phpdbg/phpdbg_watch.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -25,7 +25,7 @@
#include "phpdbg_cmd.h"
#ifdef _WIN32
-# include "phpdbg_win.h"
+# include "phpdbg_win.h"
#endif
#define PHPDBG_WATCH(name) PHPDBG_COMMAND(watch_##name)
@@ -37,47 +37,49 @@ PHPDBG_WATCH(array);
PHPDBG_WATCH(delete);
PHPDBG_WATCH(recursive);
-/**
- * Commands
- */
-
-static const phpdbg_command_t phpdbg_watch_commands[] = {
- PHPDBG_COMMAND_D_EX(array, "create watchpoint on an array", 'a', watch_array, NULL, "s"),
- PHPDBG_COMMAND_D_EX(delete, "delete watchpoint", 'd', watch_delete, NULL, "s"),
- PHPDBG_COMMAND_D_EX(recursive, "create recursive watchpoints", 'r', watch_recursive, NULL, "s"),
- PHPDBG_END_COMMAND
-};
+extern const phpdbg_command_t phpdbg_watch_commands[];
/* Watchpoint functions/typedefs */
typedef enum {
WATCH_ON_ZVAL,
WATCH_ON_HASHTABLE,
+ WATCH_ON_REFCOUNTED,
} phpdbg_watchtype;
-#define PHPDBG_WATCH_SIMPLE 0x0
-#define PHPDBG_WATCH_RECURSIVE 0x1
+#define PHPDBG_WATCH_SIMPLE 0x0
+#define PHPDBG_WATCH_RECURSIVE 0x1
+#define PHPDBG_WATCH_ARRAY 0x2
+#define PHPDBG_WATCH_OBJECT 0x4
typedef struct _phpdbg_watchpoint_t phpdbg_watchpoint_t;
struct _phpdbg_watchpoint_t {
- phpdbg_watchpoint_t *parent;
- HashTable *parent_container;
- char *name_in_parent;
- size_t name_in_parent_len;
- char *str;
- size_t str_len;
union {
zval *zv;
HashTable *ht;
+ zend_refcounted *ref;
void *ptr;
} addr;
size_t size;
phpdbg_watchtype type;
char flags;
+ phpdbg_watchpoint_t *parent;
+ HashTable *parent_container;
+ char *name_in_parent;
+ size_t name_in_parent_len;
+ char *str;
+ size_t str_len;
};
+typedef struct {
+ phpdbg_watchpoint_t watch;
+ unsigned int num;
+ unsigned int refs;
+ HashTable watches;
+} phpdbg_watch_collision;
+
void phpdbg_setup_watchpoints(TSRMLS_D);
#ifndef _WIN32
@@ -102,11 +104,11 @@ void phpdbg_watch_efree(void *ptr);
static long phpdbg_pagesize;
static zend_always_inline void *phpdbg_get_page_boundary(void *addr) {
- return (void *)((size_t)addr & ~(phpdbg_pagesize - 1));
+ return (void *) ((size_t) addr & ~(phpdbg_pagesize - 1));
}
static zend_always_inline size_t phpdbg_get_total_page_size(void *addr, size_t size) {
- return (size_t)phpdbg_get_page_boundary((void *)((size_t)addr + size - 1)) - (size_t)phpdbg_get_page_boundary(addr) + phpdbg_pagesize;
+ return (size_t) phpdbg_get_page_boundary((void *) ((size_t) addr + size - 1)) - (size_t) phpdbg_get_page_boundary(addr) + phpdbg_pagesize;
}
#endif
diff --git a/sapi/phpdbg/phpdbg_webdata_transfer.c b/sapi/phpdbg/phpdbg_webdata_transfer.c
new file mode 100644
index 0000000000..2f18b9d082
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_webdata_transfer.c
@@ -0,0 +1,170 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Bob Weinand <bwoebi@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "phpdbg_webdata_transfer.h"
+#include "ext/json/php_json.h"
+
+static int phpdbg_is_auto_global(char *name, int len TSRMLS_DC) {
+ int ret;
+ zend_string *str = zend_string_init(name, len, 0);
+ ret = zend_is_auto_global(str TSRMLS_CC);
+ efree(str);
+ return ret;
+}
+
+PHPDBG_API void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC) {
+#ifdef HAVE_JSON
+ smart_str buf = {0};
+ zval array;
+ HashTable *ht;
+ zval zv[9] = {{{0}}};
+
+ array_init(&array);
+ ht = Z_ARRVAL(array);
+
+ /* fetch superglobals */
+ {
+ phpdbg_is_auto_global(ZEND_STRL("GLOBALS") TSRMLS_CC);
+ /* might be JIT */
+ phpdbg_is_auto_global(ZEND_STRL("_ENV") TSRMLS_CC);
+ phpdbg_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC);
+ phpdbg_is_auto_global(ZEND_STRL("_REQUEST") TSRMLS_CC);
+ array_init(&zv[1]);
+ zend_hash_copy(Z_ARRVAL(zv[1]), &EG(symbol_table).ht, NULL);
+ Z_ARRVAL(zv[1])->pDestructor = NULL; /* we're operating on a copy! Don't double free zvals */
+ zend_hash_str_del(Z_ARRVAL(zv[1]), ZEND_STRL("GLOBALS")); /* do not use the reference to itself in json */
+ zend_hash_str_add(ht, ZEND_STRL("GLOBALS"), &zv[1]);
+ }
+
+ /* save php://input */
+ {
+ php_stream *stream;
+ zend_string *str;
+
+ stream = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir));
+ if ((str = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0))) {
+ ZVAL_STR(&zv[2], str);
+ } else {
+ ZVAL_EMPTY_STRING(&zv[2]);
+ }
+ Z_SET_REFCOUNT(zv[2], 1);
+ zend_hash_str_add(ht, ZEND_STRL("input"), &zv[2]);
+ }
+
+ /* change sapi name */
+ {
+ if (sapi_module.name) {
+ ZVAL_STRING(&zv[6], sapi_module.name);
+ } else {
+ Z_TYPE_INFO(zv[6]) = IS_NULL;
+ }
+ zend_hash_str_add(ht, ZEND_STRL("sapi_name"), &zv[6]);
+ Z_SET_REFCOUNT(zv[6], 1);
+ }
+
+ /* handle modules / extensions */
+ {
+ zend_module_entry *module;
+ zend_extension *extension;
+ zend_llist_position pos;
+
+ array_init(&zv[7]);
+ ZEND_HASH_FOREACH_PTR(&module_registry, module) {
+ zval *value = ecalloc(sizeof(zval), 1);
+ ZVAL_STRING(value, module->name);
+ zend_hash_next_index_insert(Z_ARRVAL(zv[7]), value);
+ } ZEND_HASH_FOREACH_END();
+ zend_hash_str_add(ht, ZEND_STRL("modules"), &zv[7]);
+
+ array_init(&zv[8]);
+ extension = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &pos);
+ while (extension) {
+ zval *value = ecalloc(sizeof(zval), 1);
+ ZVAL_STRING(value, extension->name);
+ zend_hash_next_index_insert(Z_ARRVAL(zv[8]), value);
+ extension = (zend_extension *) zend_llist_get_next_ex(&zend_extensions, &pos);
+ }
+ zend_hash_str_add(ht, ZEND_STRL("extensions"), &zv[8]);
+ }
+
+ /* switch cwd */
+ if (SG(options) & SAPI_OPTION_NO_CHDIR) {
+ char *ret = NULL;
+ char path[MAXPATHLEN];
+
+#if HAVE_GETCWD
+ ret = VCWD_GETCWD(path, MAXPATHLEN);
+#elif HAVE_GETWD
+ ret = VCWD_GETWD(path);
+#endif
+ if (ret) {
+ ZVAL_STRING(&zv[5], path);
+ Z_SET_REFCOUNT(zv[5], 1);
+ zend_hash_str_add(ht, ZEND_STRL("cwd"), &zv[5]);
+ }
+ }
+
+ /* get system ini entries */
+ {
+ zend_ini_entry *ini_entry;
+
+ array_init(&zv[3]);
+ ZEND_HASH_FOREACH_PTR(EG(ini_directives), ini_entry) {
+ zval *value = ecalloc(sizeof(zval), 1);
+ if (ini_entry->modified) {
+ if (!ini_entry->orig_value) {
+ efree(value);
+ continue;
+ }
+ ZVAL_STR(value, ini_entry->orig_value);
+ } else {
+ if (!ini_entry->value) {
+ efree(value);
+ continue;
+ }
+ ZVAL_STR(value, ini_entry->value);
+ }
+ zend_hash_add(Z_ARRVAL(zv[3]), ini_entry->name, value);
+ } ZEND_HASH_FOREACH_END();
+ zend_hash_str_add(ht, ZEND_STRL("systemini"), &zv[3]);
+ }
+
+ /* get perdir ini entries */
+ if (EG(modified_ini_directives)) {
+ zend_ini_entry *ini_entry;
+
+ array_init(&zv[4]);
+ ZEND_HASH_FOREACH_PTR(EG(ini_directives), ini_entry) {
+ zval *value = ecalloc(sizeof(zval), 1);
+ if (!ini_entry->value) {
+ efree(value);
+ continue;
+ }
+ ZVAL_STR(value, ini_entry->value);
+ zend_hash_add(Z_ARRVAL(zv[4]), ini_entry->name, value);
+ } ZEND_HASH_FOREACH_END();
+ zend_hash_str_add(ht, ZEND_STRL("userini"), &zv[4]);
+ }
+
+ /* encode data */
+ php_json_encode(&buf, &array, 0 TSRMLS_CC);
+ *msg = buf.s->val;
+ *len = buf.s->len;
+ zval_dtor(&array);
+#endif
+}
diff --git a/sapi/phpdbg/phpdbg_webdata_transfer.h b/sapi/phpdbg/phpdbg_webdata_transfer.h
new file mode 100644
index 0000000000..d70175ad99
--- /dev/null
+++ b/sapi/phpdbg/phpdbg_webdata_transfer.h
@@ -0,0 +1,27 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Bob Weinand <bwoebi@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef PHPDBG_WEBDATA_TRANSFER_H
+#define PHPDBG_WEBDATA_TRANSFER_H
+
+#include "zend.h"
+#include "phpdbg.h"
+
+PHPDBG_API void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC);
+
+#endif /* PHPDBG_WEBDATA_TRANSFER_H */
diff --git a/sapi/phpdbg/phpdbg_win.c b/sapi/phpdbg/phpdbg_win.c
index b55abd9e1b..b0cbdf267a 100644
--- a/sapi/phpdbg/phpdbg_win.c
+++ b/sapi/phpdbg/phpdbg_win.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
diff --git a/sapi/phpdbg/phpdbg_win.h b/sapi/phpdbg/phpdbg_win.h
index 3f87c216f6..68c3052790 100644
--- a/sapi/phpdbg/phpdbg_win.h
+++ b/sapi/phpdbg/phpdbg_win.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
diff --git a/sapi/phpdbg/tests/commands/0002_set.test b/sapi/phpdbg/tests/commands/0002_set.test
index 468ac6d9ea..6a14a15adc 100644
--- a/sapi/phpdbg/tests/commands/0002_set.test
+++ b/sapi/phpdbg/tests/commands/0002_set.test
@@ -8,7 +8,7 @@
# setting error color
# setting notice color
# Failed to find breakpoint #0
-# oplog disabled
+# [Oplog off]
# opened oplog test.log
# nothing
#################################################
diff --git a/sapi/phpdbg/tests/commands/0102_print.test b/sapi/phpdbg/tests/commands/0102_print.test
index de4acb7651..c174564e07 100644
--- a/sapi/phpdbg/tests/commands/0102_print.test
+++ b/sapi/phpdbg/tests/commands/0102_print.test
@@ -4,15 +4,14 @@
# expect: TEST::FORMAT
# options: -rr
#################################################
-#[User Class: test]
-#Methods (3):
+#[User Class: test (3 methods)]
#L%d-%d test::testMethod() %s
# L%d %s ZEND_RETURN C%d <unused> <unused>
# L%d-%d test::testPrivateMethod() %s
# L%d %s ZEND_RETURN C%d <unused> <unused>
# L%d-%d test::testProtectedMethod() %s
# L%d %s ZEND_RETURN C%d <unused> <unused>
-#[User Method testMethod]
+#[User Method testMethod (1 ops)]
# L%d-%d test::testMethod() %s
# L%d %s ZEND_RETURN C%d <unused> <unused>
#################################################
diff --git a/sapi/phpdbg/tests/commands/0104_clean.test b/sapi/phpdbg/tests/commands/0104_clean.test
index c7a579be17..d50903c479 100644
--- a/sapi/phpdbg/tests/commands/0104_clean.test
+++ b/sapi/phpdbg/tests/commands/0104_clean.test
@@ -4,11 +4,11 @@
# expect: TEST::FORMAT
# options: -rr
#################################################
-#[Cleaning Execution Environment]
-#Classes %d
-#Functions %d
-#Constants %d
-#Includes %d
+#Cleaning Execution Environment
+#Classes %d
+#Functions %d
+#Constants %d
+#Includes %d
#[Nothing to execute!]
#################################################
clean
diff --git a/sapi/phpdbg/tests/commands/0105_clear.test b/sapi/phpdbg/tests/commands/0105_clear.test
index b547b0d6ba..8ce1002491 100644
--- a/sapi/phpdbg/tests/commands/0105_clear.test
+++ b/sapi/phpdbg/tests/commands/0105_clear.test
@@ -4,7 +4,7 @@
# expect: TEST::FORMAT
# options: -rr
#################################################
-#[Clearing Breakpoints]
+#Clearing Breakpoints
#File%w%d
#Functions%w%d
#Methods%w%d
diff --git a/sapi/phpdbg/tests/commands/0106_compile.test b/sapi/phpdbg/tests/commands/0106_compile.test
index 7193600ea3..b4d801670b 100644
--- a/sapi/phpdbg/tests/commands/0106_compile.test
+++ b/sapi/phpdbg/tests/commands/0106_compile.test
@@ -4,9 +4,9 @@
# expect: TEST::FORMAT
# options: -rr
#################################################
-#[Attempting compilation of %s]
-#[Success]
+#[Successful compilation of %s]
#Hello World
+#[Script ended normally]
#################################################
<:
define('OUT',
diff --git a/sapi/phpdbg/tests/run-tests.php b/sapi/phpdbg/tests/run-tests.php
index 1cc31d815e..4afb64561c 100644
--- a/sapi/phpdbg/tests/run-tests.php
+++ b/sapi/phpdbg/tests/run-tests.php
@@ -389,7 +389,7 @@ namespace phpdbg\testing {
} break;
default: {
- $this->$chunks[0] = $chunks[1];
+ $this->{$chunks[0]} = $chunks[1];
}
}
} else switch(substr($trim, 1, 1)) {
diff --git a/sapi/phpdbg/xml.md b/sapi/phpdbg/xml.md
new file mode 100644
index 0000000000..7871b31376
--- /dev/null
+++ b/sapi/phpdbg/xml.md
@@ -0,0 +1,651 @@
+phpdbg XML format
+=================
+
+Common attributes
+=================
+
+severity
+--------
+
+- indicates the genre of phpdbg system output
+- usually one of these values:
+ - normal
+ - notice
+ - error
+
+msgout
+------
+
+- text message output related to the xml data (e.g. &lt;intro severity="normal" help="help" msgout="To get help using phpdbg type &amp;quot;help&amp;quot; and press enter" />)
+
+req
+---
+
+- the request id, if one was passed to the last command (via -r %d, where %d is the id) (and the output is related to that message)
+
+file
+----
+
+- refers to a filename
+
+method
+------
+
+- format classname::methodname
+- refers to a method
+
+function
+--------
+
+- refers to a function
+
+symbol
+------
+
+- either function or method (is method if "::" are present)
+
+opline
+------
+
+- in hexadecimal format
+- refers to a specific pointer to a (zend_)op
+
+opcode
+------
+
+- refers to an opcode (ZEND_*)
+
+type
+----
+
+- general attribute for most errors, describes the genre of the error
+
+General tags
+============
+
+intro
+-----
+
+- appears on startup if -q flag wasn't provided as command line arg
+- before any input possibility
+- attributes may be spread over multiple tags
+- wrapped in &lt;intros> tag
+
+### attributes ###
+
+- version: current phpdbg version (as string)
+- help: command name for help
+- report: URL for bug reporting
+
+
+phpdbg
+------
+
+- general text message output from phpdbg system
+
+stream
+------
+
+- any output by PHP itself (e.g. &lt;stream type="stdout">test&lt;/stream>)
+
+### attributes ###
+
+- type: stderr or stdout
+
+php
+---
+
+- php error output
+
+### attributes ###
+
+- msg: the error message
+
+
+General error tags
+==================
+
+command
+-------
+
+- general errors about commands
+
+### possible attributes ###
+
+- type
+ - toomanyargs: more arguments than allowed
+ - noarg: argument missing
+ - wrongarg: wrong type of argument (e.g. letters instead of integer)
+ - toofewargs: not enough arguments
+ - notfound: command (or subcommand) doesn't exist
+ - ambiguous: command was ambiguous
+ - invalidcommand: command input is totally invalid
+ - (nostack: should not happen: is an internal error)
+ - (emptystack: should not happen: is an internal error)
+- command: passed command
+- subcommand: passed subcommand (present if the error is related to the subcommand)
+- expected: count of expected arguments
+- got: type of argument for type "wrongarg"
+- num: if possible, information about which parameter had a wrong argument
+
+inactive
+--------
+
+- by type
+ - op_array: nothing was yet compiled (probably because no execution context set)
+ - symbol_table: no symbol table present (not yet initiailized or already destructed)
+ - noexec: not in execution
+ - memory_manager: using the native memory manager (malloc, free, realloc) instead of e.g. the Zend MM
+ - notfound: file not found
+ - nocontext: execution context was not set (or compilation had failed)
+ - isrunning: command requires no running script
+
+
+Commands
+========
+
+export
+------
+
+- tag: &lt;exportbreakpoint />
+- usually triggered by successful export command
+- may appear when cleaning to temporary store breakpoints
+- errors by type
+ - openfailure: could not create file
+
+### attributes ###
+
+- count: number of exported breakpoints
+
+break / info break
+------------------
+
+- General tag for breakpoint creation, deletion and hits is "&lt;breakpoint />"
+
+### possible attributes ###
+
+- id: the breakpoint id (if the leave command was executed, the id has the value "leave")
+- num: the nth opline of a function/method/file
+- add: has value "success"/"fail": a brekpoint was successfully/not added
+- pending: the breakpoint is waiting for resolving (e.g. a file opline on a not yet loaded file)
+- deleted: has value "success"/"fail": a breakpoint was successfully/not deleted
+- eval: the condition on conditional breakpoints
+- file
+- opline
+- opcode
+- symbol
+- function
+- method
+- line
+
+
+- listing breakpoints always in a container element "&lt;breakpoints>"
+ - Child nodes:
+ - function
+ - method
+ - file
+ - opline
+ - methodopline
+ - functionopline
+ - fileopline
+ - evalfunction
+ - evalfunctionopline
+ - evalmethod
+ - evalmethodopline
+ - evalfile
+ - evalopline
+ - eval
+ - opcode
+ - attributes:
+ - name: name of the symbol (function/method/file/opcode)
+ - disabled: empty value if enabled, non-empty if enabled
+
+- errors (by type)
+ - exists: the breakpoint already exists
+ - maxoplines: tries to break at an opline (usedoplinenum) higher than the number of present oplines (in maxoplinenum)
+ - nomethod: method doesn't exist
+ - internalfunction: one cannot break on an opline of an internal function
+ - notregular: tries to set a breakpoint in not a regular file
+ - (invalidparameter: should not happen: is an internal error)
+
+frame
+-----
+
+- General tag for frames is "&lt;frame>"
+- always has id attribute; if it only has id attribute, it just indicates current frame number, no other elements follow
+- may contain other elements (of type &lt;arg>) when contained in &lt;backtrace> tag
+- &lt;arg> always contains a &lt;stream> element, the value of the variable
+
+### possible attributes ###
+
+- id: the frame id, current frame has id 0 (frames with internal function calls have the same id than their called frame)
+- symbol ("{main}" is root frame)
+- file
+- line
+- internal: has value "internal" when being an internal function call (one cannot inspect that frame)
+
+- being an error: (by type)
+ - maxnum: tried to access a frame with a number heigher than existing (or &lt; 0)
+
+### attributes on &lt;arg> ###
+
+- variadic: has a non-empty value if the argument is variadic
+- name: variable name of parameter
+
+info (subcommands)
+------------------
+
+### break ###
+
+- See above ("break / info break")
+
+### files ###
+
+- lists included files
+- &lt;includedfileinfo num="" /> with num having an integer value, indicating the number of included files
+- &lt;includedfile name=""/>: one per file, with name being the file path of the included file
+
+### error ###
+
+- gets last error
+- &lt;lasterror error="" (file="" line="") />
+- error attribute contains the last error as a string, is empty if there's no last error
+
+### vars / globals ###
+
+- &lt;variableinfo num="" /> with num having an integer value, indicating the number of (local or superglobal) variables
+- if info vars was used it'll have also one of these attributes:
+ - method
+ - function
+ - file
+ - opline
+- for each variable there is a &lt;variable> followed by a &lt;variabledetails> element
+- &lt;variable address="" refcount="" type="" name="" />
+ - address: pointer to zval (hexadecimal)
+ - refcount: refcount of zval
+ - type: the variable type (long, string, ...). If the value is "unknown", the other attributes are meaningless
+ - name: the name of the variable
+ - refstatus: empty if the zval is not a reference
+ - class: the class the object in the zval is an instance of
+ - resource: the type of the resource in the zval
+
+### literal ###
+
+- &lt;literalinfo num="" /> with num having an integer value, indicating the number of literals, optional arguments are:
+ - method
+ - function
+ - file
+ - opline
+- for each literal there is a &lt;literal> followed by a &lt;stream type="stdout"> which prints the value of the literal
+- &lt;literal id="" />: where id is the internal identifier of the literal
+
+### memory ###
+
+- Format:
+
+ &lt;meminfo />
+ &lt;current />
+ &lt;used mem="" />
+ &lt;real mem="" />
+ &lt;peak />
+ &lt;used mem="" />
+ &lt;real mem="" />
+
+- mem is an attribute whose value is a float. The memory is given in kilobytes (1 kB == 1024 bytes)
+
+### classes ###
+
+- &lt;classinfo num="" /> with num having an integer value, indicating the number of loaded user-defined classes
+- Each class is enumerated with first a &lt;class>, then an optional &lt;parents> container and then a &lt;classsource> element
+- The &lt;parents> container contains the &lt;class> elements of the parent of the last &lt;class> element.
+- &lt;class type="" flags="" name="" methodcount="" />
+ - type: either "User" or "Internal"
+ - flags: either "Interface", "Class" or "Abstract Class"
+- &lt;classsource /> where the class was defined, if there are no attributes, location is unknown, usually defined by
+ - file
+ - line
+
+### funcs ###
+
+- &lt;functioninfo num="" /> with num having an integer value, indicating the number of loaded user-defined functions
+- Each class is enumerated with first a &lt;function> and then a &lt;functionsource> element
+- &lt;function name="" />
+- &lt;functionsource /> where the function was defined, if there are no attributes, location is unknown, usually defined by
+ - file
+ - line
+
+list
+----
+
+- consists of &lt;line> elements wrapped in a &lt;list> container
+- &lt;list file=""> is the container element with file being the filename
+- &lt;line line="" code="" /> with value of code being the whole line of code in the line specified in the line attribute
+ - current: this attribute is set to "current" if that line is the line where the executor currently is
+
+print
+-----
+
+### without a subcommand ###
+
+- &lt;print> elements are wrapped in a &lt;printinfo> element
+- there may be a variable number of &lt;print> elements with a variable count of args inside the &lt;printinfo> element
+- possible args are:
+ - readline: yes/no - readline enabled or disabled
+ - libedit: yes/no - libedit enabled or disabled
+ - context: current executing context
+ - compiled: yes/no - are there actual compiled ops?
+ - stepping: @@ TODO (meaningless for now) @@
+ - quiet: on/off - should it always print the opline being currently executed?
+ - oplog: on/off - are oplines logged in a file?
+ - ops: number of opcodes in current executing context
+ - vars: number of compiled variables (CV)
+ - executing: yes/no - in executor?
+ - vmret: the return value of the last executed opcode
+ - default: continue
+ - 1: return from vm
+ - 2: enter stack frame
+ - 3: leave stack frame
+ - classes: number of classes
+ - functions: number of functions
+ - constants: number of constants
+ - includes: number of included files
+
+### with a subcommand ###
+
+- introduced by &lt;printinfo num="" /> (except for print opline) with num being the number of opcodes and one of these args:
+ - file
+ - method
+ - function
+ - class (then also type and flags attributes, see info classes command for their meanings)
+ - symbol (also type and flags attributes; here the value of flags is either "Method" or "Function")
+- if there is a class method, the methods are all wrapped in a &lt;printmethods> container
+- then comes a &lt;printoplineinfo type="" /> where type is either "User" or "Internal"
+- the &lt;printoplineinfo> has either a method or a function attribute
+- if the type is "Internal"
+ - there are no oplines, it's an internal method or function
+- if the type is "User"
+ - it has these attributes
+ - startline: the first line of code where the method or function is defined
+ - endline: the lastt line of code where the method or function is defined
+ - file: the file of code where the method or function is defined
+ - is followed by the oplines of that method or function (&lt;print> elements)
+- &lt;print line="%u" opline="%p" opcode="%s" op="%s" />
+- in case of print opline it emits a single &lt;opline line="" opline="" opcode="" op="" file="" />
+
+exec
+----
+
+- command executing and compiling a given file
+ - &lt;exec type="unset" context="" />: indicates unsetting of the old context
+ - &lt;exec type="unsetops" />: indicates unsetting of the old compiled opcodes
+ - &lt;exec type="unchanged" />: same execution context choosen again
+ - &lt;exec type="set" context="" />: indicates setting of the new context
+- errors by tag
+ - &lt;compile>
+ - openfailure: couldn't open file
+ - compilefailure: The file indicated in context couldn't be compiled
+ - &lt;exec>
+ - invalid: given context (attribute) is not matching a valid file or symlink
+ - notfound: given context (attribute) does not exist
+
+run / &lt;stop> tag
+-------------------
+
+- runs the script (set via exec command)
+- &lt;stop type="end" />: script execution ended normally
+- (error) &lt;stop type="bailout" /> the VM bailed out (usually because there was some error)
+- compile failures see under exec, errors, &lt;compile>
+
+step
+----
+
+- steps by one line or opcode (as defined via set stepping) default is one line
+- returns back to the executor
+
+continue
+--------
+
+- returns back to the executor
+
+until
+-----
+
+- temporarily disables all the breakpoints on that line until that line was left once
+- returns back to the executor
+
+finish
+------
+
+- temporarily disables all the breakpoints until the end of the current frame
+- returns back to the executor
+
+leave
+------
+
+- temporarily disables all the breakpoints past the end of the current frame and then stops
+- returns back to the executor
+
+back
+----
+
+- prints backtrace
+- see frame command
+
+ev
+--
+
+- eval()uates some code
+- output wrapped in &lt;eval> tags
+
+sh
+--
+
+- executes shell command
+- still pipes to stdout ... without wrapping &lt;stream> !!! (@@ TODO @@)
+
+source
+------
+
+- executes a file in .phpdbginit format
+- errors by type
+ - notfound: file not found
+
+register
+--------
+
+- registers a function to be used like a command
+- &lt;register function="" />: successfully registered function
+- errors by type
+ - notfound: no such function
+ - inuse: function already registered
+
+quit
+----
+
+- quits phpdbg
+- if successful connection will be closed...
+
+clean
+-----
+
+- cleans environment (basically a shutdown + new startup)
+- &lt;clean> tags wrapped in a &lt;cleaninfo> container
+- possible attributes of &lt;clean> tag
+ - classes: number of classes
+ - functions: number of functions
+ - constants: number of constants
+ - includes: number of included files
+
+clear
+-----
+
+- removes all breakpoints
+- &lt;clear> tags wrapped in a &lt;clearinfo> container
+- possible attributes of &lt;clear> tag (value is always the number of defined breakpoints of that type)
+ - files
+ - functions
+ - methods
+ - oplines
+ - fileoplines
+ - functionoplines
+ - methodoplines
+ - eval
+
+watch
+-----
+
+- watchpoints generally are identified by a variable (one may need to switch frames first...)
+- &lt;watch variable="" />, &lt;watchrecursive variable="" /> and &lt;watcharray variable="" /> (normal, array, recursive)
+- &lt;watch> if error, by type:
+ - undefined: tried to set a watchpoint on a not (yet) defined variable
+ - notiterable: element which is tried to be accessed as an object or array is nor array nor object
+ - invalidinput: generally malformed input
+- &lt;watchdelete variable="" />: when "watch delete" was used on a watchpoint
+- (error) &lt;watchdelete type="nowatch" />: that watchpoint doesn't exist, so couldn't be deleted
+- for hit watchpoints etc., see Other tags, &lt;watch*>
+- when using watch list, &lt;watchvariable> elements are wrapped in a &lt;watchlist> container
+ - &lt;watchvariable variable="" on="" type="" />
+ - variable: watched variable (may be a variable of another scope!)
+ - on: values are array or variable, depending on what is watched
+ - type: values are recursive or simple, depending on whether the watchpoint is checked recursively or not
+
+set
+---
+
+- a general error is type="wrongargs" where a wrong argument was passed to a subcommand; tag is then &lt;set*>
+
+### prompt ###
+
+- without other args, a &lt;setpromt str="" /> tag is emitted where the value of the str attribue is the value of the prompt
+- when there is another arg, the prompt is changed to that arg, no further xml answer
+
+### break ###
+
+- enables / disables a given breakpoint silently with no further xml answer
+- if the boolean switch is omitted, it emits current state in a &lt;setbreak id="" active="" /> where active is on or off
+- error with type="nobreak", when no breakpoint with the given id exists
+
+### breaks ###
+
+- generally enables / disables breakpoint functionality silently with no futher xml answer
+- if the boolean switch is omitted, it emits current state in a &lt;setbreaks active="" /> where active is on or off
+
+### color ###
+
+- sets the color on prompt, error or notices
+- &lt;setcolor type="" color="" code="" />: code is the color code of color, type is either:
+ - prompt
+ - error
+ - notice
+- errors by type:
+ - nocolor: color doesn't exist
+ - invalidtype: type wasn't one of the three allowed types
+
+### colors ###
+
+- generally enables / disables colors silently with no further xml answer
+- if the boolean switch is omitted, it emits current state in a &lt;setcolors active="" /> where active is on or off
+
+### oplog ###
+
+- sets oplog
+- (error) &lt;setoplog type="openfailure" file="" /> when it couldn't open the passed file path
+- &lt;setoplog type="closingold" /> is emitted when there was a previous open oplog (and a file is passed)
+- if no further argument is passed, it emits current state in a &lt;setoplog active="" /> where active is on or off
+
+### quiet ###
+
+- generally enables / disables quietness silently with no further xml answer
+- if the boolean switch is omitted, it emits current state in a &lt;setquiet active="" /> where active is on or off
+
+### setpping ###
+
+- sets stepping to either opcode or line (so a step command will either advance one op or one line)
+- if no further argument is passed, it emits current state in a &lt;setoplog type="" /> where active is opcode or line
+
+### refcount ###
+
+- generally enables / disables showing of refcount in watchpoint breaks silently with no further xml answer
+- if the boolean switch is omitted, it emits current state in a &lt;setrefcount active="" /> where active is on or off
+
+wait
+----
+
+- internally executes exec, so exec will output first (if binding to socket worked)
+
+### attributes ###
+
+- import: has value "success"/"fail"
+- missingmodule/missingextension: modules/extensions loaded in the target SAPI, but not in phpdbg
+
+### errors (by type) ###
+
+- nosocket: couldn't establish socket
+- invaliddata: invalid JSON passed to socket
+
+dl
+--
+
+- loads a module or Zend extension at a given path
+- if a relative path is passed, it's relative to the extension_dir ini setting
+
+### attributes ###
+
+- extensiontype: "Zend extension" or "module"
+- name: the extension name
+- path: the path where it was loaded
+
+### errors (by type) ###
+
+- unsupported: dynamic extension loading is unsupported
+- relpath: relative path given, but no extension_dir defined
+- unknown: general error with internal DL_LOAD() (for message see msg attribute)
+- wrongapi: wrong Zend engine version (apineeded / apiinstalled attributes give information about the API versions)
+- wrongbuild: unmatched build versions (buildneeded / buildinstalled attributes give information about the build versions)
+- registerfailure: registering module failed
+- startupfailure: couldn't startup Zend extension / module
+- initfailure: couldn't initialize module
+- nophpso: passed shared object is not a valid Zend extension nor module
+
+- errors may have the module or extension attribute when their name is already known at the point of failure
+
+Other tags
+==========
+
+&lt;signal>
+-----------
+
+- received caught signal
+
+### attributes ###
+
+- type: type of signal (e.g. SIGINT)
+
+### by type ###
+
+- SIGINT: interactive mode is entered...
+
+&lt;watch*>
+-----------
+
+- generally emitted on hit watchpoint
+- &lt;watchdelete variable="" />: when a variable was unset, the watchpoint is removed too
+- &lt;watchhit variable="" />: when ever a watched variable is changed, followed by a &lt;watchdata> container
+- &lt;watchdata> may contain
+ - for watchpoints on variables:
+ - each of these &lt;watch*> tags conatins a type attribute whose value is either "old" or "new")
+ - &lt;watchvalue type="" inaccessible="inaccessible" />: old value is inaccessible
+ - &lt;watchvalue type=""> may contain a &lt;stream> element which indicates the old/new (type attribute) value of the variable
+ - &lt;watchrefcount type="" refcount="" isref="" />: old/new (type attribute) refcount and isref, both numbers
+ - isref: if the value is 0, it's not a reference, else it is one
+ - for watchpoints on arrays:
+ - &lt;watchsize> inspects size variations of an array (the sum):
+ - removed: number of elements removed
+ - added: number of elements added
+ - &lt;watcharrayptr>: if this tag appears, the internal pointer of the array way changed
+
+&lt;signalsegv>
+---------------
+
+- generally emitted when data couldn't be fetched (e.g. by accessing inconsistent data); only used in hard interrupt mode
+- it might mean that data couldn't be fetched at all, or that only incomplete data was fetched (e.g. when a fixed number of following attributes are fetched, this tag will mark a stop of fetching if none or not all tags were printed)
diff --git a/sapi/phpdbg/zend_mm_structs.h b/sapi/phpdbg/zend_mm_structs.h
new file mode 100644
index 0000000000..ca64069e0f
--- /dev/null
+++ b/sapi/phpdbg/zend_mm_structs.h
@@ -0,0 +1,102 @@
+#ifndef ZEND_MM_STRUCTS_H
+#define ZEND_MM_STRUCTS_H
+
+/* structs and macros defined in Zend/zend_alloc.c
+ Needed for realizing watchpoints and sigsafe memory */
+
+#include "zend.h"
+
+#ifndef ZEND_MM_COOKIES
+# define ZEND_MM_COOKIES ZEND_DEBUG
+#endif
+
+#define ZEND_MM_CACHE 1
+#ifndef ZEND_MM_CACHE_STAT
+# define ZEND_MM_CACHE_STAT 0
+#endif
+
+typedef struct _zend_mm_block_info {
+#if ZEND_MM_COOKIES
+ size_t _cookie;
+#endif
+ size_t _size;
+ size_t _prev;
+} zend_mm_block_info;
+
+typedef struct _zend_mm_small_free_block {
+ zend_mm_block_info info;
+#if ZEND_DEBUG
+ unsigned int magic;
+#ifdef ZTS
+ THREAD_T thread_id;
+#endif
+#endif
+ struct _zend_mm_free_block *prev_free_block;
+ struct _zend_mm_free_block *next_free_block;
+} zend_mm_small_free_block;
+
+typedef struct _zend_mm_free_block {
+ zend_mm_block_info info;
+#if ZEND_DEBUG
+ unsigned int magic;
+#ifdef ZTS
+ THREAD_T thread_id;
+#endif
+#endif
+ struct _zend_mm_free_block *prev_free_block;
+ struct _zend_mm_free_block *next_free_block;
+
+ struct _zend_mm_free_block **parent;
+ struct _zend_mm_free_block *child[2];
+} zend_mm_free_block;
+
+#define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \
+ (zend_mm_free_block *) ((char *)&heap->free_buckets[index * 2] + \
+ sizeof(zend_mm_free_block *) * 2 - \
+ sizeof(zend_mm_small_free_block))
+
+#define ZEND_MM_REST_BUCKET(heap) \
+ (zend_mm_free_block *)((char *)&heap->rest_buckets[0] + \
+ sizeof(zend_mm_free_block *) * 2 - \
+ sizeof(zend_mm_small_free_block))
+
+#define ZEND_MM_NUM_BUCKETS (sizeof(size_t) << 3)
+struct _zend_mm_heap {
+ int use_zend_alloc;
+ void *(*_malloc)(size_t);
+ void (*_free)(void *);
+ void *(*_realloc)(void *, size_t);
+ size_t free_bitmap;
+ size_t large_free_bitmap;
+ size_t block_size;
+ size_t compact_size;
+ zend_mm_segment *segments_list;
+ zend_mm_storage *storage;
+ size_t real_size;
+ size_t real_peak;
+ size_t limit;
+ size_t size;
+ size_t peak;
+ size_t reserve_size;
+ void *reserve;
+ int overflow;
+ int internal;
+#if ZEND_MM_CACHE
+ unsigned int cached;
+ zend_mm_free_block *cache[ZEND_MM_NUM_BUCKETS];
+#endif
+ zend_mm_free_block *free_buckets[ZEND_MM_NUM_BUCKETS*2];
+ zend_mm_free_block *large_free_buckets[ZEND_MM_NUM_BUCKETS];
+ zend_mm_free_block *rest_buckets[2];
+ int rest_count;
+#if ZEND_MM_CACHE_STAT
+ struct {
+ int count;
+ int max_count;
+ int hit;
+ int miss;
+ } cache_stat[ZEND_MM_NUM_BUCKETS+1];
+#endif
+};
+
+#endif
diff --git a/travis/compile.sh b/travis/compile.sh
index 20228cda5a..9add843a2e 100755
--- a/travis/compile.sh
+++ b/travis/compile.sh
@@ -13,6 +13,7 @@ fi
./configure --quiet \
$DEBUG \
$TS \
+--enable-phpdbg \
--enable-fpm \
--with-pdo-mysql=mysqlnd \
--with-mysql=mysqlnd \