php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61506 insteadof cause memory leak if class is not binded
Submitted: 2012-03-26 05:49 UTC Modified: 2017-01-02 14:11 UTC
From: xuefer at gmail dot com Assigned: gron (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5.4.0 OS: linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: xuefer at gmail dot com
New email:
PHP Version: OS:

 

 [2012-03-26 05:49 UTC] xuefer at gmail dot com
Description:
------------
when class is not binded, "insteadof" cause a detected memory leak. see the 
following script and output

==============
after days tracking, i lock on _destroy_zend_class_traits_info
    if (ce->trait_precedences) {
        size_t i = 0;

        while (ce->trait_precedences[i]) {
            efree((char*)ce->trait_precedences[i]->trait_method->method_name);
            efree((char*)ce->trait_precedences[i]->trait_method->class_name);
            efree(ce->trait_precedences[i]->trait_method);

            if (ce->trait_precedences[i]->exclude_from_classes) {
                efree(ce->trait_precedences[i]->exclude_from_classes);  <- 
before this line
            }

ce->trait_precedences[i]->exclude_from_classes[0] is string, should but not 
efree'ed, this is why it's leaking. however when the class is bind, it is 
zend_class_entry and should not efree 

Test script:
---------------
<?php
if (0) {
        class A {
                use b2, b33 {
                        b2::b444 insteadof b33;
                        b2::b444 as b5555;
                }
        }
}


Expected result:
----------------
./php-cgi -c php.ini test.php
X-Powered-By: PHP/5.4.1RC1-dev
Content-type: text/html



Actual result:
--------------
./php-cgi -c php.ini test.php
X-Powered-By: PHP/5.4.1RC1-dev
Content-type: text/html

[Mon Mar 26 13:40:12 2012]  Script:  'ZZZZZZZZZZs|▒▒▒▒'▒]▒G'
Zend/zend_language_scanner.l(1889) :  Freeing 0x7F4720728688 (4 bytes), 
script=ZZZZZZZZZZs|▒▒▒▒'▒]▒G
=== Total 1 memory leaks detected ===

valgrind outputs:

==31399== 4 bytes in 1 blocks are definitely lost in loss record 1 of 84
==31399==    at 0x4C2879E: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-
amd64-linux.so)
==31399==    by 0x8E9C41: _emalloc (zend_alloc.c:2423)
==31399==    by 0x8EA1A6: _estrndup (zend_alloc.c:2596)
==31399==    by 0x8D050E: lex_scan (zend_language_scanner.l:1889)
==31399==    by 0x905A52: zendlex (zend_compile.c:6666)
==31399==    by 0x8C5F45: zendparse (zend_language_parser.c:3099)
==31399==    by 0x8CC630: compile_file (zend_language_scanner.l:579)
==31399==    by 0x6F2C45: phar_compile_file (phar.c:3391)
==31399==    by 0x91F846: zend_execute_scripts (zend.c:1265)
==31399==    by 0x896FEC: php_execute_script (main.c:2473)
==31399==    by 0xA6D136: main (cgi_main.c:2422)


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-03-26 16:28 UTC] yohgaki@php.net
-Package: *Compile Issues +Package: Scripting Engine problem
 [2012-03-26 16:28 UTC] yohgaki@php.net
Changed package from Compile Issue.
 [2012-04-20 01:38 UTC] felipe@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: gron
 [2012-04-21 20:35 UTC] gron@php.net
Hi, thanks for identifying the problem!

Another of those PHP corner cases I did not handle properly.

The problem is that I only resolve the classes during the execution phase, but not 
during parsing.

One possible solution is to remember whether the class got bound: 
https://github.com/smarr/php-src/commit/d3b86b8bd33c06d55ab80baca63f5f7516a5a32b

Not the best solution I think, but I am out of ideas.
Other parts of the engine use zend_do_fetch_class(..) to do it, but this generates an 
extra opcode and will probably require larger changes to the traits implementation.
 [2017-01-02 14:11 UTC] nikic@php.net
-Status: Assigned +Status: Closed
 [2017-01-02 14:11 UTC] nikic@php.net
Seems to have been fixed in the meantime.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Jul 12 11:01:32 2025 UTC