On 10.08.2016 at 12:59, Nikita Popov wrote:

> On Wed, Aug 10, 2016 at 12:52 PM, Christoph M. Becker <cmbecke...@gmx.de>
> wrote:
>>
>> I've tried to fix <https://bugs.php.net/72793>, and it looks like
>> there's a general GC issue wrt. to resources referencing objects and
>> vice versa.  Aren't resource ZVALS put in the root buffer?
>>
>> See <https://3v4l.org/JYIQs>, which demonstrates the issue better than
>> the test script in the bug report.  A steady increase of allocated
>> memory can be seen, even though gc_collect_cycles() is called.  When
>> uncommenting `unset($this->parser);`, everything is fine (the GC
>> wouldn't be involved at all in this case).
>>
>> Wrt. to the PHP 5.6 behavior: this appears fine, but actually it's in
>> error, because of <https://github.com/php/php-src/commit/72ec2e8f>.  Not
>> increasing the refcount of `parser->object` might theoretically lead to
>> use-after-free scenarios.
> 
> As you correctly deduced, we currently do not support GC for resources.
> This would require introducing something akin to the get_gc handler for
> resources.

Thanks for the clarification!

> The simplest way to fix ext/xml in particular is probably to migrate it to
> use an object instead of a resource.

I guess that is the best action in the long run (i.e. 7.2+), but that
would of course cause a BC break, so probably it's best to document that
the user has to break the cycle manually, if xml_set_object() is used
(7.0, 7.1).

Wrt. to PHP 5.6 it appears there are no issues at all.  While the code
out-commented by Thies is still there (which should be removed to avoid
further confusion), in the following a (shallow) copy of the object is
made, and apparently due to the additional refcount in the object store
of PHP 5, everything is okay.

Another alternative for PHP 7.2 might be to drop (after deprecation)
xml_set_object(); actually, it seems to me this function is a relict of
pre PHP 5.  Cf. example #1[1].  Instead of doing:

  xml_set_object($this->parser, $this);
  xml_set_element_handler($this->parser, "tag_open", "tag_close");

one could simply do:

  xml_set_element_handler($this->parser,
      [$this, "tag_open"], [$this, "tag_close]);

[1]
<http://php.net/manual/en/function.xml-set-object.php#refsect1-function.xml-set-object-examples>

-- 
Christoph M. Becker

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to