Bug #73816 [Opn]: Broken eval(anonymous class)

From: Date: Mon, 26 Dec 2016 21:51:23 +0000
Subject: Bug #73816 [Opn]: Broken eval(anonymous class)
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-206214@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=73816&edit=1 ID: 73816 User updated by: nicolas dot grekas+php at gmail dot com Reported by: nicolas dot grekas+php at gmail dot com Summary: Broken eval(anonymous class) Status: Open Type: Bug Package: Scripting Engine problem PHP Version: 7.1.0 Block user comment: N Private report: N New Comment: 100% agree with this analysis. This still means eval+anonymous classes is kinda broken. I don't know if that would be a proper fix, but can't we use the hash of the evaluated string as part of the generated name? Or at least some nonce? Previous Comments: ------------------------------------------------------------------------ [2016-12-26 20:48:22] dave at mudsite dot com I believe you're right in the sense the fix for the referenced bug prevents your example from working, but had you stored the result of the first call to anon() and tried to use it, you'd have hit the bug that was fixed; the reference of the class would have been the second eval'd anon class, rather than the first. I'd leave it to others to say if the previous, or current, behavior is appropriate. If we took your example and ran it with a slight change, storing the return of anon() to variables and var_dumping after you'd expose the bug that's resolved (kinda). You'd see that both c1, and c2 do reference a class-entry, but it'd be the second updated pointer to the entry. https://3v4l.org/RiRcW If you were to then set the prop1 before creating it again, you'd get even weirder output where prop1 wouldn't exist. https://3v4l.org/Eq3Di I'd believe the current (7.0.10, 7.1.0) results ought to be correct. Where an anon class is defined it should be the only entry in the class-table. Since the actual name of the class is something along the lines of: class@anonymous\0/Path/to/file.php(6) : eval()'d code0xdeadbeef Where the only printed value of this name is up to that nul byte, however, the hash into the class table you'd see references the memory location where the 'new class()' is defined. Which, if your eval() line is at the same location the memory location never changes, even though you change the properties in it. ------------------------------------------------------------------------ [2016-12-26 12:48:11] nicolas dot grekas+php at gmail dot com Maybe introduced by the fix for https://bugs.php.net/72594 ? ------------------------------------------------------------------------ [2016-12-26 12:34:40] nicolas dot grekas+php at gmail dot com Description: ------------ Calling several times eval() to create different anonymous classes doesn't create new anonymous classes but always returns the first one. Used to work until 7.0.10 & 7.1.0 which both have the bug. See https://3v4l.org/t7c5Z Test script: --------------- <?php function anon() { static $i = 0; return eval(sprintf('return new class { private $prop%s; };', ++$i)); } var_dump(anon()); var_dump(anon()); Expected result: ---------------- object(class@anonymous)#1 (1) { ["prop1":"class@anonymous":private]=> NULL } object(class@anonymous)#1 (1) { ["prop2":"class@anonymous":private]=> NULL } Actual result: -------------- object(class@anonymous)#1 (1) { ["prop1":"class@anonymous":private]=> NULL } object(class@anonymous)#1 (1) { ["prop1":"class@anonymous":private]=> NULL } ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=73816&edit=1

« previous php.bugs (#206214) next »