]> granicus.if.org Git - php/commitdiff
Fixed bug #64934 Apache2 TS crash with get_browser()
authorAnatol Belski <ab@php.net>
Thu, 6 Jun 2013 16:49:04 +0000 (18:49 +0200)
committerAnatol Belski <ab@php.net>
Thu, 6 Jun 2013 16:49:04 +0000 (18:49 +0200)
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.

NEWS
ext/standard/browscap.c

diff --git a/NEWS b/NEWS
index a7c0426704059044a5283a4404657956f437caca..fc0842f427ceea7a8fbe38dccdb16f93ee33c7c3 100644 (file)
--- 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).
index 60949fc35289d4595370972bf9e396d3c2cada15..343ad2051c14259677fb456d78d3b0c136390c25 100644 (file)
@@ -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);
                }
        }