summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2013-06-06 18:49:04 +0200
committerAnatol Belski <ab@php.net>2013-06-06 18:49:04 +0200
commit1aee7ad63672747bd941f169ef42bed5765137e0 (patch)
tree41b0bfda23b879753397d6cf8f36310399719d19
parentec3bcbcb5a6336861951ad569e378e4b77984df5 (diff)
downloadphp-git-1aee7ad63672747bd941f169ef42bed5765137e0.tar.gz
Fixed bug #64934 Apache2 TS crash with get_browser()
In favour of reading the browscap.ini into a true global var only once in MINIT, the price for that is to deep copy the any data from it.
-rw-r--r--NEWS1
-rw-r--r--ext/standard/browscap.c21
2 files changed, 18 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index a7c0426704..fc0842f427 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ PHP NEWS
?? ??? 2013, PHP 5.3.27
- Core:
. Fixed bug #64960 (Segfault in gc_zval_possible_root). (Laruence)
+ . Fixed bug #64934 (Apache2 TS crash with get_browser()). (Anatol)
- PDO_firebird:
. Fixed bug #64037 (Firebird return wrong value for numeric field).
diff --git a/ext/standard/browscap.c b/ext/standard/browscap.c
index 60949fc352..343ad2051c 100644
--- a/ext/standard/browscap.c
+++ b/ext/standard/browscap.c
@@ -451,6 +451,19 @@ static int browser_reg_compare(zval **browser TSRMLS_DC, int num_args, va_list a
}
/* }}} */
+static void browscap_zval_copy_ctor(zval **p) /* {{{ */
+{
+ zval *new;
+
+ ALLOC_ZVAL(new);
+ *new = **p;
+
+ zval_copy_ctor(new);
+
+ INIT_PZVAL(new);
+ *p = new;
+} /* }}} */
+
/* {{{ proto mixed get_browser([string browser_name [, bool return_array]])
Get information about the capabilities of a browser. If browser_name is omitted or null, HTTP_USER_AGENT is used. Returns an object by default; if return_array is true, returns an array. */
PHP_FUNCTION(get_browser)
@@ -511,11 +524,11 @@ PHP_FUNCTION(get_browser)
if (return_array) {
array_init(return_value);
- zend_hash_copy(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *));
+ zend_hash_copy(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) browscap_zval_copy_ctor, (void *) &tmp_copy, sizeof(zval *));
}
else {
object_init(return_value);
- zend_hash_copy(Z_OBJPROP_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *));
+ zend_hash_copy(Z_OBJPROP_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) browscap_zval_copy_ctor, (void *) &tmp_copy, sizeof(zval *));
}
while (zend_hash_find(Z_ARRVAL_PP(agent), "parent", sizeof("parent"), (void **) &z_agent_name) == SUCCESS) {
@@ -524,10 +537,10 @@ PHP_FUNCTION(get_browser)
}
if (return_array) {
- zend_hash_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *), 0);
+ zend_hash_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) browscap_zval_copy_ctor, (void *) &tmp_copy, sizeof(zval *), 0);
}
else {
- zend_hash_merge(Z_OBJPROP_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *), 0);
+ zend_hash_merge(Z_OBJPROP_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) browscap_zval_copy_ctor, (void *) &tmp_copy, sizeof(zval *), 0);
}
}