Fix typecheck crashes
We didn't fill in the m_namedEntity field for hiphop-only type hints in non-hiphop mode, resulting in crashes when we tried to use them. Regardless of mode, we didn't check self or parent before checking a non-object parameter, resulting in asserts in dbg builds and seg-faults int opt builds.
Esse commit está contido em:
@@ -72,7 +72,9 @@ void TypeConstraint::init() {
|
||||
Type dtype;
|
||||
TRACE(5, "TypeConstraint: this %p type %s, nullable %d\n",
|
||||
this, typeName->data(), nullable());
|
||||
if (!mapGet(s_typeNamesToTypes, typeName, &dtype)) {
|
||||
if (!mapGet(s_typeNamesToTypes, typeName, &dtype) ||
|
||||
!(hhType() || dtype.m_dt == KindOfArray || dtype.isParent() ||
|
||||
dtype.isSelf())) {
|
||||
TRACE(5, "TypeConstraint: this %p no such type %s, treating as object\n",
|
||||
this, typeName->data());
|
||||
m_type = { KindOfObject, Precise };
|
||||
@@ -80,15 +82,11 @@ void TypeConstraint::init() {
|
||||
TRACE(5, "TypeConstraint: NamedEntity: %p\n", m_namedEntity);
|
||||
return;
|
||||
}
|
||||
if (hhType() || dtype.m_dt == KindOfArray || dtype.isParent() ||
|
||||
dtype.isSelf()) {
|
||||
m_type = dtype;
|
||||
} else {
|
||||
m_type = { KindOfObject, Precise };
|
||||
}
|
||||
m_type = dtype;
|
||||
assert(m_type.m_dt != KindOfStaticString);
|
||||
assert(IMPLIES(isParent(), m_type.m_dt == KindOfObject));
|
||||
assert(IMPLIES(isSelf(), m_type.m_dt == KindOfObject));
|
||||
assert(IMPLIES(isCallable(), m_type.m_dt == KindOfObject));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -186,7 +184,7 @@ TypeConstraint::check(const TypedValue* tv, const Func* func) const {
|
||||
if (isCallable()) {
|
||||
return f_is_callable(tvAsCVarRef(tv));
|
||||
}
|
||||
return checkTypedefNonObj(tv);
|
||||
return isPrecise() && checkTypedefNonObj(tv);
|
||||
}
|
||||
|
||||
return equivDataTypes(m_type.m_dt, tv->m_type);
|
||||
|
||||
@@ -56,6 +56,9 @@ protected:
|
||||
constexpr bool isCallable() const {
|
||||
return m_metatype == Callable;
|
||||
}
|
||||
constexpr bool isPrecise() const {
|
||||
return m_metatype == Precise;
|
||||
}
|
||||
};
|
||||
|
||||
// m_type represents the DataType to check on. We don't know
|
||||
@@ -109,6 +112,10 @@ public:
|
||||
return m_type.isCallable();
|
||||
}
|
||||
|
||||
bool isPrecise() const {
|
||||
return m_type.isPrecise();
|
||||
}
|
||||
|
||||
bool isObjectOrTypedef() const {
|
||||
assert(IMPLIES(isParent(), m_type.m_dt == KindOfObject));
|
||||
assert(IMPLIES(isSelf(), m_type.m_dt == KindOfObject));
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
class X {
|
||||
function test(self $s) {
|
||||
var_dump($s);
|
||||
}
|
||||
}
|
||||
X::test("hello");
|
||||
@@ -0,0 +1 @@
|
||||
HipHop Fatal error: Argument 1 passed to X::test() must be an instance of X, string given in %s/test/quick/fail_self.php on line 5
|
||||
Referência em uma Nova Issue
Bloquear um usuário