hi Dmitry,

This fix breaks TS builds.

ZEND_API void destroy_zend_class(zend_class_entry **pce) does not have
a TSRM context and doing a fetch here will be horribly slow. Can you
use something else than hash_apply instead?

Cheers,

On Wed, Sep 5, 2012 at 7:58 AM, Dmitry Stogov <dmi...@php.net> wrote:
> Commit:    6c0508f8d5d5a62adb37a76bc682c94540199ee3
> Author:    Dmitry Stogov <dmi...@zend.com>         Wed, 5 Sep 2012 09:58:22 
> +0400
> Parents:   ff0aa24054c166de64993ef608ccbb8486c64ba5
> Branches:  PHP-5.4 master
>
> Link:       
> http://git.php.net/?p=php-src.git;a=commitdiff;h=6c0508f8d5d5a62adb37a76bc682c94540199ee3
>
> Log:
> Fixed bug #62907 (Double free when use traits)
>
> Bugs:
> https://bugs.php.net/62907
>
> Changed paths:
>   M  NEWS
>   M  Zend/tests/bug62907.phpt
>   M  Zend/zend_compile.c
>   M  Zend/zend_compile.h
>   M  Zend/zend_opcode.c
>
>
> Diff:
> diff --git a/NEWS b/NEWS
> index e09664a..22d3f66 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -9,6 +9,7 @@ PHP                                                           
>              NEWS
>      some builtin classes). (Laruence)
>    . Fixed bug #62955 (Only one directive is loaded from "Per Directory 
> Values"
>      Windows registry). (aserbulov at parallels dot com)
> +  . Fixed bug #62907 (Double free when use traits). (Dmitry)
>
>  - SOAP
>    . Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a 
> choice).
> diff --git a/Zend/tests/bug62907.phpt b/Zend/tests/bug62907.phpt
> index c519a54..53ab17c 100644
> --- a/Zend/tests/bug62907.phpt
> +++ b/Zend/tests/bug62907.phpt
> @@ -1,7 +1,5 @@
>  --TEST--
>  Bug #62907 (Double free when use traits)
> ---XFAIL--
> -bug is not fixed yet
>  --FILE--
>  <?php
>  function __autoload($name) {
> diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
> index bf458e1..c39d8ea 100644
> --- a/Zend/zend_compile.c
> +++ b/Zend/zend_compile.c
> @@ -3878,10 +3878,10 @@ static int zend_traits_copy_functions(zend_function 
> *fn TSRMLS_DC, int num_args,
>                                 && 
> (zend_binary_strcasecmp(aliases[i]->trait_method->method_name, 
> aliases[i]->trait_method->mname_len, fn->common.function_name, fnname_len) == 
> 0)) {
>                                 fn_copy = *fn;
>                                 function_add_ref(&fn_copy);
> -                               /* this function_name is never destroyed, 
> because its refcount
> -                                  greater than 1 and classes are always 
> destoyed before the
> -                                  traits they use */
> +                               /* this function_name is never destroyed, 
> because ZEND_ACC_ALIAS
> +                                  flag is set */
>                                 fn_copy.common.function_name = 
> aliases[i]->alias;
> +                               fn_copy.common.fn_flags |= ZEND_ACC_ALIAS;
>
>                                 /* if it is 0, no modifieres has been changed 
> */
>                                 if (aliases[i]->modifiers) {
> @@ -3914,6 +3914,7 @@ static int zend_traits_copy_functions(zend_function *fn 
> TSRMLS_DC, int num_args,
>                 /* is not in hashtable, thus, function is not to be excluded 
> */
>                 fn_copy = *fn;
>                 function_add_ref(&fn_copy);
> +               fn_copy.common.fn_flags |= ZEND_ACC_ALIAS;
>
>                 /* apply aliases which are not qualified by a class name, or 
> which have not
>                  * alias name, just setting visibility */
> diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
> index f164122..79ace0c 100644
> --- a/Zend/zend_compile.h
> +++ b/Zend/zend_compile.h
> @@ -207,6 +207,8 @@ typedef struct _zend_try_catch_element {
>  #define ZEND_ACC_RETURN_REFERENCE              0x4000000
>  #define ZEND_ACC_DONE_PASS_TWO                 0x8000000
>
> +#define ZEND_ACC_ALIAS                                 0x10000000
> +
>  char *zend_visibility_string(zend_uint fn_flags);
>
>
> diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
> index 19fd71e..6eab0ae 100644
> --- a/Zend/zend_opcode.c
> +++ b/Zend/zend_opcode.c
> @@ -267,6 +267,15 @@ void _destroy_zend_class_traits_info(zend_class_entry 
> *ce)
>         }
>  }
>
> +static int zend_clear_trait_method_name(zend_op_array *op_array TSRMLS_DC)
> +{
> +       if (op_array->function_name && (op_array->fn_flags & ZEND_ACC_ALIAS) 
> == 0) {
> +               efree(op_array->function_name);
> +               op_array->function_name = NULL;
> +       }
> +       return 0;
> +}
> +
>  ZEND_API void destroy_zend_class(zend_class_entry **pce)
>  {
>         zend_class_entry *ce = *pce;
> @@ -298,6 +307,9 @@ ZEND_API void destroy_zend_class(zend_class_entry **pce)
>                         }
>                         zend_hash_destroy(&ce->properties_info);
>                         str_efree(ce->name);
> +                       if ((ce->ce_flags & ZEND_ACC_TRAIT) == 
> ZEND_ACC_TRAIT) {
> +                               zend_hash_apply(&ce->function_table, 
> (apply_func_t)zend_clear_trait_method_name TSRMLS_CC);
> +                       }
>                         zend_hash_destroy(&ce->function_table);
>                         zend_hash_destroy(&ce->constants_table);
>                         if (ce->num_interfaces > 0 && ce->interfaces) {
> @@ -387,7 +399,7 @@ ZEND_API void destroy_op_array(zend_op_array *op_array 
> TSRMLS_DC)
>         }
>         efree(op_array->opcodes);
>
> -       if (op_array->function_name) {
> +       if (op_array->function_name && (op_array->fn_flags & ZEND_ACC_ALIAS) 
> == 0) {
>                 efree((char*)op_array->function_name);
>         }
>         if (op_array->doc_comment) {
>
>
> --
> PHP CVS Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>



-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to