Fix a bug with boxed static/counted types
When we box things, we need to forget whether we knew it was static or not because we don't track when that might change.
Esse commit está contido em:
@@ -222,6 +222,8 @@ bool tvIsPlausible(const TypedValue* tv) {
|
||||
case KindOfStaticString:
|
||||
return okPtr(tv->m_data.pstr) && tv->m_data.pstr->isStatic();
|
||||
case KindOfString:
|
||||
return okPtr(tv->m_data.pstr) &&
|
||||
is_refcount_realistic(tv->m_data.pstr->getCount());
|
||||
case KindOfArray:
|
||||
return okPtr(tv->m_data.parr) &&
|
||||
is_refcount_realistic(tv->m_data.parr->getCount());
|
||||
|
||||
@@ -972,7 +972,7 @@ public:
|
||||
|
||||
explicit Type(bits_t bits = kNone)
|
||||
: m_bits(bits)
|
||||
{}
|
||||
{}
|
||||
|
||||
size_t hash() const {
|
||||
return hash_int64(m_bits);
|
||||
|
||||
@@ -48,14 +48,21 @@ Type builtinReturn(const IRInstruction* inst) {
|
||||
|
||||
Type boxReturn(const IRInstruction* inst, int srcId) {
|
||||
auto t = inst->getSrc(srcId)->getType();
|
||||
// If t contains Uninit, replace it with InitNull. Otherwise, leave
|
||||
// the type alone.
|
||||
// If t contains Uninit, replace it with InitNull.
|
||||
t = t.maybe(Type::Uninit) ? (t - Type::Uninit) | Type::InitNull : t;
|
||||
// We don't try to track when a BoxedStaticStr might be converted to
|
||||
// a BoxedStr, and we never guard on staticness for strings, so
|
||||
// boxing a string needs to forget this detail. Same thing for
|
||||
// arrays.
|
||||
if (t.subtypeOf(Type::Str)) {
|
||||
t = Type::Str;
|
||||
} else if (t.subtypeOf(Type::Arr)) {
|
||||
t = Type::Arr;
|
||||
}
|
||||
// Everything else is just a pure type-system boxing operation.
|
||||
return t.box();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Type stkReturn(const IRInstruction* inst, int dstId,
|
||||
std::function<Type()> inner) {
|
||||
assert(inst->modifiesStack());
|
||||
@@ -68,6 +75,8 @@ Type stkReturn(const IRInstruction* inst, int dstId,
|
||||
return Type::StkPtr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Type outputType(const IRInstruction* inst, int dstId) {
|
||||
|
||||
#define D(type) return Type::type;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
function breaker(&$x) {
|
||||
$x = (string)mt_rand();
|
||||
}
|
||||
|
||||
function foo() {
|
||||
$x = "";
|
||||
breaker($x);
|
||||
// Bug #2240782: HHIR needs to think of $x as a BoxedStr, not a
|
||||
// BoxedStaticStr here.
|
||||
echo "Num: ";
|
||||
echo $x;
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
foo();
|
||||
@@ -0,0 +1 @@
|
||||
Num
|
||||
Arquivo executável
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
exec sed -e 's/:.*//g'
|
||||
Referência em uma Nova Issue
Bloquear um usuário