From d1f6c6c788b11c283af054caad69290826613e37 Mon Sep 17 00:00:00 2001 From: Emil Hesslow Date: Wed, 10 Apr 2019 10:45:45 -0700 Subject: [PATCH] Add logging to get_class if it get bad stuff Summary: - Makes no sense for get_class to handle null, int, float or anything else than object. - The replacement for get_class(null) is self::class. Reviewed By: alexeyt Differential Revision: D14859723 fbshipit-source-id: cfa5419a51a3e462f585e67632f9a0ad8b894ddb --- hphp/runtime/base/runtime-option.h | 4 ++++ hphp/runtime/ext/std/ext_std_classobj.cpp | 17 ++++++++++++++++- hphp/test/slow/ext_class/get_class_throw.php | 17 +++++++++++++++++ hphp/test/slow/ext_class/get_class_throw.php.expectf | 6 ++++++ hphp/test/slow/ext_class/get_class_throw.php.opts | 1 + hphp/test/slow/ext_class/get_class_warn.php | 17 +++++++++++++++++ hphp/test/slow/ext_class/get_class_warn.php.expectf | 15 +++++++++++++++ hphp/test/slow/ext_class/get_class_warn.php.opts | 1 + 8 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 hphp/test/slow/ext_class/get_class_throw.php create mode 100644 hphp/test/slow/ext_class/get_class_throw.php.expectf create mode 100644 hphp/test/slow/ext_class/get_class_throw.php.opts create mode 100644 hphp/test/slow/ext_class/get_class_warn.php create mode 100644 hphp/test/slow/ext_class/get_class_warn.php.expectf create mode 100644 hphp/test/slow/ext_class/get_class_warn.php.opts diff --git a/hphp/runtime/base/runtime-option.h b/hphp/runtime/base/runtime-option.h index c21afd1e626..19159a66d72 100644 --- a/hphp/runtime/base/runtime-option.h +++ b/hphp/runtime/base/runtime-option.h @@ -735,6 +735,10 @@ struct RuntimeOption { * 0 -> no warning, 1 -> warning, 2 -> exception */ \ F(uint32_t, WarnOnTooManyArguments, 0) \ + /* GetClassBadArgument: + * 0 -> no warning, 1 -> warning, 2 -> exception + */ \ + F(uint32_t, GetClassBadArgument, 0) \ /* WarnOnIncDecInvalidType: * 0 - No restrictions on types that can be incremented or decremented * 1 - Warn when incrementing or decrementing non numeric types diff --git a/hphp/runtime/ext/std/ext_std_classobj.cpp b/hphp/runtime/ext/std/ext_std_classobj.cpp index 89636218c99..825ddd6484d 100644 --- a/hphp/runtime/ext/std/ext_std_classobj.cpp +++ b/hphp/runtime/ext/std/ext_std_classobj.cpp @@ -192,8 +192,20 @@ Variant HHVM_FUNCTION(get_class_vars, const String& className) { /////////////////////////////////////////////////////////////////////////////// Variant HHVM_FUNCTION(get_class, const Variant& object /* = uninit_variant */) { + auto logOrThrow = [&](const Variant& object) { + auto msg = folly::sformat("get_class() was called with {}, expected object", + getDataTypeString(object.getType())); + if (RuntimeOption::EvalGetClassBadArgument == 2) { + SystemLib::throwRuntimeExceptionObject(msg); + } + if (RuntimeOption::EvalGetClassBadArgument == 1) { + raise_warning(msg); + } + }; if (object.isNull()) { // No arg passed. + logOrThrow(object); + auto cls = GetCallerClassSkipBuiltins(); if (cls) { return Variant{cls->name(), Variant::PersistentStrInit{}}; @@ -202,7 +214,10 @@ Variant HHVM_FUNCTION(get_class, const Variant& object /* = uninit_variant */) { raise_warning("get_class() called without object from outside a class"); return false; } - if (!object.isObject()) return false; + if (!object.isObject()) { + logOrThrow(object); + return false; + } return Variant{object.toCObjRef()->getVMClass()->name(), Variant::PersistentStrInit{}}; } diff --git a/hphp/test/slow/ext_class/get_class_throw.php b/hphp/test/slow/ext_class/get_class_throw.php new file mode 100644 index 00000000000..dbe228e388a --- /dev/null +++ b/hphp/test/slow/ext_class/get_class_throw.php @@ -0,0 +1,17 @@ +getMessage()); } + try { var_dump(get_class(null)); } catch (Exception $e) { var_dump($e->getMessage()); } + try { var_dump(get_class(1)); } catch (Exception $e) { var_dump($e->getMessage()); } + try { var_dump(get_class(1.1)); } catch (Exception $e) { var_dump($e->getMessage()); } + try { var_dump(get_class("string")); } catch (Exception $e) { var_dump($e->getMessage()); } + var_dump(get_class(new stdclass())); + } +} + +<<__EntryPoint>> +function main() { + GetClassTest::test(); +} diff --git a/hphp/test/slow/ext_class/get_class_throw.php.expectf b/hphp/test/slow/ext_class/get_class_throw.php.expectf new file mode 100644 index 00000000000..33f5e9c2365 --- /dev/null +++ b/hphp/test/slow/ext_class/get_class_throw.php.expectf @@ -0,0 +1,6 @@ +string(49) "get_class() was called with null, expected object" +string(49) "get_class() was called with null, expected object" +string(52) "get_class() was called with integer, expected object" +string(51) "get_class() was called with double, expected object" +string(51) "get_class() was called with string, expected object" +string(8) "stdClass" diff --git a/hphp/test/slow/ext_class/get_class_throw.php.opts b/hphp/test/slow/ext_class/get_class_throw.php.opts new file mode 100644 index 00000000000..2c5d591dbf3 --- /dev/null +++ b/hphp/test/slow/ext_class/get_class_throw.php.opts @@ -0,0 +1 @@ +-vEval.GetClassBadArgument=2 diff --git a/hphp/test/slow/ext_class/get_class_warn.php b/hphp/test/slow/ext_class/get_class_warn.php new file mode 100644 index 00000000000..9420180d3d2 --- /dev/null +++ b/hphp/test/slow/ext_class/get_class_warn.php @@ -0,0 +1,17 @@ +> +function main() { + GetClassTest::test(); +} diff --git a/hphp/test/slow/ext_class/get_class_warn.php.expectf b/hphp/test/slow/ext_class/get_class_warn.php.expectf new file mode 100644 index 00000000000..cb24bbfa692 --- /dev/null +++ b/hphp/test/slow/ext_class/get_class_warn.php.expectf @@ -0,0 +1,15 @@ +Warning: get_class() was called with null, expected object in %s/test/slow/ext_class/get_class_warn.php on line 5 +string(12) "GetClassTest" + +Warning: get_class() was called with null, expected object in %s/test/slow/ext_class/get_class_warn.php on line 6 +string(12) "GetClassTest" + +Warning: get_class() was called with integer, expected object in %s/test/slow/ext_class/get_class_warn.php on line 7 +bool(false) + +Warning: get_class() was called with double, expected object in %s/test/slow/ext_class/get_class_warn.php on line 8 +bool(false) + +Warning: get_class() was called with string, expected object in %s/test/slow/ext_class/get_class_warn.php on line 9 +bool(false) +string(8) "stdClass" diff --git a/hphp/test/slow/ext_class/get_class_warn.php.opts b/hphp/test/slow/ext_class/get_class_warn.php.opts new file mode 100644 index 00000000000..ac282b1ae9a --- /dev/null +++ b/hphp/test/slow/ext_class/get_class_warn.php.opts @@ -0,0 +1 @@ +-vEval.GetClassBadArgument=1 -- 2.11.4.GIT