Translator analyze assumed strlen($x) is always an int
This was leading to people getting (int)&some_null_variant as the result of strlen. I think this came about when we implemented the 5.4 strlen semantics (we stopped returning 5 for strlen(array()), etc.)
Esse commit está contido em:
@@ -7400,14 +7400,12 @@ void TranslatorX64::translateContHandle(const Tracelet& t,
|
||||
void TranslatorX64::analyzeStrlen(Tracelet& t,
|
||||
NormalizedInstruction& i) {
|
||||
switch (i.inputs[0]->rtt.valueType()) {
|
||||
NULLCASE() :
|
||||
case KindOfBoolean:
|
||||
i.m_txFlags = Native;
|
||||
break;
|
||||
STRINGCASE() :
|
||||
// May have to destroy a StringData, but can't reenter
|
||||
i.m_txFlags = Simple;
|
||||
break;
|
||||
NULLCASE() :
|
||||
case KindOfBoolean:
|
||||
case KindOfArray:
|
||||
case KindOfInt64:
|
||||
case KindOfDouble:
|
||||
|
||||
@@ -423,6 +423,7 @@ enum OutTypeConstraints {
|
||||
OutBitOp, // For BitAnd, BitOr, BitXor
|
||||
OutSetOp, // For SetOpL
|
||||
OutIncDec, // For IncDecL
|
||||
OutStrlen, // OpStrLen
|
||||
OutClassRef, // KindOfClass
|
||||
OutNone
|
||||
};
|
||||
@@ -915,6 +916,11 @@ getDynLocType(const vector<DynLocation*>& inputs,
|
||||
KindOfInt64 : KindOfInvalid);
|
||||
}
|
||||
|
||||
case OutStrlen: {
|
||||
auto const& rtt = ni->inputs[0]->rtt;
|
||||
return RuntimeType(rtt.isString() ? KindOfInt64 : KindOfInvalid);
|
||||
}
|
||||
|
||||
case OutCInput: {
|
||||
assert(inputs.size() >= 1);
|
||||
const DynLocation* in = inputs[inputs.size() - 1];
|
||||
@@ -1275,7 +1281,7 @@ static const struct {
|
||||
{ OpContCurrent, {None, Stack1, OutUnknown, 1 }},
|
||||
{ OpContStopped, {None, None, OutNone, 0 }},
|
||||
{ OpContHandle, {Stack1, None, OutNone, -1 }},
|
||||
{ OpStrlen, {Stack1, Stack1, OutInt64, 0 }},
|
||||
{ OpStrlen, {Stack1, Stack1, OutStrlen, 0 }},
|
||||
{ OpIncStat, {None, None, OutNone, 0 }},
|
||||
};
|
||||
|
||||
@@ -2111,6 +2117,7 @@ bool outputDependsOnInput(const Opcode instr) {
|
||||
case OutClassRef:
|
||||
case OutPred:
|
||||
case OutCns:
|
||||
case OutStrlen:
|
||||
case OutNone:
|
||||
return false;
|
||||
case OutFDesc:
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
function none() {}
|
||||
set_error_handler('none');
|
||||
|
||||
class Foo {
|
||||
}
|
||||
|
||||
function asdf($pattern) {
|
||||
$len = strlen($pattern);
|
||||
$len--;
|
||||
echo $len;
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function main() {
|
||||
$foo = new Foo();
|
||||
for ($i=0; $i<100; $i++) {
|
||||
asdf(new Foo());
|
||||
asdf(array());
|
||||
}
|
||||
}
|
||||
main();
|
||||
main();
|
||||
|
||||
function main2() {
|
||||
echo "foo: " .strlen($x)."\n";
|
||||
echo "foo: " .strlen(true)."\n";
|
||||
echo "foo: " .strlen(NULL)."\n";
|
||||
echo "foo: " .strlen(false)."\n";
|
||||
}
|
||||
main2();
|
||||
|
||||
echo "done\n";
|
||||
@@ -0,0 +1,405 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
foo: 0
|
||||
foo: 1
|
||||
foo: 0
|
||||
foo: 0
|
||||
done
|
||||
Referência em uma Nova Issue
Bloquear um usuário