From 6c7d8b60e836766c07c861e10e98d503fc0b5f69 Mon Sep 17 00:00:00 2001 From: James Wu Date: Mon, 5 Sep 2022 19:57:38 -0700 Subject: [PATCH] Add runtime enforcement for instance properties Summary: This diff adds interpreter and jit support for enforcing internal on instance properties. In general for property enforcement, when the property is statically known, we can check the modules check statically and easily. When it isn't, we always fall back to C++ code using minstr-helpers.cpp. Therefore, the implementation in the jit is rather straightforward. - If we have a propInfo, we statically check that propInfo for modularity violations. - If we don't, we default to using minstr-helpers.cpp, which calls the same C++ helpers as the interpreter code. Reviewed By: oulgen Differential Revision: D38639723 fbshipit-source-id: ee94b612063479cc3ab61deb39137c5c91fe0508 --- hphp/doc/ir.specification | 4 ++++ hphp/runtime/base/object-data.cpp | 7 ++++++ hphp/runtime/vm/class.cpp | 25 ++++++++++++---------- hphp/runtime/vm/class.h | 9 ++++++++ hphp/runtime/vm/jit/dce.cpp | 1 + hphp/runtime/vm/jit/extra-data.h | 1 + hphp/runtime/vm/jit/ir-opcode.cpp | 1 + hphp/runtime/vm/jit/irgen-call.cpp | 9 ++++++++ hphp/runtime/vm/jit/irgen-call.h | 9 ++++++-- hphp/runtime/vm/jit/irgen-minstr.cpp | 13 ++++++----- hphp/runtime/vm/jit/irlower-exception.cpp | 9 ++++++++ hphp/runtime/vm/jit/memory-effects.cpp | 1 + hphp/runtime/vm/module.cpp | 2 ++ hphp/runtime/vm/runtime.cpp | 14 ++++++++++++ hphp/runtime/vm/runtime.h | 1 + .../modules/instance-properties-incdec-throw.php | 15 +++++++++++++ .../instance-properties-incdec-throw.php.expectf | 2 ++ .../instance-properties-incdec-throw.php.hphp_opts | 2 ++ .../instance-properties-incdec-throw.php.opts | 1 + .../slow/modules/instance-properties-incdec.php | 12 +++++++++++ .../modules/instance-properties-incdec.php.expectf | 3 +++ .../instance-properties-incdec.php.hphp_opts | 2 ++ .../slow/modules/instance-properties-throw-2.php | 14 ++++++++++++ .../instance-properties-throw-2.php.expectf | 2 ++ .../instance-properties-throw-2.php.hphp_opts | 2 ++ .../modules/instance-properties-throw-2.php.opts | 1 + .../slow/modules/instance-properties-throw-3.php | 14 ++++++++++++ .../instance-properties-throw-3.php.expectf | 2 ++ .../instance-properties-throw-3.php.hphp_opts | 3 +++ .../modules/instance-properties-throw-3.php.opts | 1 + .../slow/modules/instance-properties-throw.php | 14 ++++++++++++ .../modules/instance-properties-throw.php.expectf | 2 ++ .../instance-properties-throw.php.hphp_opts | 2 ++ .../modules/instance-properties-throw.php.opts | 1 + hphp/test/slow/modules/instance-properties.inc | 17 +++++++++++++++ hphp/test/slow/modules/instance-properties.php | 12 +++++++++++ .../slow/modules/instance-properties.php.expectf | 3 +++ .../slow/modules/instance-properties.php.hphp_opts | 2 ++ hphp/test/slow/modules/instance-properties2.php | 12 +++++++++++ .../slow/modules/instance-properties2.php.expectf | 3 +++ .../modules/instance-properties2.php.hphp_opts | 2 ++ hphp/test/slow/modules/instance-properties3.php | 12 +++++++++++ .../slow/modules/instance-properties3.php.expectf | 3 +++ .../modules/instance-properties3.php.hphp_opts | 2 ++ hphp/test/slow/modules/module.inc | 3 +++ 45 files changed, 254 insertions(+), 18 deletions(-) create mode 100644 hphp/test/slow/modules/instance-properties-incdec-throw.php create mode 100644 hphp/test/slow/modules/instance-properties-incdec-throw.php.expectf create mode 100644 hphp/test/slow/modules/instance-properties-incdec-throw.php.hphp_opts create mode 100644 hphp/test/slow/modules/instance-properties-incdec-throw.php.opts create mode 100644 hphp/test/slow/modules/instance-properties-incdec.php create mode 100644 hphp/test/slow/modules/instance-properties-incdec.php.expectf create mode 100644 hphp/test/slow/modules/instance-properties-incdec.php.hphp_opts create mode 100644 hphp/test/slow/modules/instance-properties-throw-2.php create mode 100644 hphp/test/slow/modules/instance-properties-throw-2.php.expectf create mode 100644 hphp/test/slow/modules/instance-properties-throw-2.php.hphp_opts create mode 100644 hphp/test/slow/modules/instance-properties-throw-2.php.opts create mode 100644 hphp/test/slow/modules/instance-properties-throw-3.php create mode 100644 hphp/test/slow/modules/instance-properties-throw-3.php.expectf create mode 100644 hphp/test/slow/modules/instance-properties-throw-3.php.hphp_opts create mode 100644 hphp/test/slow/modules/instance-properties-throw-3.php.opts create mode 100644 hphp/test/slow/modules/instance-properties-throw.php create mode 100644 hphp/test/slow/modules/instance-properties-throw.php.expectf create mode 100644 hphp/test/slow/modules/instance-properties-throw.php.hphp_opts create mode 100644 hphp/test/slow/modules/instance-properties-throw.php.opts create mode 100644 hphp/test/slow/modules/instance-properties.inc create mode 100644 hphp/test/slow/modules/instance-properties.php create mode 100644 hphp/test/slow/modules/instance-properties.php.expectf create mode 100644 hphp/test/slow/modules/instance-properties.php.hphp_opts create mode 100644 hphp/test/slow/modules/instance-properties2.php create mode 100644 hphp/test/slow/modules/instance-properties2.php.expectf create mode 100644 hphp/test/slow/modules/instance-properties2.php.hphp_opts create mode 100644 hphp/test/slow/modules/instance-properties3.php create mode 100644 hphp/test/slow/modules/instance-properties3.php.expectf create mode 100644 hphp/test/slow/modules/instance-properties3.php.hphp_opts create mode 100644 hphp/test/slow/modules/module.inc diff --git a/hphp/doc/ir.specification b/hphp/doc/ir.specification index 50216b9b8fc..f8c35d5cfc9 100644 --- a/hphp/doc/ir.specification +++ b/hphp/doc/ir.specification @@ -2259,6 +2259,10 @@ To string conversions: attempting to either call, if S0 is Func, or create a pointer to the callee in S0 in context `ctx`. +| RaiseModulePropertyViolation, ND, S(Cls) S(Str), NF + Raises a warning to indicate a module boundary violation resulting from caller + attempting to access a property S1 from class S0. + | RaiseImplicitContextStateInvalid, ND, NA, NF Raises a warning or throws an exception for invalid, soft implicit context diff --git a/hphp/runtime/base/object-data.cpp b/hphp/runtime/base/object-data.cpp index 18d1d685c57..08b96adaf2f 100644 --- a/hphp/runtime/base/object-data.cpp +++ b/hphp/runtime/base/object-data.cpp @@ -45,6 +45,7 @@ #include "hphp/runtime/vm/native-prop-handler.h" #include "hphp/runtime/vm/jit/translator-inline.h" #include "hphp/runtime/vm/repo-global-data.h" +#include "hphp/runtime/vm/runtime.h" #include "hphp/system/systemlib.h" @@ -1206,6 +1207,12 @@ ObjectData::PropLookup ObjectData::getPropImpl( } } + // If the prop is internal, check that modules are compatible + if (lookup.internal && + will_symbol_raise_module_boundary_violation(&declProp, &propCtx)) { + raiseModuleBoundaryViolation(m_cls, key, propCtx.moduleName()); + } + return { prop, &declProp, diff --git a/hphp/runtime/vm/class.cpp b/hphp/runtime/vm/class.cpp index 36a38d92a32..b08e79b60e1 100644 --- a/hphp/runtime/vm/class.cpp +++ b/hphp/runtime/vm/class.cpp @@ -1230,10 +1230,12 @@ Class::PropSlotLookup Class::getDeclPropSlot( auto const ctx = propCtx.cls(); auto accessible = false; auto readonly = false; + auto internal = false; if (propSlot != kInvalidSlot) { auto const attrs = m_declProperties[propSlot].attrs; readonly = bool(attrs & AttrIsReadonly); + internal = bool(attrs & AttrInternal); if ((attrs & (AttrProtected|AttrPrivate)) && (g_context.isNull() || !g_context->debuggerSettings.bypassCheck)) { // Fetch the class in the inheritance tree which first declared the @@ -1242,10 +1244,10 @@ Class::PropSlotLookup Class::getDeclPropSlot( assertx(baseClass); // If ctx == baseClass, we have the right property and we can stop here. - if (ctx == baseClass) return PropSlotLookup { propSlot, true, false, readonly }; + if (ctx == baseClass) return PropSlotLookup { propSlot, true, false, readonly, internal }; // The anonymous context cannot access protected or private properties, so // we can fail fast here. - if (ctx == nullptr) return PropSlotLookup { propSlot, false, false, readonly }; + if (ctx == nullptr) return PropSlotLookup { propSlot, false, false, readonly, internal }; if (attrs & AttrPrivate) { // ctx != baseClass and the property is private, so it is not @@ -1260,7 +1262,7 @@ Class::PropSlotLookup Class::getDeclPropSlot( // ctx is derived from baseClass, so we know this protected // property is accessible and we know ctx cannot have private // property with the same name, so we're done. - return PropSlotLookup { propSlot, true, false, readonly }; + return PropSlotLookup { propSlot, true, false, readonly, internal }; } if (!baseClass->classof(ctx)) { // ctx is not the same, an ancestor, or a descendent of baseClass, @@ -1268,7 +1270,7 @@ Class::PropSlotLookup Class::getDeclPropSlot( // be the same or an ancestor of this, so we don't need to check if // ctx declares a private property with the same name and we can // fail fast here. - return PropSlotLookup { propSlot, false, false, readonly }; + return PropSlotLookup { propSlot, false, false, readonly, internal }; } // We now know this protected property is accessible, but we need to // keep going because ctx may define a private property with the same @@ -1282,7 +1284,7 @@ Class::PropSlotLookup Class::getDeclPropSlot( accessible = true; // If ctx == this, we don't have to check if ctx defines a private // property with the same name and we can stop here. - if (ctx == this) return PropSlotLookup { propSlot, true, false, readonly }; + if (ctx == this) return PropSlotLookup { propSlot, true, false, readonly, internal }; // We still need to check if ctx defines a private property with the same // name. @@ -1303,7 +1305,8 @@ Class::PropSlotLookup Class::getDeclPropSlot( // A private property from ctx trumps any other property we may // have found. readonly = bool(ctx->m_declProperties[ctxPropSlot].attrs & AttrIsReadonly); - return PropSlotLookup { ctxPropSlot, true, false, readonly }; + internal = bool(ctx->m_declProperties[ctxPropSlot].attrs & AttrInternal); + return PropSlotLookup { ctxPropSlot, true, false, readonly, internal }; } } @@ -1318,7 +1321,7 @@ Class::PropSlotLookup Class::getDeclPropSlot( return m_parent->getDeclPropSlot(propCtx, key); } - return PropSlotLookup { propSlot, accessible, false, readonly }; + return PropSlotLookup { propSlot, accessible, false, readonly, internal }; } Class::PropSlotLookup Class::findSProp( @@ -1330,7 +1333,7 @@ Class::PropSlotLookup Class::findSProp( // Non-existent property. if (sPropInd == kInvalidSlot) - return PropSlotLookup { kInvalidSlot, false, false, false }; + return PropSlotLookup { kInvalidSlot, false, false, false, false }; auto const& sProp = m_staticProperties[sPropInd]; auto const sPropAttrs = sProp.attrs; @@ -1343,7 +1346,7 @@ Class::PropSlotLookup Class::findSProp( baseCls = sProp.cls; } // Property access within this Class's context. - if (ctx == baseCls) return PropSlotLookup { sPropInd, true, sPropConst, sPropReadOnly }; + if (ctx == baseCls) return PropSlotLookup { sPropInd, true, sPropConst, sPropReadOnly, false }; auto const accessible = [&] { switch (sPropAttrs & (AttrPublic | AttrProtected | AttrPrivate)) { @@ -1365,8 +1368,8 @@ Class::PropSlotLookup Class::findSProp( } not_reached(); }(); - - return PropSlotLookup { sPropInd, accessible, sPropConst, sPropReadOnly }; + // TODO(T130877659): Static property enforcement + return PropSlotLookup { sPropInd, accessible, sPropConst, sPropReadOnly, false }; } Class::PropValLookup Class::getSPropIgnoreLateInit( diff --git a/hphp/runtime/vm/class.h b/hphp/runtime/vm/class.h index 61d2c3f60eb..84780feb6ab 100644 --- a/hphp/runtime/vm/class.h +++ b/hphp/runtime/vm/class.h @@ -207,6 +207,14 @@ struct Class : AtomicCountable { * Slot number that is only valid for reflection and serialization. */ Slot serializationIdx; + + bool isInternal() const { + return (attrs & AttrInternal); + } + + const StringData* moduleName() const { + return cls.get()->moduleName(); + } }; /* @@ -1008,6 +1016,7 @@ public: bool accessible; bool constant; bool readonly; + bool internal; }; /* diff --git a/hphp/runtime/vm/jit/dce.cpp b/hphp/runtime/vm/jit/dce.cpp index d08c0f2ae24..b0a2a0461b1 100644 --- a/hphp/runtime/vm/jit/dce.cpp +++ b/hphp/runtime/vm/jit/dce.cpp @@ -533,6 +533,7 @@ bool canDCE(const IRInstruction& inst) { case RaiseCoeffectsFunParamCoeffectRulesViolation: case RaiseStrToClassNotice: case RaiseModuleBoundaryViolation: + case RaiseModulePropertyViolation: case RaiseImplicitContextStateInvalid: case CheckClsMethFunc: case CheckClsReifiedGenericMismatch: diff --git a/hphp/runtime/vm/jit/extra-data.h b/hphp/runtime/vm/jit/extra-data.h index 55e9ea67633..26e95c2395d 100644 --- a/hphp/runtime/vm/jit/extra-data.h +++ b/hphp/runtime/vm/jit/extra-data.h @@ -2896,6 +2896,7 @@ X(RaiseCoeffectsCallViolation, FuncData); X(RaiseCoeffectsFunParamTypeViolation, ParamData); X(RaiseModuleBoundaryViolation, OptClassAndFuncData); +X(RaiseModulePropertyViolation, OptClassAndFuncData); X(CallViolatesModuleBoundary, FuncData); X(CheckInOutMismatch, BoolVecArgsData); X(ThrowInOutMismatch, ParamData); diff --git a/hphp/runtime/vm/jit/ir-opcode.cpp b/hphp/runtime/vm/jit/ir-opcode.cpp index ccbf711d93b..ab0050d4d87 100644 --- a/hphp/runtime/vm/jit/ir-opcode.cpp +++ b/hphp/runtime/vm/jit/ir-opcode.cpp @@ -387,6 +387,7 @@ bool opcodeMayRaise(Opcode opc) { case RaiseForbiddenDynConstruct: case RaiseImplicitContextStateInvalid: case RaiseModuleBoundaryViolation: + case RaiseModulePropertyViolation: case RaiseNotice: case RaiseStrToClassNotice: case RaiseTooManyArg: diff --git a/hphp/runtime/vm/jit/irgen-call.cpp b/hphp/runtime/vm/jit/irgen-call.cpp index ce6fef88130..4a9da9dd210 100644 --- a/hphp/runtime/vm/jit/irgen-call.cpp +++ b/hphp/runtime/vm/jit/irgen-call.cpp @@ -1249,6 +1249,15 @@ void emitModuleBoundaryCheckKnown(IRGS& env, const T* symbol) { template void emitModuleBoundaryCheckKnown(IRGS&, const Func*); template void emitModuleBoundaryCheckKnown(IRGS&, const Class*); +template<> +void emitModuleBoundaryCheckKnown(IRGS& env, const Class::Prop* prop) { + auto const caller = curFunc(env); + if (will_symbol_raise_module_boundary_violation(prop, caller)) { + auto const data = OptClassAndFuncData { curClass(env), caller }; + gen(env, RaiseModulePropertyViolation, data, cns(env, prop->cls.get()), cns(env, prop->name.get())); + } +} + void emitModuleBoundaryCheck(IRGS& env, SSATmp* symbol, bool func /* = true */) { if (!RO::EvalEnforceModules) return; auto const caller = curFunc(env); diff --git a/hphp/runtime/vm/jit/irgen-call.h b/hphp/runtime/vm/jit/irgen-call.h index 299528e460d..ee73b332872 100644 --- a/hphp/runtime/vm/jit/irgen-call.h +++ b/hphp/runtime/vm/jit/irgen-call.h @@ -18,6 +18,12 @@ #include #include "hphp/runtime/vm/hhbc.h" +#include "hphp/runtime/vm/module.h" +#include "hphp/runtime/vm/jit/extra-data.h" +#include "hphp/runtime/vm/jit/ir-opcode.h" +#include "hphp/runtime/vm/jit/irgen-interpone.h" +#include "hphp/runtime/vm/jit/irgen-internal.h" +#include "hphp/runtime/vm/jit/minstr-helpers.h" #include "hphp/runtime/vm/jit/stack-offsets.h" namespace HPHP { @@ -47,8 +53,7 @@ void emitModuleBoundaryCheck(IRGS&, SSATmp* symbol, bool func = true); template void emitModuleBoundaryCheckKnown(IRGS&, const T* symbol); - ////////////////////////////////////////////////////////////////////// -}}} +}}} diff --git a/hphp/runtime/vm/jit/irgen-minstr.cpp b/hphp/runtime/vm/jit/irgen-minstr.cpp index b2fba9478b6..164a20bc4da 100644 --- a/hphp/runtime/vm/jit/irgen-minstr.cpp +++ b/hphp/runtime/vm/jit/irgen-minstr.cpp @@ -30,6 +30,7 @@ #include "hphp/runtime/vm/jit/type.h" #include "hphp/runtime/vm/jit/irgen-arith.h" +#include "hphp/runtime/vm/jit/irgen-call.h" #include "hphp/runtime/vm/jit/irgen-exit.h" #include "hphp/runtime/vm/jit/irgen-incdec.h" #include "hphp/runtime/vm/jit/irgen-inlining.h" @@ -38,6 +39,7 @@ #include "hphp/runtime/vm/jit/irgen-types.h" #include "hphp/runtime/vm/jit/irgen-internal.h" +#include "hphp/runtime/vm/module.h" #include "hphp/runtime/ext/collections/ext_collections-map.h" #include "hphp/runtime/ext/collections/ext_collections-pair.h" @@ -79,7 +81,7 @@ struct PropInfo { Type knownType, const HPHP::TypeConstraint* typeConstraint, const UpperBoundVec* ubs, - const Class* objClass, + const Class::Prop* objProp, const Class* propClass) : slot{slot} , index{index} @@ -90,7 +92,7 @@ struct PropInfo { , knownType{std::move(knownType)} , typeConstraint{typeConstraint} , ubs{ubs} - , objClass{objClass} + , objProp{objProp} , propClass{propClass} {} @@ -103,8 +105,9 @@ struct PropInfo { Type knownType{TCell}; const HPHP::TypeConstraint* typeConstraint{nullptr}; const UpperBoundVec* ubs{nullptr}; - const Class* objClass{nullptr}; + const Class::Prop* objProp{nullptr}; const Class* propClass{nullptr}; + }; Type knownTypeForProp(const Class::Prop& prop, @@ -201,7 +204,7 @@ getPropertyOffset(IRGS& env, knownTypeForProp(prop, baseClass, ctx, ignoreLateInit), &prop.typeConstraint, &prop.ubs, - baseClass, + &prop, prop.cls ); } @@ -337,7 +340,7 @@ SSATmp* emitPropSpecialized( assertx(base->isA(TObj)); assertx(IMPLIES(propInfo.lateInitCheck, propInfo.lateInit)); - + emitModuleBoundaryCheckKnown(env, propInfo.objProp); if (!propInfo.lateInitCheck && (propInfo.lateInit || mode != MOpMode::Warn || diff --git a/hphp/runtime/vm/jit/irlower-exception.cpp b/hphp/runtime/vm/jit/irlower-exception.cpp index 24bdb339f88..719b6fd0e92 100644 --- a/hphp/runtime/vm/jit/irlower-exception.cpp +++ b/hphp/runtime/vm/jit/irlower-exception.cpp @@ -237,6 +237,15 @@ void cgRaiseModuleBoundaryViolation(IRLS& env, const IRInstruction* inst) { cgCallHelper(vmain(env), env, target, kVoidDest, SyncOptions::Sync, args); } +void cgRaiseModulePropertyViolation(IRLS& env, const IRInstruction* inst) { + auto const data = inst->extra(); + assertx(inst->src(0)->isA(TCls)); + assertx(inst->src(1)->isA(TStr)); + using Fn = void(*)(const Class*, const StringData* prop, const StringData*); + auto const target = CallSpec::direct(static_cast(raiseModuleBoundaryViolation)); + auto const args = argGroup(env, inst).ssa(0).ssa(1).imm(data->func->moduleName()); + cgCallHelper(vmain(env), env, target, kVoidDest, SyncOptions::Sync, args); +} /////////////////////////////////////////////////////////////////////////////// IMPL_OPCODE_CALL(InitThrowableFileAndLine) diff --git a/hphp/runtime/vm/jit/memory-effects.cpp b/hphp/runtime/vm/jit/memory-effects.cpp index ced8596b3a4..818bc27a939 100644 --- a/hphp/runtime/vm/jit/memory-effects.cpp +++ b/hphp/runtime/vm/jit/memory-effects.cpp @@ -1773,6 +1773,7 @@ MemEffects memory_effects_impl(const IRInstruction& inst) { case RaiseCoeffectsFunParamTypeViolation: case LdCoeffectFunParamNaive: case RaiseModuleBoundaryViolation: + case RaiseModulePropertyViolation: case RaiseImplicitContextStateInvalid: return may_load_store(AEmpty, AEmpty); diff --git a/hphp/runtime/vm/module.cpp b/hphp/runtime/vm/module.cpp index 5aec3b34ef8..6befec8e1f0 100644 --- a/hphp/runtime/vm/module.cpp +++ b/hphp/runtime/vm/module.cpp @@ -86,6 +86,8 @@ bool will_symbol_raise_module_boundary_violation(const Sym* symbol, template bool will_symbol_raise_module_boundary_violation(const Func*, const Func*); template bool will_symbol_raise_module_boundary_violation(const Func*, const MemberLookupContext*); +template bool will_symbol_raise_module_boundary_violation(const Class::Prop*, const MemberLookupContext*); +template bool will_symbol_raise_module_boundary_violation(const Class::Prop*, const Func*); template bool will_symbol_raise_module_boundary_violation(const Class*, const Func*); } // namespace HPHP diff --git a/hphp/runtime/vm/runtime.cpp b/hphp/runtime/vm/runtime.cpp index f99eb70b806..13402738d59 100644 --- a/hphp/runtime/vm/runtime.cpp +++ b/hphp/runtime/vm/runtime.cpp @@ -451,6 +451,20 @@ void moduleBoundaryViolationImpl( } // namespace +void raiseModuleBoundaryViolation(const Class* cls, const StringData* prop, const StringData* callerModule) { + if (!RO::EvalEnforceModules) return; + assertx(cls); + assertx(prop); + DEBUG_ONLY auto const propSlot = cls->lookupDeclProp(prop); + DEBUG_ONLY auto const attrs = cls->declProperties()[propSlot].attrs; + assertx(attrs & AttrInternal); + return moduleBoundaryViolationImpl( + folly::sformat("property {}::${}", cls->name(), prop->data()), + cls->moduleName(), + callerModule + ); +} + void raiseModuleBoundaryViolation(const Class* ctx, const Func* callee, const StringData* callerModule) { diff --git a/hphp/runtime/vm/runtime.h b/hphp/runtime/vm/runtime.h index 0c5348923f0..f9a82a8f0ff 100644 --- a/hphp/runtime/vm/runtime.h +++ b/hphp/runtime/vm/runtime.h @@ -90,6 +90,7 @@ void raiseModuleBoundaryViolation(const Class* ctx, const StringData* callerModule); void raiseModuleBoundaryViolation(const Class* cls, const StringData* callerModule); +void raiseModuleBoundaryViolation(const Class* cls, const StringData* prop, const StringData* callerModule); void raiseImplicitContextStateInvalidDispatch(const Func*); diff --git a/hphp/test/slow/modules/instance-properties-incdec-throw.php b/hphp/test/slow/modules/instance-properties-incdec-throw.php new file mode 100644 index 00000000000..3e049d750e5 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-incdec-throw.php @@ -0,0 +1,15 @@ +> + + +<<__EntryPoint>> +function main(): void { + include "module.inc"; + include "instance-properties.inc"; + ok(); + $x = new Foo(vec[]); + try { + $x->x++; // error, cannot incdec internal property + } catch (Exception $e) { echo $e->getMessage()."\n"; } + +} diff --git a/hphp/test/slow/modules/instance-properties-incdec-throw.php.expectf b/hphp/test/slow/modules/instance-properties-incdec-throw.php.expectf new file mode 100644 index 00000000000..98a93d9c761 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-incdec-throw.php.expectf @@ -0,0 +1,2 @@ +int(4) +Accessing internal property Foo::$x in module foo from outside of a module is not allowed diff --git a/hphp/test/slow/modules/instance-properties-incdec-throw.php.hphp_opts b/hphp/test/slow/modules/instance-properties-incdec-throw.php.hphp_opts new file mode 100644 index 00000000000..6e9aae73812 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-incdec-throw.php.hphp_opts @@ -0,0 +1,2 @@ +--inputs=hphp/test/slow/modules/instance-properties.inc +--inputs=hphp/test/slow/modules/module.inc diff --git a/hphp/test/slow/modules/instance-properties-incdec-throw.php.opts b/hphp/test/slow/modules/instance-properties-incdec-throw.php.opts new file mode 100644 index 00000000000..c267f7044a9 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-incdec-throw.php.opts @@ -0,0 +1 @@ +-vEval.EnforceModules=2 diff --git a/hphp/test/slow/modules/instance-properties-incdec.php b/hphp/test/slow/modules/instance-properties-incdec.php new file mode 100644 index 00000000000..c01172dfaf8 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-incdec.php @@ -0,0 +1,12 @@ +> + + +<<__EntryPoint>> +function main(): void { + include "module.inc"; + include "instance-properties.inc"; + ok(); + $x = new Foo(vec[]); + $x->x++; // error, cannot incdec internal property +} diff --git a/hphp/test/slow/modules/instance-properties-incdec.php.expectf b/hphp/test/slow/modules/instance-properties-incdec.php.expectf new file mode 100644 index 00000000000..7b443dc1e4e --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-incdec.php.expectf @@ -0,0 +1,3 @@ +int(4) + +Warning: Accessing internal property Foo::$x in module foo from outside of a module is not allowed in %s on line 11 diff --git a/hphp/test/slow/modules/instance-properties-incdec.php.hphp_opts b/hphp/test/slow/modules/instance-properties-incdec.php.hphp_opts new file mode 100644 index 00000000000..6e9aae73812 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-incdec.php.hphp_opts @@ -0,0 +1,2 @@ +--inputs=hphp/test/slow/modules/instance-properties.inc +--inputs=hphp/test/slow/modules/module.inc diff --git a/hphp/test/slow/modules/instance-properties-throw-2.php b/hphp/test/slow/modules/instance-properties-throw-2.php new file mode 100644 index 00000000000..1e7edb34b52 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-throw-2.php @@ -0,0 +1,14 @@ +> + + +<<__EntryPoint>> +function main(): void { + include "module.inc"; + include "instance-properties.inc"; + ok(); + $x = new Foo(vec[]); + try { + $z = $x->x; // error, cannot get internal property + } catch (Exception $e) { echo $e->getMessage()."\n"; } +} diff --git a/hphp/test/slow/modules/instance-properties-throw-2.php.expectf b/hphp/test/slow/modules/instance-properties-throw-2.php.expectf new file mode 100644 index 00000000000..98a93d9c761 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-throw-2.php.expectf @@ -0,0 +1,2 @@ +int(4) +Accessing internal property Foo::$x in module foo from outside of a module is not allowed diff --git a/hphp/test/slow/modules/instance-properties-throw-2.php.hphp_opts b/hphp/test/slow/modules/instance-properties-throw-2.php.hphp_opts new file mode 100644 index 00000000000..6e9aae73812 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-throw-2.php.hphp_opts @@ -0,0 +1,2 @@ +--inputs=hphp/test/slow/modules/instance-properties.inc +--inputs=hphp/test/slow/modules/module.inc diff --git a/hphp/test/slow/modules/instance-properties-throw-2.php.opts b/hphp/test/slow/modules/instance-properties-throw-2.php.opts new file mode 100644 index 00000000000..c267f7044a9 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-throw-2.php.opts @@ -0,0 +1 @@ +-vEval.EnforceModules=2 diff --git a/hphp/test/slow/modules/instance-properties-throw-3.php b/hphp/test/slow/modules/instance-properties-throw-3.php new file mode 100644 index 00000000000..2441d113b38 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-throw-3.php @@ -0,0 +1,14 @@ +> + + +<<__EntryPoint>> +function main(): void { + include "module.inc"; + include "instance-properties.inc"; + ok(); + $x = new Foo(vec[]); + try { + $x->v[] = 6; // error cannot append to internal prop + } catch (Exception $e) { echo $e->getMessage()."\n"; } +} diff --git a/hphp/test/slow/modules/instance-properties-throw-3.php.expectf b/hphp/test/slow/modules/instance-properties-throw-3.php.expectf new file mode 100644 index 00000000000..16384d69c44 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-throw-3.php.expectf @@ -0,0 +1,2 @@ +int(4) +Accessing internal property Foo::$v in module foo from outside of a module is not allowed diff --git a/hphp/test/slow/modules/instance-properties-throw-3.php.hphp_opts b/hphp/test/slow/modules/instance-properties-throw-3.php.hphp_opts new file mode 100644 index 00000000000..6f09922719e --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-throw-3.php.hphp_opts @@ -0,0 +1,3 @@ +--inputs=hphp/test/slow/modules/instance-properties.inc +--inputs=hphp/test/slow/modules/module.inc + diff --git a/hphp/test/slow/modules/instance-properties-throw-3.php.opts b/hphp/test/slow/modules/instance-properties-throw-3.php.opts new file mode 100644 index 00000000000..c267f7044a9 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-throw-3.php.opts @@ -0,0 +1 @@ +-vEval.EnforceModules=2 diff --git a/hphp/test/slow/modules/instance-properties-throw.php b/hphp/test/slow/modules/instance-properties-throw.php new file mode 100644 index 00000000000..cc5106f26ca --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-throw.php @@ -0,0 +1,14 @@ +> + + +<<__EntryPoint>> +function main(): void { + include "module.inc"; + include "instance-properties.inc"; + ok(); + $x = new Foo(vec[]); + try { + $x->x = 10; // error, cannot set internal property + } catch (Exception $e) { echo $e->getMessage()."\n"; } +} diff --git a/hphp/test/slow/modules/instance-properties-throw.php.expectf b/hphp/test/slow/modules/instance-properties-throw.php.expectf new file mode 100644 index 00000000000..98a93d9c761 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-throw.php.expectf @@ -0,0 +1,2 @@ +int(4) +Accessing internal property Foo::$x in module foo from outside of a module is not allowed diff --git a/hphp/test/slow/modules/instance-properties-throw.php.hphp_opts b/hphp/test/slow/modules/instance-properties-throw.php.hphp_opts new file mode 100644 index 00000000000..6e9aae73812 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-throw.php.hphp_opts @@ -0,0 +1,2 @@ +--inputs=hphp/test/slow/modules/instance-properties.inc +--inputs=hphp/test/slow/modules/module.inc diff --git a/hphp/test/slow/modules/instance-properties-throw.php.opts b/hphp/test/slow/modules/instance-properties-throw.php.opts new file mode 100644 index 00000000000..c267f7044a9 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties-throw.php.opts @@ -0,0 +1 @@ +-vEval.EnforceModules=2 diff --git a/hphp/test/slow/modules/instance-properties.inc b/hphp/test/slow/modules/instance-properties.inc new file mode 100644 index 00000000000..247ddc10e98 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties.inc @@ -0,0 +1,17 @@ +> +module foo; + +class Foo { + internal int $x = 5; + + public function __construct(internal vec $v) { + $this->v = $v; + } +} + +function ok(): void { + $x = new Foo(vec[2]); + $x->x = 4; + var_dump($x->x); +} diff --git a/hphp/test/slow/modules/instance-properties.php b/hphp/test/slow/modules/instance-properties.php new file mode 100644 index 00000000000..b09abfde653 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties.php @@ -0,0 +1,12 @@ +> + + +<<__EntryPoint>> +function main(): void { + include "module.inc"; + include "instance-properties.inc"; + ok(); + $x = new Foo(vec[]); + $x->x = 10; // error, cannot set internal property +} diff --git a/hphp/test/slow/modules/instance-properties.php.expectf b/hphp/test/slow/modules/instance-properties.php.expectf new file mode 100644 index 00000000000..7b443dc1e4e --- /dev/null +++ b/hphp/test/slow/modules/instance-properties.php.expectf @@ -0,0 +1,3 @@ +int(4) + +Warning: Accessing internal property Foo::$x in module foo from outside of a module is not allowed in %s on line 11 diff --git a/hphp/test/slow/modules/instance-properties.php.hphp_opts b/hphp/test/slow/modules/instance-properties.php.hphp_opts new file mode 100644 index 00000000000..6e9aae73812 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties.php.hphp_opts @@ -0,0 +1,2 @@ +--inputs=hphp/test/slow/modules/instance-properties.inc +--inputs=hphp/test/slow/modules/module.inc diff --git a/hphp/test/slow/modules/instance-properties2.php b/hphp/test/slow/modules/instance-properties2.php new file mode 100644 index 00000000000..22c42578c03 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties2.php @@ -0,0 +1,12 @@ +> + + +<<__EntryPoint>> +function main(): void { + include "module.inc"; + include "instance-properties.inc"; + ok(); + $x = new Foo(vec[]); + $z = $x->x; // error, cannot get internal property +} diff --git a/hphp/test/slow/modules/instance-properties2.php.expectf b/hphp/test/slow/modules/instance-properties2.php.expectf new file mode 100644 index 00000000000..7b443dc1e4e --- /dev/null +++ b/hphp/test/slow/modules/instance-properties2.php.expectf @@ -0,0 +1,3 @@ +int(4) + +Warning: Accessing internal property Foo::$x in module foo from outside of a module is not allowed in %s on line 11 diff --git a/hphp/test/slow/modules/instance-properties2.php.hphp_opts b/hphp/test/slow/modules/instance-properties2.php.hphp_opts new file mode 100644 index 00000000000..6e9aae73812 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties2.php.hphp_opts @@ -0,0 +1,2 @@ +--inputs=hphp/test/slow/modules/instance-properties.inc +--inputs=hphp/test/slow/modules/module.inc diff --git a/hphp/test/slow/modules/instance-properties3.php b/hphp/test/slow/modules/instance-properties3.php new file mode 100644 index 00000000000..1a85e222097 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties3.php @@ -0,0 +1,12 @@ +> + + +<<__EntryPoint>> +function main(): void { + include "module.inc"; + include "instance-properties.inc"; + ok(); + $x = new Foo(vec[]); + $x->v[] = 6; // error cannot append to internal prop +} diff --git a/hphp/test/slow/modules/instance-properties3.php.expectf b/hphp/test/slow/modules/instance-properties3.php.expectf new file mode 100644 index 00000000000..5f4c7eb9f64 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties3.php.expectf @@ -0,0 +1,3 @@ +int(4) + +Warning: Accessing internal property Foo::$v in module foo from outside of a module is not allowed in %s on line 11 diff --git a/hphp/test/slow/modules/instance-properties3.php.hphp_opts b/hphp/test/slow/modules/instance-properties3.php.hphp_opts new file mode 100644 index 00000000000..6e9aae73812 --- /dev/null +++ b/hphp/test/slow/modules/instance-properties3.php.hphp_opts @@ -0,0 +1,2 @@ +--inputs=hphp/test/slow/modules/instance-properties.inc +--inputs=hphp/test/slow/modules/module.inc diff --git a/hphp/test/slow/modules/module.inc b/hphp/test/slow/modules/module.inc new file mode 100644 index 00000000000..69e791fe738 --- /dev/null +++ b/hphp/test/slow/modules/module.inc @@ -0,0 +1,3 @@ +> +new module foo {} -- 2.11.4.GIT