summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS8
-rw-r--r--Zend/tests/closure_033.phpt2
-rw-r--r--Zend/tests/nested_method_and_function.phpt29
-rw-r--r--Zend/zend_compile.c7
-rw-r--r--Zend/zend_list.c12
-rw-r--r--ext/pdo_oci/oci_statement.c21
-rw-r--r--sapi/phpdbg/phpdbg.c2
-rw-r--r--sapi/phpdbg/phpdbg.h5
-rw-r--r--sapi/phpdbg/phpdbg_print.c74
9 files changed, 122 insertions, 38 deletions
diff --git a/NEWS b/NEWS
index da4c43b2b9..3724350431 100644
--- a/NEWS
+++ b/NEWS
@@ -270,7 +270,7 @@
. Added "v" DateTime format modifier to get the 3-digit version of fraction
of seconds. (Mariano Iglesias)
. Implemented FR #69089: Added DateTime::RFC3339_EXTENDED to output in
- RFC3339 Extended format which includes fraction of seconds (Mariano
+ RFC3339 Extended format which includes fraction of seconds. (Mariano
Iglesias)
- DBA:
@@ -431,9 +431,9 @@
- Zip:
. Added ZipArchive::setCompressionName and ZipArchive::setCompressionIndex
- methods (Remi, Cedric Delmas)
- . Update bundled libzip to 1.0.1 (Remi, Anatol)
- . Fixed bug #67161. (ZipArchive::getStream() returns NULL for certain file)
+ methods. (Remi, Cedric Delmas)
+ . Update bundled libzip to 1.0.1. (Remi, Anatol)
+ . Fixed bug #67161 (ZipArchive::getStream() returns NULL for certain file).
(Christoph M. Becker)
<<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>
diff --git a/Zend/tests/closure_033.phpt b/Zend/tests/closure_033.phpt
index d92716aacc..c83a53898d 100644
--- a/Zend/tests/closure_033.phpt
+++ b/Zend/tests/closure_033.phpt
@@ -23,7 +23,7 @@ $o->func();
?>
===DONE===
--EXPECTF--
-Test::{closure}()
+{closure}()
Fatal error: Uncaught Error: Call to private method Test::func() from context '' in %sclosure_033.php:%d
Stack trace:
diff --git a/Zend/tests/nested_method_and_function.phpt b/Zend/tests/nested_method_and_function.phpt
new file mode 100644
index 0000000000..46d55ddc52
--- /dev/null
+++ b/Zend/tests/nested_method_and_function.phpt
@@ -0,0 +1,29 @@
+--TEST--
+active_class_entry must be always correct (__METHOD__ should not depend on declaring function ce)
+--FILE--
+<?php
+
+namespace Baz;
+
+class Foo {
+ public static function bar() {
+ function foo() {
+ var_dump(__FUNCTION__);
+ var_dump(__METHOD__);
+ }
+
+ foo();
+
+ var_dump(__FUNCTION__);
+ var_dump(__METHOD__);
+ }
+}
+
+Foo::bar();
+
+?>
+--EXPECT--
+string(7) "Baz\foo"
+string(7) "Baz\foo"
+string(3) "bar"
+string(12) "Baz\Foo::bar"
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 6808eedbc6..4cf2a57f75 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -4793,6 +4793,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast) /* {{{ */
zend_bool is_method = decl->kind == ZEND_AST_METHOD;
zend_op_array *orig_op_array = CG(active_op_array);
+ zend_class_entry *orig_ce = CG(active_class_entry);
zend_op_array *op_array = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
zend_oparray_context orig_oparray_context;
@@ -4817,6 +4818,11 @@ void zend_compile_func_decl(znode *result, zend_ast *ast) /* {{{ */
}
CG(active_op_array) = op_array;
+
+ if (!is_method) {
+ CG(active_class_entry) = NULL;
+ }
+
zend_oparray_context_begin(&orig_oparray_context);
if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
@@ -4852,6 +4858,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast) /* {{{ */
/* Pop the loop variable stack separator */
zend_stack_del_top(&CG(loop_var_stack));
+ CG(active_class_entry) = orig_ce;
CG(active_op_array) = orig_op_array;
}
/* }}} */
diff --git a/Zend/zend_list.c b/Zend/zend_list.c
index 261489b4a1..e38246ee87 100644
--- a/Zend/zend_list.c
+++ b/Zend/zend_list.c
@@ -102,12 +102,14 @@ ZEND_API zend_resource* zend_register_resource(void *rsrc_pointer, int rsrc_type
ZEND_API void *zend_fetch_resource2(zend_resource *res, const char *resource_type_name, int resource_type1, int resource_type2)
{
- if (resource_type1 == res->type) {
- return res->ptr;
- }
+ if (res) {
+ if (resource_type1 == res->type) {
+ return res->ptr;
+ }
- if (resource_type2 == res->type) {
- return res->ptr;
+ if (resource_type2 == res->type) {
+ return res->ptr;
+ }
}
if (resource_type_name) {
diff --git a/ext/pdo_oci/oci_statement.c b/ext/pdo_oci/oci_statement.c
index 868e69f77a..9c2e149935 100644
--- a/ext/pdo_oci/oci_statement.c
+++ b/ext/pdo_oci/oci_statement.c
@@ -51,7 +51,7 @@
} \
} while(0)
-static php_stream *oci_create_lob_stream(pdo_stmt_t *stmt, OCILobLocator *lob);
+static php_stream *oci_create_lob_stream(zval *dbh, pdo_stmt_t *stmt, OCILobLocator *lob);
static int oci_stmt_dtor(pdo_stmt_t *stmt) /* {{{ */
{
@@ -377,7 +377,7 @@ static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *pa
* wanted to bind a lob locator into it from the query
* */
- stm = oci_create_lob_stream(stmt, (OCILobLocator*)P->thing);
+ stm = oci_create_lob_stream(&stmt->database_object_handle, stmt, (OCILobLocator*)P->thing);
if (stm) {
OCILobOpen(S->H->svc, S->err, (OCILobLocator*)P->thing, OCI_LOB_READWRITE);
php_stream_to_zval(stm, parameter);
@@ -614,6 +614,7 @@ struct _oci_lob_env {
typedef struct _oci_lob_env oci_lob_env;
struct oci_lob_self {
+ zval dbh;
pdo_stmt_t *stmt;
pdo_oci_stmt *S;
OCILobLocator *lob;
@@ -666,10 +667,14 @@ static size_t oci_blob_read(php_stream *stream, char *buf, size_t count)
static int oci_blob_close(php_stream *stream, int close_handle)
{
struct oci_lob_self *self = (struct oci_lob_self *)stream->abstract;
- /* pdo_stmt_t *stmt = self->stmt; */
+ pdo_stmt_t *stmt = self->stmt;
if (close_handle) {
+ zend_object *obj = &stmt->std;
+
OCILobClose(self->E->svc, self->E->err, self->lob);
+ zval_ptr_dtor(&self->dbh);
+ GC_REFCOUNT(obj)--;
efree(self->E);
efree(self);
}
@@ -709,10 +714,12 @@ static php_stream_ops oci_blob_stream_ops = {
NULL
};
-static php_stream *oci_create_lob_stream(pdo_stmt_t *stmt, OCILobLocator *lob)
+static php_stream *oci_create_lob_stream(zval *dbh, pdo_stmt_t *stmt, OCILobLocator *lob)
{
php_stream *stm;
struct oci_lob_self *self = ecalloc(1, sizeof(*self));
+
+ ZVAL_COPY_VALUE(&self->dbh, dbh);
self->lob = lob;
self->offset = 1; /* 1-based */
self->stmt = stmt;
@@ -724,6 +731,10 @@ static php_stream *oci_create_lob_stream(pdo_stmt_t *stmt, OCILobLocator *lob)
stm = php_stream_alloc(&oci_blob_stream_ops, self, 0, "r+b");
if (stm) {
+ zend_object *obj;
+ obj = &stmt->std;
+ Z_ADDREF(self->dbh);
+ GC_REFCOUNT(obj)++;
return stm;
}
@@ -747,7 +758,7 @@ static int oci_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, size_t *len
if (C->dtype == SQLT_BLOB || C->dtype == SQLT_CLOB) {
if (C->data) {
- *ptr = (char*)oci_create_lob_stream(stmt, (OCILobLocator*)C->data);
+ *ptr = (char*)oci_create_lob_stream(&stmt->database_object_handle, stmt, (OCILobLocator*)C->data);
OCILobOpen(S->H->svc, S->err, (OCILobLocator*)C->data, OCI_LOB_READONLY);
}
*len = (size_t) 0;
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c
index 85a085b26e..3ee0bde97f 100644
--- a/sapi/phpdbg/phpdbg.c
+++ b/sapi/phpdbg/phpdbg.c
@@ -447,7 +447,7 @@ static PHP_FUNCTION(phpdbg_end_oplog)
phpdbg_oplog_entry *cur = PHPDBG_G(oplog_list)->start;
phpdbg_oplog_list *prev = PHPDBG_G(oplog_list)->prev;
- HashTable *options;
+ HashTable *options = NULL;
zval *option_buffer;
zend_bool by_function = 0;
zend_bool by_opcode = 0;
diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h
index 7fb8083793..f900866211 100644
--- a/sapi/phpdbg/phpdbg.h
+++ b/sapi/phpdbg/phpdbg.h
@@ -100,9 +100,8 @@
/* {{{ 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_ISSUES "http://bugs.php.net/report.php"
+#define PHPDBG_VERSION "0.5.0"
#define PHPDBG_INIT_FILENAME ".phpdbginit"
#define PHPDBG_DEFAULT_PROMPT "prompt>"
/* }}} */
diff --git a/sapi/phpdbg/phpdbg_print.c b/sapi/phpdbg/phpdbg_print.c
index eff9a406e1..b7bb9e688a 100644
--- a/sapi/phpdbg/phpdbg_print.c
+++ b/sapi/phpdbg/phpdbg_print.c
@@ -270,23 +270,27 @@ void phpdbg_print_opcodes_function(const char *function, size_t len) {
zend_function *func = zend_hash_str_find_ptr(EG(function_table), function, len);
if (!func) {
+ zend_string *rt_name;
+ ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), rt_name, func) {
+ if (func->type == ZEND_USER_FUNCTION && *rt_name->val == '\0') {
+ if (func->op_array.function_name->len == len && !zend_binary_strcasecmp(function, len, func->op_array.function_name->val, func->op_array.function_name->len)) {
+ phpdbg_print_opcodes_function(rt_name->val, rt_name->len);
+ }
+ }
+ } ZEND_HASH_FOREACH_END();
+
return;
}
- phpdbg_out("function name: %.*s\n", (int) len, function);
+ phpdbg_out("function name: %.*s\n", ZSTR_LEN(func->op_array.function_name), ZSTR_VAL(func->op_array.function_name));
phpdbg_print_function_helper(func);
}
-void phpdbg_print_opcodes_method(const char *class, const char *function) {
- zend_class_entry *ce;
+static void phpdbg_print_opcodes_method_ce(zend_class_entry *ce, const char *function) {
zend_function *func;
- if (phpdbg_safe_class_lookup(class, strlen(class), &ce) != SUCCESS) {
- return;
- }
-
if (ce->type != ZEND_USER_CLASS) {
- phpdbg_out("function name: %s::%s (internal)\n", class, function);
+ phpdbg_out("function name: %s::%s (internal)\n", ce->name->val, function);
return;
}
@@ -294,20 +298,34 @@ void phpdbg_print_opcodes_method(const char *class, const char *function) {
return;
}
- phpdbg_out("function name: %s::%s\n", class, function);
+ phpdbg_out("function name: %s::%s\n", ce->name->val, function);
phpdbg_print_function_helper(func);
}
-void phpdbg_print_opcodes_class(const char *class) {
+void phpdbg_print_opcodes_method(const char *class, const char *function) {
zend_class_entry *ce;
- zend_function *method;
- zend_string *method_name;
- zend_bool first = 1;
if (phpdbg_safe_class_lookup(class, strlen(class), &ce) != SUCCESS) {
+ zend_string *rt_name;
+ ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), rt_name, ce) {
+ if (ce->type == ZEND_USER_CLASS && *rt_name->val == '\0') {
+ if (ce->name->len == strlen(class) && !zend_binary_strcasecmp(class, strlen(class), ce->name->val, ce->name->len)) {
+ phpdbg_print_opcodes_method_ce(ce, function);
+ }
+ }
+ } ZEND_HASH_FOREACH_END();
+
return;
}
+ phpdbg_print_opcodes_method_ce(ce, function);
+}
+
+static void phpdbg_print_opcodes_ce(zend_class_entry *ce) {
+ zend_function *method;
+ zend_string *method_name;
+ zend_bool first = 1;
+
phpdbg_out("%s %s: %s\n",
(ce->type == ZEND_USER_CLASS) ?
"user" : "internal",
@@ -342,10 +360,28 @@ void phpdbg_print_opcodes_class(const char *class) {
} ZEND_HASH_FOREACH_END();
}
+void phpdbg_print_opcodes_class(const char *class) {
+ zend_class_entry *ce;
+
+ if (phpdbg_safe_class_lookup(class, strlen(class), &ce) != SUCCESS) {
+ zend_string *rt_name;
+ ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), rt_name, ce) {
+ if (ce->type == ZEND_USER_CLASS && *rt_name->val == '\0') {
+ if (ce->name->len == strlen(class) && !zend_binary_strcasecmp(class, strlen(class), ce->name->val, ce->name->len)) {
+ phpdbg_print_opcodes_ce(ce);
+ }
+ }
+ } ZEND_HASH_FOREACH_END();
+
+ return;
+ }
+
+ phpdbg_print_opcodes_ce(ce);
+}
+
PHPDBG_API void phpdbg_print_opcodes(char *function)
{
- char *method_name;
- strtok(function, ":");
+ char *method_name = strtok(function, ":");
if (function == NULL) {
phpdbg_print_opcodes_main();
@@ -364,15 +400,15 @@ PHPDBG_API void phpdbg_print_opcodes(char *function)
}
} ZEND_HASH_FOREACH_END();
- ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), name, ce) {
+ ZEND_HASH_FOREACH_PTR(EG(class_table), ce) {
if (ce->type == ZEND_USER_CLASS) {
phpdbg_out("\n\n");
- phpdbg_print_opcodes_class(ZSTR_VAL(name));
+ phpdbg_print_opcodes_ce(ce);
}
} ZEND_HASH_FOREACH_END();
- } else if ((method_name = strtok(NULL, ":")) == NULL) {
+ } else if (method_name == NULL) {
phpdbg_print_opcodes_function(function, strlen(function));
- } else if ((method_name + 1) == NULL) {
+ } else if ((method_name = strtok(NULL, ":")) == NULL) {
phpdbg_print_opcodes_class(function);
} else {
phpdbg_print_opcodes_method(function, method_name);