PHP :: Bug #55475 :: is_a() triggers autoloader
| Bug #55475 | is_a() triggers autoloader | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Submitted: | 2011-08-22 08:16 UTC | Modified: | 2011-11-09 05:27 UTC |
|
||||||||||
| From: | mads at gartneriet dot dk | Assigned: | dmitry (profile) | |||||||||||
| Status: | Closed | Package: | Scripting Engine problem | |||||||||||
| PHP Version: | 5.3.7 | OS: | ||||||||||||
| Private report: | No | CVE-ID: | 2011-3379 | |||||||||||
[2011-08-22 08:16 UTC] mads at gartneriet dot dk
Description:
------------
When calling is_a() with a first argument that is not an object, then __autoload() is triggered:
Test script:
---------------
<?php
function __autoload($class) {
echo "Would load: " . $class . PHP_EOL;
}
$var = "test";
var_dump(is_a($var, 'B'));
$obj = new Stdclass;
var_dump(is_a($obj, 'C'));
?>
Expected result:
----------------
bool(false)
bool(false)
Actual result:
--------------
Would load: test
bool(false)
bool(false)
Patches
final_patch_for_5_4_and_HEAD_v2 (last revision 2011-11-08 09:24 UTC by alan_k@php.net)is_a_5.4_alternative (last revision 2011-10-17 13:15 UTC by jbondc at openmv dot com)
final_patch_for_5_4_and_HEAD (last revision 2011-10-13 07:36 UTC by alan_k@php.net)
is_a_with_warning.txt (last revision 2011-09-25 09:32 UTC by alan_k@php.net)
Is_a_with_allow_string_argument_v3 (last revision 2011-09-22 23:31 UTC by alan_k@php.net)
Is_a_with_allow_string_argument_v2 (last revision 2011-09-22 23:26 UTC by alan_k@php.net)
Is_a_with_allow_string_argument (last revision 2011-09-22 23:24 UTC by alan_k@php.net)
is_class_of.diff (last revision 2011-09-20 21:32 UTC by alan_k@php.net)
is_class_of.txt (last revision 2011-09-20 21:25 UTC by alan_k@php.net)
revert.is_a.behaviour.to.ignoring.strings.diff (last revision 2011-08-25 02:37 UTC by alan at akbkhome dot com)
bug55475 (last revision 2011-08-22 10:30 UTC by kalle@php.net)
Pull Requests
History
AllCommentsChangesGit/SVN commits
[2011-08-22 08:19 UTC] pajoye@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: dmitry
[2011-08-22 08:57 UTC] konstantin dot leboev at gmail dot com
[2011-08-22 09:15 UTC] colder@php.net
[2011-08-22 10:12 UTC] zeev@php.net
Discussed with Dmitry, the current functionality appears to be correct. is_a('foo', 'bar') *can* be true even if class foo isn't loaded, and we'll only know that if we try to load 'foo'. This is different from is_a($obj, 'non_existent_class'), which we can resolve as 'false' in case non_existent_class isn't loaded without trying to load it (there can't be an instance of a class that doesn't exist).[2011-08-22 10:29 UTC] kalle@php.net
[2011-08-22 11:00 UTC] dmitry@php.net
Before the patch, is_a() didn't accept string as the first argument at all, so it always returned "false" and never triggered __autoload(). The proposed patch didn't revert to original behavior. It just disables autoloading and may lead to wrong result. class a {} class b extends a {} var_dump(is_a("b", "a")); // it was false before 5.3.7, now it's true I would say that the old behaviour was wrong, especially because "instanceof" and is_subclass_of() already implemented support for string arguments.[2011-08-22 13:31 UTC] colder@php.net
[2011-08-22 13:41 UTC] kalle@php.net
[2011-08-22 14:27 UTC] colder@php.net
[2011-08-22 14:40 UTC] kalle@php.net
[2011-08-22 14:44 UTC] kalle@php.net
[2011-08-22 14:49 UTC] colder@php.net
[2011-08-22 15:46 UTC] johannes@php.net
[2011-08-22 18:36 UTC] stas@php.net
[2011-08-22 19:17 UTC] mads at gartneriet dot dk
[2011-08-22 21:46 UTC] colder@php.net
[2011-08-23 05:17 UTC] mads at gartneriet dot dk
[2011-08-23 06:26 UTC] alan at akbkhome dot com
[2011-08-23 08:25 UTC] alan at akbkhome dot com
[2011-08-23 14:24 UTC] jha dot rajeev at gmail dot com
[2011-08-24 01:59 UTC] alan at akbkhome dot com
For reference: The workaround is to do this if (is_a($a, 'B')) { becomes if (is_object($a) && is_a($a, 'B')) {[2011-08-24 05:16 UTC] jha dot rajeev at gmail dot com
I have a question re. the correct behavior of custom __autoload() functions when called from is_a() in 5.3.7. How do we handle/report missing classes? is is_a() prepared to handle any sort of exceptions or does it assume that __autoload will return TRUE/FALSE only? what if I just did something like is_a("",ABCD)?[2011-08-26 10:24 UTC] kkaminski at itens dot pl
[2011-08-29 07:15 UTC] tyrael@php.net
[2011-09-07 06:30 UTC] vchernoivan at gmail dot com
I guess it is no use to argue if the behaviuor is correct or not, or how precise the manual is. Since IT IS BREAKING EXISTING CODE, for me, too. Before the change if (is_a($date,"DateTime")) return $date->format(...); /// some code handling datetime strings worked just fine. Now it triggers __autoload and results in completely broken page. For sure, personally I can change every piece of MY OWN code. But consider users of tons of PHP libraries! What do you think, how long will it take to update every piece of them? Vote for reverting to prior-5.7 behavior until 5.4[2011-09-15 10:00 UTC] dmitry@php.net
-Status: Assigned +Status: Closed
[2011-09-15 10:00 UTC] dmitry@php.net
[2011-09-15 11:00 UTC] dmitry@php.net
-Status: Closed +Status: Assigned
[2011-09-15 11:00 UTC] dmitry@php.net
[2011-09-20 21:30 UTC] alan_k@php.net
[2011-09-23 09:51 UTC] rasmus@php.net
[2011-09-24 09:22 UTC] henri at nerv dot fi
[2011-09-24 13:13 UTC] cipri@php.net
[2011-09-26 19:38 UTC] togos00 at gmail dot com
[2011-09-26 19:45 UTC] pajoye@php.net
[2011-10-03 07:30 UTC] alan_k@php.net
[2011-11-09 05:27 UTC] stas@php.net
-Status: Assigned +Status: Closed
[2012-01-09 08:27 UTC] counterpoint at aliro dot org
[2012-07-02 10:30 UTC] rmc1134 at gmail dot com
I don't get it: why should is_a() accept a string as its first argument? This function is supposed to be a check on AN OBJECT and is_a('stdClass', 'stdClass') SHOULD NOT EVER RETURN any truthy value. Calling __autoload() to check whether some string might be some object is something a programmer should do, not the language.[2013-01-28 17:09 UTC] martijn dot niji at gmail dot com
I must agree with the people who say that is_a('stdClass', 'stdClass') should not return true. The is_a() function is intended as a function that checks a certain condition is true, that condition being that a certain variable/object is of a certain type/class. Having is_a() try to automatically load a class by calling autoload is bad behaviour at best and a code breaking security flaw at worst.