From 8990e16877eabebb27057caf9a3c5eb255704a6a Mon Sep 17 00:00:00 2001 From: Paul Bissonnette Date: Thu, 19 Jul 2018 13:14:57 -0700 Subject: [PATCH] Fix inout calls with boxed but unreferenced values Summary: Passing these as inout values should be completely fine, the fact that something can be boxed but not referenced is purely an implementation detail. Reviewed By: swtaarrs Differential Revision: D8624735 fbshipit-source-id: d48782bdf64dfbbbef8bc69cd95a6ae57fd38a89 --- hphp/runtime/vm/member-operations.h | 6 ++++++ hphp/test/one_bit_refcount_failing_slow | 1 + hphp/test/slow/inout-refs.php | 14 ++++++++++++++ hphp/test/slow/inout-refs.php.expect | 15 +++++++++++++++ 4 files changed, 36 insertions(+) create mode 100644 hphp/test/slow/inout-refs.php create mode 100644 hphp/test/slow/inout-refs.php.expect diff --git a/hphp/runtime/vm/member-operations.h b/hphp/runtime/vm/member-operations.h index 6f1376c694a..7eea9a1da89 100644 --- a/hphp/runtime/vm/member-operations.h +++ b/hphp/runtime/vm/member-operations.h @@ -501,6 +501,12 @@ inline tv_rval Elem(TypedValue& tvRef, assertx(mode != MOpMode::Define && mode != MOpMode::Unset); assertx(tvIsPlausible(base.tv())); + if (mode == MOpMode::InOut) { + if (UNLIKELY(tvIsRef(base) && !base.val().pref->isReferenced())) { + base = base.unboxed(); + } + } + if (LIKELY(tvIsArray(base))) { return ElemArray(base.val().parr, key); } diff --git a/hphp/test/one_bit_refcount_failing_slow b/hphp/test/one_bit_refcount_failing_slow index fa9c2acf85e..34e2c011cd3 100644 --- a/hphp/test/one_bit_refcount_failing_slow +++ b/hphp/test/one_bit_refcount_failing_slow @@ -21,3 +21,4 @@ slow/unserialize-reference-overwritten.php slow/hack_arr_compat/parse-str.php slow/dv_array_hack_arr/ext_xenon/xenon_crash.php slow/dv_array/ext_xenon/xenon_crash.php +slow/inout-refs.php diff --git a/hphp/test/slow/inout-refs.php b/hphp/test/slow/inout-refs.php new file mode 100644 index 00000000000..0f355475e46 --- /dev/null +++ b/hphp/test/slow/inout-refs.php @@ -0,0 +1,14 @@ + + string(1) "a" + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(12) + } + [2]=> + string(1) "b" +} -- 2.11.4.GIT