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:
Jordan DeLong
2013-05-08 15:10:24 -07:00
commit de Sara Golemon
commit 19562faabc
4 arquivos alterados com 449 adições e 5 exclusões
+2 -4
Ver Arquivo
@@ -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:
+8 -1
Ver Arquivo
@@ -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:
+34
Ver Arquivo
@@ -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";
+405
Ver Arquivo
@@ -0,0 +1,405 @@
foo: 0
foo: 1
foo: 0
foo: 0
done