/* +----------------------------------------------------------------------+ | HipHop for PHP | +----------------------------------------------------------------------+ | Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ */ #include #include #include #include #include #include #include #include #include #include #include #include #include using std::istringstream; using std::ostringstream; /////////////////////////////////////////////////////////////////////////////// const char *TestCodeRun::Filter = 0; // By default, use shared linking for faster testing. bool TestCodeRun::FastMode = true; TestCodeRun::TestCodeRun() : m_perfMode(false), m_test(0) { Option::KeepStatementsWithNoEffect = false; Option::ParserThreadCount = 4; } bool TestCodeRun::preTest() { if (!CleanUp()) return false; m_infos.clear(); return true; } bool TestCodeRun::postTest() { return true; } bool TestCodeRun::CleanUp() { string out, err; const char *argv[] = {"", nullptr}; Process::Exec("runtime/tmp/cleanup.sh", argv, nullptr, out, &err); if (!err.empty()) { printf("Failed to clean up runtime/tmp: %s\n", err.c_str()); return false; } return true; } static bool GenerateMainPHP(const std::string &fullPath, const char *file, int line, const char *input) { Util::mkdir(fullPath.c_str()); std::ofstream f(fullPath.c_str()); if (!f) { printf("Unable to open %s for write. Run this test from hphp/.\n", fullPath.c_str()); return false; } if (file && !strncmp(input, " 1000) sinput = "(long program)"; // we have to adjust timing by removing loop cost, which is the 1st test static int adj1 = -1; static int adj2 = -1; int ms1 = atoi(expected.c_str()); int ms2 = atoi(actual.c_str()); if (adj1 == -1) adj1 = ms1; if (adj2 == -1) adj2 = ms2; int msAdj1 = ms1 - adj1; int msAdj2 = ms2 - adj2; double x = 0.0; // how many times faster double p = 0.0; // percentage if (msAdj2 != 0) { x = ((double)(int)(msAdj1 * 100 / msAdj2)) / 100; } if (msAdj1 != 0) { p = ((double)(int)(msAdj2 * 10000 / msAdj1)) / 100; } printf("----------------------------------------------------------\n" "%s\n\n" " PHP C++\n" "===========================================\n" " %6d ms %6d ms\n" " -%6d ms %6d ms\n" "===========================================\n" " %6d ms %6d ms = %2.4gx or %2.4g%%\n\n", sinput.c_str(), ms1, ms2, adj1, adj2, msAdj1, msAdj2, x, p); return true; } bool out_ok = actual == expected; if (!out_ok || (!nowarnings && !err.empty())) { if (out_ok && err.find("symbol lookup error:") != string::npos && err.find("undefined symbol: ") != string::npos) { printf("%s: Ignoring loader error: %s\n", fullPath.c_str(), err.c_str()); } else { printf("======================================\n" "%s:\n" "======================================\n" "%s:%d\nParsing: [%s]\nBet %d:\n" "--------------------------------------\n" "%s" "--------------------------------------\n" "Got %d:\n" "--------------------------------------\n" "%s" "--------------------------------------\n" "Err: [%s]\n", fullPath.c_str(), file, line, input, (int)expected.length(), escape(expected).c_str(), (int)actual.length(), escape(actual).c_str(), err.c_str()); return false; } } } return true; } bool TestCodeRun::RecordMulti(const char *input, const char *output, const char *file, int line, bool nowarnings, bool fileoutput) { if (Filter) { const char *errptr; int erroffset; pcre *re = pcre_compile(Filter, PCRE_CASELESS, &errptr, &erroffset, 0); if (re && pcre_exec(re, 0, input, strlen(input), 0, 0, 0, 0) >= 0) { return true; } } string fullPath = "runtime/tmp/" + Test::s_suite + "/" + test_name + "/tcr-" + boost::lexical_cast(m_test++); if (!GenerateMainPHP(fullPath + "/main.php", file, line, input)) return false; if (nowarnings) { std::ofstream((fullPath + "/nowarnings").c_str()); } if (!m_compileOptions.empty()) { std::ofstream s((fullPath + "/build.opts").c_str()); s << m_compileOptions; } if (!m_runtimeOptions.empty()) { std::ofstream s((fullPath + "/test.opts").c_str()); s << m_runtimeOptions; } if (!m_envVars.empty()) { std::ofstream s((fullPath + "/test.env").c_str()); s << m_envVars; } if (output) { std::ofstream s((fullPath + "/test.result").c_str()); if (fileoutput) { String expected = f_file_get_contents(output); s << string(expected.data(), expected.size()); } else { s << output; } } return true; } bool TestCodeRun::VerifyCodeRun(const char *input, const char *output, const char *file /* = "" */, int line /* = 0 */, bool nowarnings /* = false */, bool fileoutput /* = false */) { assert(input); if (!CleanUp()) return false; return verify_result(input, output, m_perfMode, file, line, nowarnings, fileoutput, "Test0", FastMode); } /////////////////////////////////////////////////////////////////////////////// #define GEN_TEST(test) \ if (!which.empty() && which != #test) { \ } else { \ test_name = #test; \ test(); \ } bool TestCodeRun::RunTests(const std::string &which) { CleanUp(); bool ret = true; GEN_TEST(TestSanity); GEN_TEST(TestInnerFunction); GEN_TEST(TestInnerClass); GEN_TEST(TestVariableArgument); GEN_TEST(TestArgumentHandling); GEN_TEST(TestListAssignment); GEN_TEST(TestExceptions); GEN_TEST(TestPredefined); GEN_TEST(TestLabels); GEN_TEST(TestPerfectVirtual); GEN_TEST(TestBoolean); GEN_TEST(TestInteger); GEN_TEST(TestDouble); GEN_TEST(TestString); GEN_TEST(TestLocale); GEN_TEST(TestArray); GEN_TEST(TestArrayInit); GEN_TEST(TestArrayCopy); GEN_TEST(TestArrayEscalation); GEN_TEST(TestArrayOffset); GEN_TEST(TestArrayAccess); GEN_TEST(TestArrayIterator); GEN_TEST(TestArrayForEach); GEN_TEST(TestArrayAssignment); GEN_TEST(TestArrayFunctions); GEN_TEST(TestArrayCSE); GEN_TEST(TestScalarArray); GEN_TEST(TestRange); GEN_TEST(TestVariant); GEN_TEST(TestObject); GEN_TEST(TestObjectProperty); GEN_TEST(TestObjectMethod); GEN_TEST(TestClassMethod); GEN_TEST(TestObjectMagicMethod); GEN_TEST(TestObjectInvokeMethod); GEN_TEST(TestObjectAssignment); GEN_TEST(TestNewObjectExpression); GEN_TEST(TestObjectPropertyExpression); GEN_TEST(TestCollectionClasses); GEN_TEST(TestComparisons); GEN_TEST(TestReference); GEN_TEST(TestUnset); GEN_TEST(TestDynamicConstants); GEN_TEST(TestDynamicVariables); GEN_TEST(TestDynamicProperties); GEN_TEST(TestDynamicFunctions); GEN_TEST(TestRenameFunction); GEN_TEST(TestIntercept); GEN_TEST(TestMaxInt); GEN_TEST(TestDynamicMethods); GEN_TEST(TestVolatile); GEN_TEST(TestHereDoc); GEN_TEST(TestProgramFunctions); GEN_TEST(TestCompilation); GEN_TEST(TestReflection); GEN_TEST(TestReflectionClasses); GEN_TEST(TestErrorHandler); GEN_TEST(TestAssertOptions); GEN_TEST(TestExtMisc); GEN_TEST(TestInvalidArgument); GEN_TEST(TestSuperGlobals); GEN_TEST(TestGlobalStatement); GEN_TEST(TestStaticStatement); GEN_TEST(TestIfStatement); GEN_TEST(TestBreakStatement); GEN_TEST(TestContinueStatement); GEN_TEST(TestReturnStatement); GEN_TEST(TestAdd); GEN_TEST(TestMinus); GEN_TEST(TestMultiply); GEN_TEST(TestDivide); GEN_TEST(TestModulus); GEN_TEST(TestOperationTypes); GEN_TEST(TestUnaryOperators); GEN_TEST(TestSilenceOperator); GEN_TEST(TestPrint); GEN_TEST(TestVarExport); GEN_TEST(TestLogicalOperators); GEN_TEST(TestGetClass); GEN_TEST(TestGetParentClass); GEN_TEST(TestRedeclaredFunctions); GEN_TEST(TestRedeclaredClasses); GEN_TEST(TestReassignThis); GEN_TEST(TestClone); GEN_TEST(TestEvalOrder); GEN_TEST(TestGetObjectVars); GEN_TEST(TestSerialization); GEN_TEST(TestJson); GEN_TEST(TestThrift); GEN_TEST(TestExit); GEN_TEST(TestCreateFunction); GEN_TEST(TestConstructorDestructor); GEN_TEST(TestConcat); GEN_TEST(TestConstant); GEN_TEST(TestClassConstant); GEN_TEST(TestConstantFunction); GEN_TEST(TestDefined); GEN_TEST(TestSimpleXML); GEN_TEST(TestXML); GEN_TEST(TestDOMDocument); GEN_TEST(TestFile); GEN_TEST(TestUserWrappers); GEN_TEST(TestDirectory); GEN_TEST(TestAssignment); GEN_TEST(TestBadFunctionCalls); GEN_TEST(TestConstructor); GEN_TEST(TestIntIsset); GEN_TEST(TestTernary); GEN_TEST(TestUselessAssignment); GEN_TEST(TestTypes); GEN_TEST(TestSwitchStatement); GEN_TEST(TestExtString); GEN_TEST(TestExtArray); GEN_TEST(TestExtFile); GEN_TEST(TestExtDate); GEN_TEST(TestExtImage); GEN_TEST(TestExtSplFile); GEN_TEST(TestExtIterator); GEN_TEST(TestExtSoap); GEN_TEST(TestExtCollator); GEN_TEST(TestExtSocket); GEN_TEST(TestAPC); GEN_TEST(TestInlining); GEN_TEST(TestCopyProp); GEN_TEST(TestParser); GEN_TEST(TestTypeAssertions); GEN_TEST(TestSerialize); if (Option::EnableEval == Option::FullEval) { // hphpc is intentionally more liberal with its hoisting rules GEN_TEST(TestHoisting); } // PHP 5.3 features GEN_TEST(TestVariableClassName); GEN_TEST(TestLateStaticBinding); GEN_TEST(TestCallStatic); GEN_TEST(TestNowDoc); GEN_TEST(TestTernaryShortcut); GEN_TEST(TestGoto); GEN_TEST(TestClosure); if (false) { GEN_TEST(TestNamespace); } // PHP 5.4 features GEN_TEST(TestTraits); // PHP 5.5 features GEN_TEST(TestUConverter); // HipHop features GEN_TEST(TestYield); GEN_TEST(TestHint); GEN_TEST(TestUserAttributes); #ifdef TAINTED GEN_TEST(TestTaint); GEN_TEST(TestTaintExt); #endif GEN_TEST(TestStrictMode); GEN_TEST(TestAdHoc); { // We have a still unresolved repo contention issues with more // than 20 jobs. t1394416 int cpus = std::min(20, Process::GetCPUCount()); int jobs = cpus; char* hphp_slow_tests_jobs = getenv("HPHP_SLOW_TESTS_JOBS"); if (hphp_slow_tests_jobs) { int n = atoi(hphp_slow_tests_jobs); if (n > 0) jobs = n; } string cmd = "env -u MFLAGS -u MAKEFLAGS " "make -f runtime/tmp/test.mk --no-print-directory " "SUITE="+Test::s_suite + " -j" + boost::lexical_cast(jobs); if (::system(cmd.c_str())) { printf("Failed to run testsuite: %s\n", Test::s_suite.c_str()); return false; } std::ifstream in(("runtime/tmp/"+Test::s_suite+"/results").c_str()); if (in.fail()) return false; in >> fail_count; in >> pass_count; int total; in >> total; Test::s_passed = pass_count; Test::s_total = total; return total == pass_count && !fail_count; } return ret; } /////////////////////////////////////////////////////////////////////////////// // code generation bool TestCodeRun::TestSanity() { MVCR("#"); return true; } bool TestCodeRun::TestInnerFunction() { MVCR("p();"); MVCR("p();"); MVCR("p();"); return true; } bool TestCodeRun::TestVariableArgument() { MVCR("test('test'); $obj->test(1, 2, 3);"); MVCR("buz);" "unset($x);"); if (false) { MVCR(" 10, 'y' => 20, 'z' => 30, 'j' => 40));\n" " call_user_func_array($f, " " array(3 => 10, 80 => 20, 10 => 30, 30 => 40));\n" "}\n" "g(10);\n"); MVCR("container = array(" " 'one' => 1," " 'two' => 2," " 'three' => 3," " );" " }" " public function offsetSet($offset, $value) {" " $this->container[$offset] = $value;" " }" " public function offsetExists($offset) {" " return isset($this->container[$offset]);" " }" " public function offsetUnset($offset) {" " unset($this->container[$offset]);" " }" " public function offsetGet($offset) {" " return isset($this->container[$offset]) ? $this->container[$offset] : null;" " }" "}" "class SetTest {" " private $_vals = array(" " 'one' => 1," " 'two' => 2," " 'three' => 3," " );" " public function __set($name, $value) {" " $this->_vals[$name] = $value;" " }" "}" "$o = new obj;" "$q = list($o['one'], $o['two'], list($o['three'])) =" " array('eins', 'zwei', array('drei'));" "var_dump($o);" "var_dump($q);" "$x = new SetTest;" "$qq = list($x->one, $x->two, list($x->three)) = 1;" "var_dump($x);" "$qq = list($x->one, $x->two, list($x->three)) = $q;" "var_dump($x);" "var_dump($qq);"); MVCR("foo();" "X::$val = null;"); return true; } bool TestCodeRun::TestExceptions() { MVCR("getTrace(); foreach ($a as &$b) $b['file'] = 'string';\n" " var_dump($a);\n" " var_dump($exn->getLine());\n" "}\n" ); MVCR("getTrace(); foreach ($a as &$b) $b['file'] = 'string';\n" " var_dump($a);\n" " var_dump($exn->getLine());\n" " }\n" "}\n" "\n" "bar();\n"); MVCR("code, '\nm:', $this->message, '\n';" " echo 'x:', $this->x, '\ny:', $this->y, '\n';" " }" "}" "if (0) { class a extends Exception {} }" "try {" " throw(new b(1, 2));" "} catch (b $e) {" " $e->dump();" "}"); MVCR("foo();\n" "var_dump($ex->getMessage());\n"); MVCR("= Option::FullEval) { MVCRNW("getTrace();\n" " foreach ($bt as $k => $_) {\n" " $frame = $bt[$k];\n" " unset($frame['file']);\n" " unset($frame['line']);\n" " unset($frame['args']);\n" " ksort($frame);\n" " $bt[$k] = $frame;\n" " }\n" " var_dump($bt);\n" " }\n" " function f() {\n" " $this->g();\n" " }\n" "}\n" "$obj = new C;\n" "$obj->f();\n" "echo \"==========\\n\";\n" "Exception::setTraceOptions(true);\n" "$obj->f();\n" , "array(2) {\n" " [0]=>\n" " array(3) {\n" " [\"class\"]=>\n" " string(1) \"C\"\n" " [\"function\"]=>\n" " string(1) \"g\"\n" " [\"type\"]=>\n" " string(2) \"->\"\n" " }\n" " [1]=>\n" " array(3) {\n" " [\"class\"]=>\n" " string(1) \"C\"\n" " [\"function\"]=>\n" " string(1) \"f\"\n" " [\"type\"]=>\n" " string(2) \"->\"\n" " }\n" "}\n" "==========\n" "array(2) {\n" " [0]=>\n" " array(4) {\n" " [\"class\"]=>\n" " string(1) \"C\"\n" " [\"function\"]=>\n" " string(1) \"g\"\n" " [\"object\"]=>\n" " object(C)#1 (0) {\n" " }\n" " [\"type\"]=>\n" " string(2) \"->\"\n" " }\n" " [1]=>\n" " array(4) {\n" " [\"class\"]=>\n" " string(1) \"C\"\n" " [\"function\"]=>\n" " string(1) \"f\"\n" " [\"object\"]=>\n" " object(C)#1 (0) {\n" " }\n" " [\"type\"]=>\n" " string(2) \"->\"\n" " }\n" "}\n" ); if (false) { FinallyStatement w(this); MVCRO("getMessage();\n" " $e = $e->getPrevious();\n" " }\n" "}\n", "Exception 4" "Exception 3" "Exception 2" "Exception 1"); MVCRO("testr();"); MVCR("foo();" " $obj = new B; $obj->foo();" "} bar();" ); MVCR("foo();" " $obj = new B; $obj->foo();" "} bar();" ); MVCR("foo(123);" " $obj = new B; $obj->foo(123, 456);" "} bar();" ); MVCR("foo();" " $obj = new B; $obj->foo();" "} bar();" ); MVCR("foo(5);" " return ++$y;" "}" "test(new Y);"); return true; } /////////////////////////////////////////////////////////////////////////////// // type system bool TestCodeRun::TestBoolean() { MVCR("> 2);"); MVCR(">= 2; var_dump($a);"); MVCR("'foo');" "$b = 'qqq';" "class c {}" "$c = new c;" "$c->p = 'zzz';" "var_dump(\"AAA ${a['x']} $a[x] $b $c->p\");"); MVCR(" 1, 'abcd' => 2);\n" " $s .= 'c'; var_dump($a[$s]);\n" " $s .= 'd'; var_dump($a[$s]);\n" // should find 'abcd' in $a "}\n" "test('ab');\n"); MVCR(" '2', 'a' => '1'));"); MVCR(" 'a', 0 => 'b'));"); MVCR(" 1); var_dump($a);"); MVCR(" 2, 'a' => 1); var_dump($a);"); MVCR(" '1'); var_dump($a);"); MVCR(" '2', 'a' => '1'); var_dump($a);"); MVCR(" 1, 'a' => 2); var_dump($a);"); MVCR(" 1, 'b' => 2, 'a' => 3); var_dump($a);"); MVCR(" 2, 'a' => 1); " "foreach ($a as $item) print '['.$item.']';"); MVCR(" 2, 'a' => 1); " "foreach ($a as $name => $item) print '['.$name.'=>'.$item.']';"); MVCR(" 2, 'a' => 1); var_dump($a['b']);"); MVCR(" 2, 'a' => 1); var_dump($a['bogus']);"); MVCR(" 1); var_dump($a);"); MVCR(" 'test'); var_dump($a[1]);"); MVCR(" 1, 'b' => 2);" "foreach ($a as $b => $c) {" " var_dump($b);" " unset($a['b']);" "}"); MVCR(" 1, 'b' => 2);" "foreach ($a as $b => &$c) {" " var_dump($b);" " unset($a['b']);" "}"); MVCRO(" 1, 'b' => 2);" " foreach ($a as $b => &$c) {" " yield null;" " var_dump($b);" " unset($a['b']);" " }" "}" "foreach (gen() as $_) {}" , "string(1) \"a\"\n" ); MVCR(" $val) {" " if($val == 2) {" " $foo[$key] = 0;" " } else if($val == 3) {" " unset($foo[$key]);" " } else {" " $foo[$key] = $val + 1;" " }" "}" "var_dump($foo);"); MVCR(" &$val) {" " if($val == 2) {" " $foo[$key] = 0;" " } else if($val == 3) {" " unset($foo[$key]);" " } else {" " $val++;" " }" "}" "var_dump($foo);"); MVCRO(" &$val) {" " if($val == 2) {" " $foo[$key] = 0;" " } else if($val == 3) {" " unset($foo[$key]);" " } else {" " $val++;" " }" " }" " var_dump($foo);" " yield null;" "}" "foreach (gen() as $_) {}" , "array(3) {\n" " [0]=>\n" " int(2)\n" " [1]=>\n" " int(0)\n" " [3]=>\n" " &int(5)\n" "}\n" ); MVCR(" 'apple', 'b' => 'banana', 'c' => 'citrus');" "foreach ($a as $k1 => &$v1) {" " foreach ($a as $k2 => &$v2) {" " if ($k2 == 'a') {" " unset($a[$k2]);" " }" " var_dump($v1, $v2);" " }" "}"); MVCRO(" 'apple', 'b' => 'banana', 'c' => 'citrus');" " foreach ($a as $k1 => &$v1) {" " foreach ($a as $k2 => &$v2) {" " if ($k2 == 'a') {" " unset($a[$k2]);" " }" " var_dump($v1, $v2);" " }" " }" " yield null;" "}" "foreach (gen() as $_) {}" , "string(5) \"apple\"\n" "string(5) \"apple\"\n" "string(5) \"apple\"\n" "string(6) \"banana\"\n" "string(5) \"apple\"\n" "string(6) \"citrus\"\n" "string(6) \"banana\"\n" "string(6) \"banana\"\n" "string(6) \"banana\"\n" "string(6) \"citrus\"\n" "string(6) \"citrus\"\n" "string(6) \"banana\"\n" "string(6) \"citrus\"\n" "string(6) \"citrus\"\n" ); MVCR("f(array());"); MVCR(" array(2 => 'test'));" "unset($array['1'][2]);" "var_dump($array['1']);"); MVCR(" 0, 3 => true, 4 => true); " " var_dump($args);" " }" "}" "$obj = new A;" "$obj->foo(1, 2, 3);"); MVCRO("valid(); $o->next()) {" " $v = &$o->currentRef();" " var_dump($v);" " var_dump($v);" " }" " var_dump(array_key_exists('foo', $args));" " var_dump(array_unshift($args, 4));" " var_dump(array_pop($args));" " if (isset($args['foo'])) {}" " var_dump(each($args));" " var_dump(array_shift($args));" " }" "}" "$obj = new A;" "$obj->foo(1, 2, 3);", "int(1)\n" "int(1)\n" "int(2)\n" "int(2)\n" "int(3)\n" "int(3)\n" "bool(false)\n" "int(4)\n" "int(3)\n" "array(4) {\n" " [1]=>\n" " int(4)\n" " [\"value\"]=>\n" " int(4)\n" " [0]=>\n" " int(0)\n" " [\"key\"]=>\n" " int(0)\n" "}\n" "int(4)\n"); MVCR(" $a);" " if ($x) {" " var_dump(isset($x[0][1]), isset($x['foo'][1]));" " var_dump(isset($x[$b][1]), isset($x[$c][1]));" " var_dump(end($x[0]));" " }" "}" "test(5, array(0,1), 0, 'foo');"); MVCR(" null, 'b' => 123, 'c' => false);" "var_dump(array_keys($a));" "var_dump(array_keys($a, null));" "var_dump(array_keys($a, null, true));" ); return true; } bool TestCodeRun::TestArrayInit() { MVCR(" 1, new MyClass() => 2, " "false => 3, true => 4, count(array(1,2,3)) => 5);\n" "var_dump($arr);\n"); MVCR(" 'a', 1 => 'b', 2 => $p);" " $a[] = 'd';" " var_dump($a);" " $a = array(2 => 'a', 4 => 'b', 6 => $p);" " $a[] = 'd';" " var_dump($a);" " $a = array(-2 => 'a', -4 => 'b', -6 => $p);" " $a[] = 'd';" " var_dump($a);" " $a = array(0 => 'a');" " $a[] = 'b';" " var_dump($a);" "}" "foo('c');"); MVCR(" $b);\n" " $a[0] = $a; var_dump($a);\n" "}\n" "f(false);\n"); MVCR(" $b);\n" " $a2 = &$a; $a[] = $a2; var_dump($a);\n" "}\n" "f(false);\n" , "array(2) {\n" " [\"x\"]=>\n" " bool(false)\n" " [0]=>\n" " array(1) {\n" " [\"x\"]=>\n" " bool(false)\n" " }\n" "}\n"); MVCR(" true, false => 0, 1 => 1.0," " '1.0' => 1.23456789e+34," " 1.7976931348623157e+308 => 1E666," " 1E666/1E666 => \"a bc\"," " \"\\xc1 bc\");" "$a16 = array(null => true, false => 0, 1 => 1.0," " '1.0' => 1.23456789e+34," " 1.7976931348623157e+308 => 1E666," " 1E666/1E666 => \"a bc\"," " \"\\xc1 bc\"," " array(null => true, array()," " false => 0, 1 => 1.0," " '1.0' => 1.23456789e+34," " 1.7976931348623157e+308 => 1E666," " 1E666/1E666 => \"a bc\"," " \"\\xc1 bc\"));" "var_dump($a1);" "var_dump($a2);" "var_dump($a3);" "var_dump($a4);" "var_dump($a5);" "var_dump($a6);" "var_dump($a7);" "var_dump($a8);" "var_dump($a9);" "var_dump($a10);" "var_dump($a11);" "var_dump($a12);" "var_dump($a13);" "var_dump($a14);" "var_dump($a15);" "var_dump($a16);"); MVCR(" @VALUE));"); return true; } bool TestCodeRun::TestRange() { MVCR(" 20); var_dump($a);"); \ MVCR(" 'b'); var_dump($a);"); \ MVCR(" array(3)); var_dump($a);"); \ bool TestCodeRun::TestArrayEscalation() { TEST_ARRAY_CONVERT("array()"); TEST_ARRAY_CONVERT("array(10)"); TEST_ARRAY_CONVERT("array('test')"); TEST_ARRAY_CONVERT("array(array(0))"); TEST_ARRAY_CONVERT("array('a' => 10)"); TEST_ARRAY_CONVERT("array('a' => 'va')"); TEST_ARRAY_CONVERT("array('a' => array(1))"); TEST_ARRAY_PLUS("array()"); TEST_ARRAY_PLUS("array(10)"); TEST_ARRAY_PLUS("array('test')"); TEST_ARRAY_PLUS("array(array(0))"); TEST_ARRAY_PLUS("array('a' => 10)"); TEST_ARRAY_PLUS("array('a' => 'va')"); TEST_ARRAY_PLUS("array('a' => array(1))"); MVCR("$offset.'get';" " }" " public function offsetSet($offset, $value) {" " $this->$offset = $value.'set';" " }" " public function offsetUnset($offset) {" " $this->$offset = 'unset';" " }" "}" "function f() { var_dump('f()'); return 1; }\n" "function test($a) {\n" "$a['foo'] .= f();\n" "$a['bar'] += f();\n" "$a['bar'] -= f();\n" "$a['bar'] *= f();\n" "$a['bar'] /= f();\n" "$a['bar'] %= f();\n" "$a['bar'] &= f();\n" "$a['bar'] |= f();\n" "$a['bar'] ^= f();\n" "$a['bar'] <<= f();\n" "$a['bar'] >>= f();\n" "}\n" "test(new A);\n" ); MVCR("$offset.'get';" " }" " public function offsetSet($offset, $value) {" " $this->$offset = $value.'set';" " }" " public function offsetUnset($offset) {" " $this->$offset = 'unset';" " }" "}" "$obj = new A();" "if (!isset($obj['a'])) {" " $obj['a'] = 'test';" "}" "if (!empty($obj['a'])) {" " $obj['a'] = 'test2';" "}" "var_dump($obj['a']);" "unset($obj['a']);" "var_dump($obj['a']);" ); MVCR("data[$index];" " if(is_array($value)) {" " $u = new ArrayAccessImpl();" " foreach($value as $idx=>$e)" " $u[$idx]=$e;" " } else" " $u=$value;" " }" " public function offsetGet($index) {" " echo (\"GET: $index\\n\");" " if(!isset($this->data[$index]))" " $this->data[$index]=new ArrayAccessImpl();" " return $this->data[$index];" " }" " public function offsetExists($index) {" " echo (\"EXISTS: $index\\n\");" " if(isset($this->data[$index])) {" " if($this->data[$index] instanceof ArrayAccessImpl) {" " if(count($this->data[$index]->data)>0)" " return true;" " else" " return false;" " } else" " return true;" " } else" " return false;" " }" "}" "" "class ArrayAccessImpl2 extends ArrayAccessImpl {" " public function offsetUnset($index) { echo \"UNSET2: $index\\n\"; }" " public function offsetSet($index, $value) {" " echo (\"SET2: $index\\n\");" " if(isset($data[$index])) {" " unset($data[$index]);" " }" " $u = &$this->data[$index];" " if(is_array($value)) {" " $u = new ArrayAccessImpl();" " foreach($value as $idx=>$e)" " $u[$idx]=$e;" " } else" " $u=$value;" " }" " public function offsetGet($index) {" " echo (\"GET2: $index\\n\");" " if(!isset($this->data[$index]))" " $this->data[$index]=new ArrayAccessImpl();" " return $this->data[$index];" " }" " public function offsetExists($index) {" " echo (\"EXISTS2: $index\\n\");" " if(isset($this->data[$index])) {" " if($this->data[$index] instanceof ArrayAccessImpl) {" " if(count($this->data[$index]->data)>0)" " return true;" " else" " return false;" " } else" " return true;" " } else" " return false;" " }" "}" "offsetGet('foo');" "$data = new ArrayAccessImpl();" "$data['string']=\"Just a simple string\";" "$data['number']=33;" "$data['array']['another_string']=\"Alpha\";" "$data['array']['some_object']=new stdClass();" "$data['array']['another_array']['x']['y']=\"Beta\";" "$data['blank_array']=array();" "print_r(isset($data['array']));" "print_r($data['array']['non_existent']);" "print_r(isset($data['array']['non_existent']));" "print_r($data['blank_array']);" "print_r(isset($data['blank_array']));" "unset($data['blank_array']);" "print_r($data);" "$data2 = new ArrayAccessImpl2();" "$data2['string']=\"Just a simple string\";" "$data2['number']=33;" "$data2['array']['another_string']=\"Alpha\";" "$data2['array']['some_object']=new stdClass();" "$data2['array']['another_array']['x']['y']=\"Beta\";" "$data2['blank_array']=array();" "print_r(isset($data2['array']));" "print_r($data2['array']['non_existent']);" "print_r(isset($data2['array']['non_existent']));" "print_r($data2['blank_array']);" "print_r(isset($data2['blank_array']));" "unset($data2['blank_array']);" "print_r($data2);"); MVCR("foo = 1;" " var_dump($a, $b);" " $a = $x;" " $b = $a;" " $a[0][1] = 1;" " var_dump($a, $b);" " $a = $x;" " $c = &$a[0];" " $b = $a;" " $a[0][1] = 1;" " var_dump($a, $b);" " }" "test(array(false));" "var_dump(array(false));"); return true; } bool TestCodeRun::TestArrayIterator() { HipHopSyntax w(this); MVCR("var = $array;" " }" " }" " public function rewind() {" " echo \"rewinding\n\";" " reset($this->var);" " }" " public function current() {" " $var = current($this->var);" " echo \"current: $var\n\";" " return $var;" " }" " public function key() {" " $var = key($this->var);" " echo \"key: $var\n\";" " return $var;" " }" " public function next() {" " $var = next($this->var);" " echo \"next: $var\n\";" " return $var;" " }" " public function valid() {" " $var = $this->current() !== false;" " echo \"valid: {$var}\n\";" " return $var;" " }" "}" "$values = array(1,2,3);" "$it = new MyIterator($values);" "foreach ($it as $a => $b) {" " print \"$a: $b\n\";" "}" "$itp = \"it\";" "foreach ($$itp as $a => $b) {" " print \"$a: $b\n\";" "}" "function getIter() {" " $values = array(1,2,3);" " $it = new MyIterator($values);" " return $it;" "}" "foreach (getIter() as $a => $b) {" " print \"$a: $b\n\";" "}" "class MyIteratorAggregate implements IteratorAggregate {" " public function getIterator() {" " return getIter();" " }" "}" "$obj = new MyIteratorAggregate();" "foreach ($obj as $a => $b) {" " print \"$a: $b\n\";" "}" ); MVCR(" $v) { if ($v >= 4) $a = $v + $v; }\n" "var_dump($a);\n"); MVCR("valid()) {" " var_dump($it->key());" " var_dump($it->current());" " $it->next();" " }" "}" "test(array('a' => 'x'," " false => 'y'," " '1' => false," " null => 'z'," " 'c' => 'w'));"); MVCR("next());\n" "var_dump($o->rewind());\n" "var_dump($o->seek());\n" "var_dump($o->asort());\n" "var_dump($o->ksort());\n" "var_dump($o->natsort());\n" "var_dump($o->natcasesort());\n"); // MutableArrayIterator MVCRO(" &$v1) { $v1 += $k1; }\n" "var_dump($a);\n" "$a = array(1, 2, 3);\n" "for ($o = new MutableArrayIterator($a); $o->valid(); $o->next()) {\n" " $k2 = $o->key();\n" " $v2 = &$o->currentRef();\n" " $v2 += $k2;\n" "}\n" "var_dump($a);\n" , "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(3)\n" " [2]=>\n" " &int(5)\n" "}\n" "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(3)\n" " [2]=>\n" " &int(5)\n" "}\n"); MVCRO(" &$v1) { $v1 += $k1; }\n" " var_dump($a);\n" " $a = array(1, 2, 3);\n" " for ($o = new MutableArrayIterator($a); $o->valid(); $o->next()) {\n" " $k2 = $o->key();\n" " $v2 = &$o->currentRef();\n" " $v2 += $k2;\n" " }\n" " var_dump($a);\n" " yield null;\n" "}\n" "foreach (gen() as $_) {}\n" , "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(3)\n" " [2]=>\n" " &int(5)\n" "}\n" "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(3)\n" " [2]=>\n" " &int(5)\n" "}\n"); MVCR("tn = $tn; $this->tv = $tv; }" " function __destruct() {" " var_dump(__METHOD__);" " }" " public function gen() { return new I($this->tn, $this->tv); }" "}" "class JJ {" " private $tn, $tv;" " function __construct($tn, $tv) { $this->tn = $tn; $this->tv = $tv; }" " function __destruct() {" " var_dump(__METHOD__);" " }" " public function gen() { return new J($this->tn, $this->tv); }" "}" "class KK {" " private $tn, $tv;" " function __construct($tn, $tv) { $this->tn = $tn; $this->tv = $tv; }" " function __destruct() {" " var_dump(__METHOD__);" " }" " public function gen() { return new K($this->tn, $this->tv); }" "}" "class LL {" " private $tn, $tv;" " function __construct($tn, $tv) { $this->tn = $tn; $this->tv = $tv; }" " function __destruct() {" " var_dump(__METHOD__);" " }" " public function gen() { return new L($this->tn, $this->tv); }" "}" "class I implements Iterator" "{" " private $tn, $tv, $i = 0;" " public function gen() { return $this; }" " public function __construct($tn, $tv) {" " $this->tn = $tn;" " $this->tv = $tv;" " }" " public function __destruct() {" " var_dump(__METHOD__);" " }" " public function rewind() {" " var_dump(__METHOD__);" " if ($this->tn == 0) ex(__METHOD__);" " $this->i = 1;" " }" " public function current() {" " var_dump(__METHOD__);" " return $this->i;" " }" " public function key() {" " var_dump(__METHOD__);" " return $this->i;" " }" " public function next() {" " var_dump(__METHOD__);" " if ($this->tn == $this->i) ex(__METHOD__);" " return ++$this->i;" " }" " public function valid() {" " var_dump(__METHOD__);" " if ($this->tv == $this->i) ex(__METHOD__);" " return $this->i < 10;" " }" "}" "class J implements IteratorAggregate {" " private $i;" " public function __construct($tn, $tv) {" " $this->i = new I($tn, $tv);" " }" " public function __destruct() {" " var_dump(__METHOD__);" " }" " public function getIterator() { return $this->i; }" " public function gen() { return $this; }" "}" "class K implements IteratorAggregate {" " private $tn, $tv;" " public function __construct($tn, $tv) {" " $this->tn = $tn;" " $this->tv = $tv;" " }" " public function __destruct() {" " var_dump(__METHOD__);" " }" " public function getIterator() { return new I($this->tn, $this->tv); }" " public function gen() { return $this; }" "}" "class L implements IteratorAggregate {" " public function getIterator() { ex(__METHOD__); }" " public function gen() { return $this; }" "}" "function run($n, $tn, $tv) {" " var_dump('>>>main');" " $a = new A();" " $b = new $n($tn, $tv);" " $b->a = $a;" " try {" " foreach ($b->gen() as $k) {" " var_dump('got '.$k);" " }" " } catch(Exception $e) {" " var_dump('Exception: ' . $e->getMessage());" " unset($e);" " }" " unset($b);" " var_dump('<< &$val) {\n" " echo \"key=$key val=$val\\n\";\n" " if($val == 2) {\n" " $foo[$key] = 0;\n" " } else if($val == 3) {\n" " unset($foo[$key]);\n" " } else {\n" " $val++;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "f1();\n"); MVCRO(" &$val) {\n" " yield null;\n" " echo \"key=$key val=$val\\n\";\n" " if($val == 2) {\n" " $foo[$key] = 0;\n" " } else if($val == 3) {\n" " unset($foo[$key]);\n" " } else {\n" " $val++;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "foreach (f1() as $_) {}\n" , "key=0 val=1\n" "key=1 val=2\n" "key=2 val=3\n" "key=3 val=4\n" "array(3) {\n" " [0]=>\n" " int(2)\n" " [1]=>\n" " int(0)\n" " [3]=>\n" " &int(5)\n" "}\n" ); MVCR(" &$val) {\n" " echo \"key=$key val=$val\\n\";\n" " if($val == 2) {\n" " $foo[$key] = 0;\n" " } else if($val == 3) {\n" " $foo['a'] = 7;\n" " } else {\n" " $val++;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "f2();\n"); MVCRO(" &$val) {\n" " yield null;\n" " echo \"key=$key val=$val\\n\";\n" " if($val == 2) {\n" " $foo[$key] = 0;\n" " } else if($val == 3) {\n" " $foo['a'] = 7;\n" " } else {\n" " $val++;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "foreach (f2() as $_) {}\n" , "key=0 val=1\n" "key=1 val=2\n" "key=2 val=3\n" "key=3 val=4\n" "key=a val=7\n" "array(5) {\n" " [0]=>\n" " int(2)\n" " [1]=>\n" " int(0)\n" " [2]=>\n" " int(3)\n" " [3]=>\n" " int(5)\n" " [\"a\"]=>\n" " &int(8)\n" "}\n" ); /** * Zend PHP 5.2 outputs: * key=a val=1 * key=b val=2 * key=c val=333 * array(6) { * ["a"]=> * int(1) * ["b"]=> * int(2) * ["d"]=> * int(4) * ["e"]=> * int(5) * ["f"]=> * int(6) * ["c"]=> * &int(333) * } * * The difference in behavior is intentional. Under Zend, when the next * element is unset inside a foreach by reference loop, a heuristic is used * to figure out which element should be visited next. In this specific * example, the loop resumes at key 'c', skipping over keys 'd', 'e', and * 'f'. * * Under HPHP, when the next element is unset inside a foreach by loop, the * loop's iterator is appropriately updated. HPHP successfully upholds the * invariant that a foreach by refererence loop that exhausts the array will * visit every element that has not been deleted exactly once. */ MVCRO("1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5, 'f'=>6);\n" " $bar = array();\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'b' && $a == 0) {\n" " $a = 1;\n" " unset($foo['c']);\n" " $foo['c'] = 333;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "f3();\n" , "key=a val=1\n" "key=b val=2\n" "key=d val=4\n" "key=e val=5\n" "key=f val=6\n" "key=c val=333\n" "array(6) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " int(2)\n" " [\"d\"]=>\n" " int(4)\n" " [\"e\"]=>\n" " int(5)\n" " [\"f\"]=>\n" " int(6)\n" " [\"c\"]=>\n" " &int(333)\n" "}\n" ); MVCRO("1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5, 'f'=>6);\n" " $bar = array();\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " yield null;\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'b' && $a == 0) {\n" " $a = 1;\n" " unset($foo['c']);\n" " $foo['c'] = 333;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "foreach (f3() as $_) {}\n" , "key=a val=1\n" "key=b val=2\n" "key=d val=4\n" "key=e val=5\n" "key=f val=6\n" "key=c val=333\n" "array(6) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " int(2)\n" " [\"d\"]=>\n" " int(4)\n" " [\"e\"]=>\n" " int(5)\n" " [\"f\"]=>\n" " int(6)\n" " [\"c\"]=>\n" " &int(333)\n" "}\n" ); MVCR("1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5, 'f'=>6);\n" " $bar = array();\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'b' && $a == 0) {\n" " $a = 1;\n" " unset($foo['c']);\n" " $bar['b'] = 888;\n" " $foo['c'] = 333;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "f4();\n"); MVCRO("1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5, 'f'=>6);\n" " $bar = array();\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " yield null;\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'b' && $a == 0) {\n" " $a = 1;\n" " unset($foo['c']);\n" " $bar['b'] = 888;\n" " $foo['c'] = 333;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "foreach (f4() as $_) {}\n" , "key=a val=1\n" "key=b val=2\n" "key=d val=4\n" "key=e val=5\n" "key=f val=6\n" "key=c val=333\n" "array(6) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " int(2)\n" " [\"d\"]=>\n" " int(4)\n" " [\"e\"]=>\n" " int(5)\n" " [\"f\"]=>\n" " int(6)\n" " [\"c\"]=>\n" " &int(333)\n" "}\n" ); /** * Zend PHP 5.2 outputs: * key=f val=3 * key()=e current()=1 * key=e val=1 * key()=d current()=5 * key=d val=9 * key()=0s0 current()=0 * key=0s0 val=0 * key()=1s1 current()=1 * key=1s1 val=1 * key()=2s2 current()=2 * key=2s2 val=2 * key()=3s3 current()=3 * key=3s3 val=3 * key()=4s4 current()=4 * ... * * The difference in behavior is intentional. For more info, see testcase h3. */ MVCRO("3, 'e'=>1, 'd'=>5, 'a'=>6, 'b'=>2, 'c'=>4);\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'e' && $a == 0) {\n" " $a = 1;\n" " unset($foo['e']);\n" " unset($foo['d']);\n" " $foo['d'] = 9;\n" " for ($j = 0; $j < 10000; ++$j)\n" " $foo[$j . 's' . $j] = $j;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "f5();\n" , "key=f val=3\n" "key=e val=1\n" "key=a val=6\n" "key=b val=2\n" "key=c val=4\n" "key=d val=9\n" "key=0s0 val=0\n" "key=1s1 val=1\n" "key=2s2 val=2\n" "key=3s3 val=3\n" "key=4s4 val=4\n" "key=5s5 val=5\n" "key=6s6 val=6\n" "key=7s7 val=7\n" "key=8s8 val=8\n" "key=9s9 val=9\n" "key=10s10 val=10\n" "key=11s11 val=11\n" "key=12s12 val=12\n" "key=13s13 val=13\n" ); MVCRO("3, 'e'=>1, 'd'=>5, 'a'=>6, 'b'=>2, 'c'=>4);\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " yield null;\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'e' && $a == 0) {\n" " $a = 1;\n" " unset($foo['e']);\n" " unset($foo['d']);\n" " $foo['d'] = 9;\n" " for ($j = 0; $j < 10000; ++$j)\n" " $foo[$j . 's' . $j] = $j;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "foreach (f5() as $_) {}\n" , "key=f val=3\n" "key=e val=1\n" "key=a val=6\n" "key=b val=2\n" "key=c val=4\n" "key=d val=9\n" "key=0s0 val=0\n" "key=1s1 val=1\n" "key=2s2 val=2\n" "key=3s3 val=3\n" "key=4s4 val=4\n" "key=5s5 val=5\n" "key=6s6 val=6\n" "key=7s7 val=7\n" "key=8s8 val=8\n" "key=9s9 val=9\n" "key=10s10 val=10\n" "key=11s11 val=11\n" "key=12s12 val=12\n" "key=13s13 val=13\n" ); MVCR("3, 'e'=>1, 'd'=>5, 'a'=>6, 'b'=>2, 'c'=>4);\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'e' && $a == 0) {\n" " $a = 1;\n" " unset($foo['e']);\n" " unset($foo['d']);\n" " $bar['e'] = 8;\n" " $foo['d'] = 9;\n" " for ($j = 0; $j < 10000; ++$j)\n" " $foo[$j . 's' . $j] = $j;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "f6();\n"); MVCRO("3, 'e'=>1, 'd'=>5, 'a'=>6, 'b'=>2, 'c'=>4);\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " yield null;\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'e' && $a == 0) {\n" " $a = 1;\n" " unset($foo['e']);\n" " unset($foo['d']);\n" " $bar['e'] = 8;\n" " $foo['d'] = 9;\n" " for ($j = 0; $j < 10000; ++$j)\n" " $foo[$j . 's' . $j] = $j;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "foreach (f6() as $_) {}\n" , "key=f val=3\n" "key=e val=1\n" "key=a val=6\n" "key=b val=2\n" "key=c val=4\n" "key=d val=9\n" "key=0s0 val=0\n" "key=1s1 val=1\n" "key=2s2 val=2\n" "key=3s3 val=3\n" "key=4s4 val=4\n" "key=5s5 val=5\n" "key=6s6 val=6\n" "key=7s7 val=7\n" "key=8s8 val=8\n" "key=9s9 val=9\n" "key=10s10 val=10\n" "key=11s11 val=11\n" "key=12s12 val=12\n" "key=13s13 val=13\n" ); /** * Zend PHP 5.2 outputs: * key=0 value=0 * key=1 value=1 * key=2 value=0 * key=3 value=1 * * The difference in behavior is intentional. Under PHP, a foreach by * reference loop will not visit an element that is appended to the array * during the iteration for the last element in the array. * * Under HPHP, a foreach by reference loop will always visit an element that * is appended to the array during any iteration, provided that the element * is not deleted and the loop does not exit early. */ MVCRO(" &$v) {\n" " echo \"key=$k value=$v\\n\";\n" " if ($k == 0)\n" " $val = 1;\n" " else\n" " $val = $arr[$k-1];\n" " $arr[$k+1] = $val;\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "f7();\n" , "key=0 value=0\n" "key=1 value=1\n" "key=2 value=0\n" "key=3 value=1\n" "key=4 value=0\n" "key=5 value=1\n" "key=6 value=0\n" "key=7 value=1\n" "key=8 value=0\n" "key=9 value=1\n" "key=10 value=0\n" "key=11 value=1\n" "key=12 value=0\n" "key=13 value=1\n" "key=14 value=0\n" "key=15 value=1\n" "key=16 value=0\n" "key=17 value=1\n" "key=18 value=0\n" "key=19 value=1\n" ); MVCRO(" &$v) {\n" " yield null;\n" " echo \"key=$k value=$v\\n\";\n" " if ($k == 0)\n" " $val = 1;\n" " else\n" " $val = $arr[$k-1];\n" " $arr[$k+1] = $val;\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "foreach (f7() as $_) {}\n" , "key=0 value=0\n" "key=1 value=1\n" "key=2 value=0\n" "key=3 value=1\n" "key=4 value=0\n" "key=5 value=1\n" "key=6 value=0\n" "key=7 value=1\n" "key=8 value=0\n" "key=9 value=1\n" "key=10 value=0\n" "key=11 value=1\n" "key=12 value=0\n" "key=13 value=1\n" "key=14 value=0\n" "key=15 value=1\n" "key=16 value=0\n" "key=17 value=1\n" "key=18 value=0\n" "key=19 value=1\n" ); MVCR(" &$v) {\n" " echo \"key=$k value=$v\\n\";\n" " if ($k == 0)\n" " $val = 1;\n" " else\n" " $val = $arr[$k-1];\n" " unset($arr[$k+1]);\n" " $bar[] = 0;\n" " $arr[$k+1] = $val;\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "f8();\n"); MVCRO(" &$v) {\n" " yield null;\n" " echo \"key=$k value=$v\\n\";\n" " if ($k == 0)\n" " $val = 1;\n" " else\n" " $val = $arr[$k-1];\n" " unset($arr[$k+1]);\n" " $bar[] = 0;\n" " $arr[$k+1] = $val;\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "foreach (f8() as $_) {}\n" , "key=0 value=0\n" "key=2 value=0\n" "key=1 value=1\n" "key=3 value=1\n" "key=2 value=0\n" "key=4 value=0\n" "key=3 value=1\n" "key=5 value=1\n" "key=4 value=0\n" "key=6 value=0\n" "key=5 value=1\n" "key=7 value=1\n" "key=6 value=0\n" "key=8 value=0\n" "key=7 value=1\n" "key=9 value=1\n" "key=8 value=0\n" "key=10 value=0\n" "key=9 value=1\n" "key=11 value=1\n" ); MVCR(" &$v) {\n" " echo \"k=$k v=$v\\n\";\n" " if (!$first) {\n" " $prev_k = ($k+2)%3;\n" " unset($arr[$prev_k]);\n" " if (count($bar) > 100)\n" " $bar = array();\n" " $bar[] = 1;\n" " $arr[$prev_k] = 1;\n" " }\n" " $first = false;\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "f9();\n"); MVCRO(" &$v) {\n" " yield null;\n" " echo \"k=$k v=$v\\n\";\n" " if (!$first) {\n" " $prev_k = ($k+2)%3;\n" " unset($arr[$prev_k]);\n" " if (count($bar) > 100)\n" " $bar = array();\n" " $bar[] = 1;\n" " $arr[$prev_k] = 1;\n" " }\n" " $first = false;\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "foreach (f9() as $_) {}\n" , "k=0 v=1\n" "k=1 v=1\n" "k=2 v=1\n" "k=0 v=1\n" "k=1 v=1\n" "k=2 v=1\n" "k=0 v=1\n" "k=1 v=1\n" "k=2 v=1\n" "k=0 v=1\n" "k=1 v=1\n" "k=2 v=1\n" "k=0 v=1\n" "k=1 v=1\n" "k=2 v=1\n" "k=0 v=1\n" "k=1 v=1\n" "k=2 v=1\n" "k=0 v=1\n" "k=1 v=1\n" ); MVCR("1,2,'b'=>3,4);\n" " $b = true;\n" " foreach ($arr as $k => &$v) {\n" " echo \"key=$k val=$v\\n\";\n" " if ($b && $v == 1) {\n" " $b = false;\n" " array_pop($arr);\n" " }\n" " }\n" "}\n" "g6();\n"); MVCRO("1,2,'b'=>3,4);\n" " $b = true;\n" " foreach ($arr as $k => &$v) {\n" " yield null;\n" " echo \"key=$k val=$v\\n\";\n" " if ($b && $v == 1) {\n" " $b = false;\n" " array_pop($arr);\n" " }\n" " }\n" "}\n" "foreach (g6() as $_) {}\n" , "key=0 val=0\n" "key=a val=1\n" "key=1 val=2\n" "key=b val=3\n" ); MVCR("1,2,'b'=>3,4);\n" " $b = true;\n" " foreach ($arr as $k => &$v) {\n" " echo \"key=$k val=$v\\n\";\n" " if ($b && $v == 1) {\n" " $b = false;\n" " unset($arr[1]); \n" " }\n" " }\n" "}\n" "g7();\n"); MVCRO("1,2,'b'=>3,4);\n" " $b = true;\n" " foreach ($arr as $k => &$v) {\n" " yield null;\n" " echo \"key=$k val=$v\\n\";\n" " if ($b && $v == 1) {\n" " $b = false;\n" " unset($arr[1]); \n" " }\n" " }\n" "}\n" "foreach (g7() as $_) {}\n" , "key=0 val=0\n" "key=a val=1\n" "key=b val=3\n" "key=2 val=4\n" ); /** * Zend PHP 5.2 outputs: * key=0 val=0 * key=a val=1 * key=0 val=0 * key=a val=1 * key=b val=3 * * The difference in behavior is intentional. Under PHP, after the next * element is unset inside the foreach by reference loop and the array_pop * operation is performed, a heuristic is used to determine which element * should be visited next. If this specific example, the loop chooses to * resume at key '0'. * * Under HPHP, when the next element is unset inside a foreach by loop, the * loop's iterator is appropriately updated. Likewise, the loop's iterator * remains intact after the array_pop operation. Thus, after the unset and * the pop operation, HPHP resumes the loop at key 'b'. */ MVCRO("1,2,'b'=>3,4);\n" " $b = true;\n" " foreach ($arr as $k => &$v) {\n" " echo \"key=$k val=$v\\n\";\n" " if ($b && $v == 1) {\n" " $b = false;\n" " unset($arr[1]); \n" " array_pop($arr);\n" " }\n" " }\n" "}\n" "g8();\n" , "key=0 val=0\n" "key=a val=1\n" "key=b val=3\n" ); MVCRO("1,2,'b'=>3,4);\n" " $b = true;\n" " foreach ($arr as $k => &$v) {\n" " yield null;\n" " echo \"key=$k val=$v\\n\";\n" " if ($b && $v == 1) {\n" " $b = false;\n" " unset($arr[1]); \n" " array_pop($arr);\n" " }\n" " }\n" "}\n" "foreach (g8() as $_) {}\n" , "key=0 val=0\n" "key=a val=1\n" "key=b val=3\n" ); MVCR("\n" " int(0)\n" " [1]=>\n" " int(0)\n" " [2]=>\n" " int(0)\n" " [3]=>\n" " int(0)\n" "}\n" "array(4) {\n" " [0]=>\n" " int(0)\n" " [1]=>\n" " int(0)\n" " [2]=>\n" " int(0)\n" " [3]=>\n" " int(0)\n" "}\n" ); MVCR(" &$v) {\n" " echo \"i=$i key=$k\\n\";\n" " if ($k == 0) {\n" " if ($i > 0) {\n" " h1($arr, $i-1);\n" " } else if ($i == 0) {\n" " echo \"Unsetting key 1\\n\";\n" " unset($arr[1]);\n" " }\n" " }\n" " }\n" " end($arr);\n" "}\n" "$arr = array('a','b','c');\n" "h1($arr, 10);\n" "var_dump($arr);\n"); MVCRO(" &$v) {\n" " yield null;\n" " echo \"i=$i key=$k\\n\";\n" " if ($k == 0) {\n" " if ($i > 0) {\n" " foreach (h1($arr, $i-1) as $_) {}\n" " } else if ($i == 0) {\n" " echo \"Unsetting key 1\\n\";\n" " unset($arr[1]);\n" " }\n" " }\n" " }\n" " end($arr);\n" "}\n" "$arr = array('a','b','c');\n" "foreach (h1($arr, 10) as $_) {}\n" "var_dump($arr);\n" , "i=10 key=0\n" "i=9 key=0\n" "i=8 key=0\n" "i=7 key=0\n" "i=6 key=0\n" "i=5 key=0\n" "i=4 key=0\n" "i=3 key=0\n" "i=2 key=0\n" "i=1 key=0\n" "i=0 key=0\n" "Unsetting key 1\n" "i=0 key=2\n" "i=1 key=2\n" "i=2 key=2\n" "i=3 key=2\n" "i=4 key=2\n" "i=5 key=2\n" "i=6 key=2\n" "i=7 key=2\n" "i=8 key=2\n" "i=9 key=2\n" "i=10 key=2\n" "array(2) {\n" " [0]=>\n" " string(1) \"a\"\n" " [2]=>\n" " string(1) \"c\"\n" "}\n" ); MVCR(" &$v) {\n" " echo $k . \"\\n\";\n" " if ($k == 2 && !isset($arr2)) {\n" " $arr2 = $arr;\n" " }\n" " $v += 100;\n" " }\n" " var_dump($arr);\n" " var_dump($arr2);\n" "}\n" "foo();\n"); MVCRO(" &$v) {\n" " yield null;\n" " echo $k . \"\\n\";\n" " if ($k == 2 && !isset($arr2)) {\n" " $arr2 = $arr;\n" " }\n" " $v += 100;\n" " }\n" " var_dump($arr);\n" " var_dump($arr2);\n" "}\n" "foreach (foo() as $_) {}\n" , "0\n" "1\n" "2\n" "3\n" "4\n" "array(5) {\n" " [0]=>\n" " int(110)\n" " [1]=>\n" " int(120)\n" " [2]=>\n" " &int(130)\n" " [3]=>\n" " int(140)\n" " [4]=>\n" " &int(150)\n" "}\n" "array(5) {\n" " [0]=>\n" " int(110)\n" " [1]=>\n" " int(120)\n" " [2]=>\n" " &int(130)\n" " [3]=>\n" " int(40)\n" " [4]=>\n" " int(50)\n" "}\n" ); MVCR(" &$v) {\n" " echo $k . \"\\n\";\n" " if ($k == 2 && !isset($arr2)) {\n" " $arr2 = $arr;\n" " $arr[] = 60;\n" " }\n" " $v += 100;\n" " }\n" " var_dump($arr);\n" " var_dump($arr2);\n" "}\n" "foo();\n"); MVCRO(" &$v) {\n" " yield null;\n" " echo $k . \"\\n\";\n" " if ($k == 2 && !isset($arr2)) {\n" " $arr2 = $arr;\n" " $arr[] = 60;\n" " }\n" " $v += 100;\n" " }\n" " var_dump($arr);\n" " var_dump($arr2);\n" "}\n" "foreach (foo() as $_) {}\n" , "0\n" "1\n" "2\n" "3\n" "4\n" "5\n" "array(6) {\n" " [0]=>\n" " int(110)\n" " [1]=>\n" " int(120)\n" " [2]=>\n" " &int(130)\n" " [3]=>\n" " int(140)\n" " [4]=>\n" " int(150)\n" " [5]=>\n" " &int(160)\n" "}\n" "array(5) {\n" " [0]=>\n" " int(110)\n" " [1]=>\n" " int(120)\n" " [2]=>\n" " &int(130)\n" " [3]=>\n" " int(40)\n" " [4]=>\n" " int(50)\n" "}\n" ); /** * Zend PHP 5.2 outputs: * val=0 * val=1 * val=2 * val=3 * val=4 * bool(false) * * The difference in behavior is intentional. Under PHP, foreach by value can * in some cases modify the array's internal iterator without triggering an * array copy. This can potentially expose information to user code about * when array copies are triggered. * * Under HPHP, foreach by value will never modify the array's internal * iterator. The advantage here is that we do not expose information about * when array copies are triggered to user code. * * The PHP manual states the following: * foreach has some side effects on the array pointer. Don't rely on the * array pointer during or after the foreach without resetting it. */ MVCRO(" &$a[foo($i++, $i++, $i++)]) {" " var_dump($a[1],$a[2]);" "}" "foreach ($a as " " $a[bar($i++, $i++, $i++)] => $a[foo($i++, $i++, $i++)]) {" " var_dump($a[1],$a[2]);" "}"); MVCR(" 1) as $k => $v) {\n" " break;\n" " }\n" " echo \"Leaving main\\n\";\n" "}\n" "main();\n"); return true; } bool TestCodeRun::TestArrayAssignment() { MVCR(" '1', 2 => 2, 'c' => '3');" "var_dump($a);" "$a = array('a' => '1', 2 => 2, 'c' => '3'," " 'd' => array('a' => '1', 2 => 2, 'c' => '3'));" "var_dump($a);"); MVCR("'main', 2=>'sub');" "$b = $a;" "var_dump(array_pop($b));" "print_r($a);" "var_dump(array_shift($b));" "print_r($a);"); MVCR("$p, '2'=>&$q);" " $b = array('3'=>$r, '4'=>&$s);" " var_dump($a);" " $a += $b;" " var_dump($a);" " var_dump($b);" "}" "foo();"); MVCR("$f($a[$obj] = 1, $value);\n" " var_dump($a[$obj] = 1);\n" "}\n" "function setNullVariant($value) {\n" " setNullVariantHelper('f', $value);\n" "}\n" "setNullVariant('Surprise!');\n" "$b = null;\n" "var_dump($b[1]);\n"); // empty string to array conversion MVCR(" 'a'),\n" " array('b' => 'bb'),\n" " array('c' => 'cc'),\n" ");\n" "\n" "$refs = array();\n" "foreach ($a as &$arr) {\n" " $refs[] = &$arr;\n" "}\n" "array_splice($a, 1, 1);\n" "var_dump($a);\n" ); MVCR(" 'y');\n" "$a = array('a1' => $x, 'a2' => $x);\n" "$b = array('a1' => array(1,2,3), 'a2' => array(1,2,3));\n" "var_dump(array_merge_recursive($a, $b));"); MVCR(" 'y');\n" "$a = array('a1' => &$x, 'a2' => &$x);\n" "$b = array('a1' => array(), 'a2' => array(1,2));\n" "var_dump(array_merge_recursive($a, $b));"); MVCR(" 'y');\n" "$a = array('a1' => &$x, 'a2' => &$x);\n" "$b = array('a1' => array(1,2), 'a2' => array(3,4));\n" "var_dump(array_merge_recursive($a, $b));"); MVCR(" 1, 3 => 3); " "var_dump(array_merge($a, array(2)));"); MVCR(" 1, 3 => 3); " "var_dump(array_merge($a, array()));"); MVCR(" 1, 3 => 3); " "var_dump(array_merge($a, array(2)));"); MVCR(" 1, 'b' => 3); " "var_dump(array_merge($a, array(2)));"); MVCR(" 1, 3 => 3); " "var_dump(array_merge($a, array('a' => 2)));"); MVCR(" 1, 3 => 3); " "var_dump(array_merge($a, array('b' => 2)));"); MVCR(" 1, 'b' => 3); " "var_dump(array_merge($a, array('c' => 2)));"); MVCR(" \"green\"," " \"red\", \"b\" => \"green\", \"blue\", \"red\");" "$result = array_unique($input);" "print_r($result);"); MVCR("$f = 100;\n" "$a = (array)$o;\n" "$v = 1;\n" "$a[10] = &$v;\n" "$a[11] = array(&$v);\n" "var_dump($a);\n" // array_diff "$b = array(10 => 10);\n" "var_dump(array_diff_key($a, $b));\n" // array_merge and array_merge_recursive "var_dump(array_merge($a, $b));\n" "var_dump(array_merge_recursive($a, $b));\n" // array_reverse "var_dump(array_reverse($a));\n" // array_chunk "var_dump(array_chunk($a, 2));\n" ); // Test array_reduce MVCR(" 22)));"); return true; } bool TestCodeRun::TestArrayCSE() { HipHopSyntax w0(this); OptionSetter w1(this, OptionSetter::CompileTime, "-vArrayAccessIdempotent=1"); MVCR(" array('baz' => 40)), 'e');\n" "var_dump(f(array('y' => array()), 'y'));\n" "var_dump(f(array(), 'y'));\n" "var_dump(f(array(), array()));\n" "h(array(), 0);\n" "h(array(array()), 0);\n"); MVCRO("\n" " array(1) {\n" " [0]=>\n" " int(30)\n" " }\n" "}\n" "array(1) {\n" " [0]=>\n" " int(30)\n" "}\n" "string(1) \"b\"\n" "string(1) \"a\"\n" "string(1) \"b\"\n" "string(0) \"\"\n" "string(0) \"\"\n" "string(0) \"\"\n" "string(1) \"b\"\n" "string(0) \"\"\n" "string(1) \"b\"\n"); MVCR("x = $x;\n" " }\n" " public function offsetSet($offset, $value) {\n" " $this->x[$offset] = $value;\n" " }\n" " public function offsetExists($offset) {\n" " return isset($this->x[$offset]);\n" " }\n" " public function offsetUnset($offset) {\n" " unset($this->x[$offset]);\n" " }\n" " public function offsetGet($offset) {\n" " return $this->x[$offset];\n" " }\n" "}\n" "$o = new ArrayWrap(array(0, 1, 2));\n" "\n" "function f1($x) {\n" " return isset($x[0]) && $x[0];\n" "}\n" "var_dump(f1(null));\n" "var_dump(f1(array()));\n" "var_dump(f1(array(0)));\n" "var_dump(f1(''));\n" "var_dump(f1('a'));\n" "var_dump(f1($o));\n" "\n" "function f2($x) {\n" " if (!is_null($x[0])) var_dump($x[0]);\n" " var_dump($x[0]);\n" "}\n" "f2(array(0 => array()));\n" "f2(array());\n" "f2('');\n" "f2($o);\n" "f2(null);\n" "\n" "function f3($x) {\n" " foreach ($x['foo'] as $k => $v) {\n" " if ($v) unset($x['foo'][$k]);\n" " }\n" " var_dump($x);\n" "}\n" "f3(array('foo' => array(0,1,2,3)));\n" "\n" "function f4($x) {\n" " var_dump($x[0][1]);\n" " unset($x[0][1]);\n" " var_dump($x[0][1]);\n" "}\n" "f4(array(array(1 => new stdClass())));\n" "\n" "function f5($x) {\n" " var_dump(md5($x[0]), $x[0]);\n" "}\n" "f5('foobar');\n"); MVCR("function f1($x) {\n" " if (count($x) > 0) { \n" " var_dump($x); \n" " } else if (count($x[0]) > 0) {\n" " var_dump($x[0]);\n" " }\n" "}\n" "f1(array(array(0, 1, 2)));\n" "f1('abc');\n" "\n" "function id($x) { return $x; }\n" "function f2($x) {\n" " if ($x[0]) var_dump(id($x), $x[0]);\n" "}\n" "f2(null);\n" "f2(array());\n" "f2(array(10));\n" "\n" "function f3($x) {\n" " var_dump($x[0].'/'. $x[1]);\n" " var_dump($x[0].'/'. $x[1]);\n" "}\n" "f3(array('first', 'second'));\n" "f3('AB');\n" "\n" "function f4($x) {\n" " $z = @id($x[0]);\n" " var_dump($z);\n" " var_dump($x[0]);\n" "}\n" "f4(array('e1', 'e2'));\n" "\n" "function f5($x) {\n" " if ($x[0][id($x[0])-1]) var_dump($x);\n" "}\n" "f5(array(0, 1, 2));\n"); MVCR("function id($x) { return $x; }\n" "function f1($x) {\n" " $z = id($x[0]);\n" " foreach ($x[0] as $a) {\n" " $z[] = array(id($z), count($x[0]));\n" " }\n" "}\n" "f1(array(array(0, 1, 2, 3)));\n" "\n" "function f2($x) {\n" " var_dump($x[0]);\n" " $y = 'foo' . $x[0] . 'bar';\n" "}\n" "f2('foobar');\n" "\n" "function f3($x) {\n" " $x = is_string($x[0]) ? $x[0] : get_class($x[0]);\n" " return $x;\n" "}\n" "var_dump(f3('abc'));\n" "var_dump(f3(array(new stdClass)));\n"); MVCR(" array($GLOBALS['foo']),\n" " 20 => array($GLOBALS['foo']));\n" "var_dump($GLOBALS['bar']);\n"); MVCR(" $v) {\n" " var_dump($x[0]);\n" " var_dump($k, $v);\n" " }\n" "}\n" "function f5($x) {\n" " switch ($x[0]) {\n" " case 0:\n" " var_dump($x[0]);\n" " }\n" "}\n" "function f6($x, $y, $z) {\n" " if ($z) goto my_clause;\n" " if ($y) { var_dump($y); }\n" " else if ($x[0]) {\n" " var_dump($x[0]);\n" " my_clause:\n" " var_dump($x);\n" " }\n" "}\n" "f1(array(0, 0));\n" "f2(array(10));\n" "f3(array(10), false);\n" "f4(array(array(1, 2, 3)));\n" "f5(array(false, false));\n" "f6(array(true), false, false);\n"); MVCR("> 2);"); MVCR("> $b);"); MVCR("> $b);"); MVCR(">= 2; var_dump($a);"); MVCR("var1 = 1; }" "f();"); //#147156 return true; } bool TestCodeRun::TestObject() { HipHopSyntax w(this); MVCR("a++; " "$obj3 = new B(); $obj3->a = 10;" "var_dump($obj1->a);" "var_dump($obj1);" "var_dump($obj2->a);" "var_dump($obj2);" "var_dump($obj3);" "var_dump($obj1 instanceof A);" "var_dump($obj3 instanceof A);" "var_dump($obj1 instanceof B);" "var_dump($obj3 instanceof B);" ); MVCR("a = $a + 1;" " }" " public function __destruct() {" " $this->a += 2;" " var_dump($this->a);" " }" "}" "class B extends A {" " public function __construct($a) {" " }" "}" "class C extends A {" " public function __construct($a) {" " parent::__construct($a);" " }" "}" "$obj = new A(1); var_dump($obj->a);" "$obj = new B(1); var_dump($obj->a);" "$obj = new C(1); var_dump($obj->a);" "unset($obj);" ); MVCR("c);" ); MVCR("b);*/" // undeclared "$obj = new B(); var_dump($obj); var_dump($obj->b);" ); MVCR("a);" "$obj = new B(); var_dump($obj); var_dump($obj->b);" ); MVCR("b);" "$obj = new B(); var_dump($obj); var_dump($obj->b);" ); MVCR("b);" "$obj = new B(); var_dump($obj); var_dump($obj->b);" ); MVCR("test('cool');" ); MVCR("test(1);" "$obj = new B(); $obj->test(1);" ); // circular references MVCR("a = $obj2; $obj2->a = $obj1;" "var_dump($obj1);"); MVCR("t();"); MVCR("v = $v;" " return $this;" " }" "}" "function foo() {" " $z = 1;" " $qd = array('x' => $z);" " $a = G()->set($qd);" " var_dump($a);" " $qd['e'] = true;" " $b = G()->set($qd);" " var_dump($a);" "" "}" "function G() {" " return new g;" "}" "foo();"); MVCR("c = 3;" "var_dump($obj);" "foreach ($obj as &$value) {" " $value = 2;" "}" "var_dump($obj);"); MVCRO("c = 3;" " var_dump($obj);" " foreach ($obj as &$value) {" " yield null;" " $value = 2;" " }" " var_dump($obj);" "}" "foreach (gen() as $_) {}" , "object(A)#2 (2) {\n" " [\"a\"]=>\n" " NULL\n" " [\"b\"]=>\n" " NULL\n" "}\n" "object(A)#2 (2) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " &int(1)\n" "}\n" "object(A)#2 (3) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " &int(1)\n" " [\"c\"]=>\n" " int(3)\n" "}\n" "object(A)#2 (3) {\n" " [\"a\"]=>\n" " int(2)\n" " [\"b\"]=>\n" " int(2)\n" " [\"c\"]=>\n" " &int(2)\n" "}\n" ); MVCR(" &$value) {" " $value = 'ok';" "}" "var_dump($obj);" "var_dump($obj2);"); MVCRO(" &$value) {" " yield null;" " $value = 'ok';" " }" " var_dump($obj);" " var_dump($obj2);" "}" "foreach (gen() as $_) {}" , "object(A)#2 (2) {\n" " [\"a\"]=>\n" " string(2) \"ok\"\n" " [\"b\"]=>\n" " &string(2) \"ok\"\n" "}\n" "object(A)#2 (2) {\n" " [\"a\"]=>\n" " string(2) \"ok\"\n" " [\"b\"]=>\n" " &string(2) \"ok\"\n" "}\n" ); MVCR("a = $p1;" " $this->b = $p2;" " $this->c = $p3;" " $this->d = $p4;" " }" "};" "$obj = new A(1, 2, 3, 4);" "foreach ($obj as $key => &$val) {" " if($val == 2) {" " $obj->$key = 0;" " } else if($val == 3) {" " var_dump($key);" " unset($obj->$key);" " } else {" " $val++;" " }" "}" "var_dump($obj);"); MVCRO("a = $p1;" " $this->b = $p2;" " $this->c = $p3;" " $this->d = $p4;" " }" "};" "function gen() {" " $obj = new A(1, 2, 3, 4);" " foreach ($obj as $key => &$val) {" " yield null;" " if($val == 2) {" " $obj->$key = 0;" " } else if($val == 3) {" " var_dump($key);" " unset($obj->$key);" " } else {" " $val++;" " }" " }" " var_dump($obj);" "}" "foreach (gen() as $_) {}" , "string(1) \"c\"\n" "object(A)#2 (3) {\n" " [\"a\"]=>\n" " int(2)\n" " [\"b\"]=>\n" " int(0)\n" " [\"d\"]=>\n" " &int(5)\n" "}\n" ); MVCR("a = 1;" " $this->b = 2;" " $this->c = 3;" " $this->d = 4;" " }" "};" "function f() {" " $obj = new A();" " foreach ($obj as $key => &$val) {" " $val = 5;" " }" " var_dump($obj);" "}" "f();"); MVCRO("a = 1;" " $this->b = 2;" " $this->c = 3;" " $this->d = 4;" " }" "};" "function f() {" " $obj = new A();" " foreach ($obj as $key => &$val) {" " yield null;" " $val = 5;" " }" " var_dump($obj);" "}" "foreach (f() as $_) {}" , "object(A)#2 (4) {\n" " [\"a\"]=>\n" " int(5)\n" " [\"b\"]=>\n" " int(5)\n" " [\"c\"]=>\n" " int(5)\n" " [\"d\"]=>\n" " &int(5)\n" "}\n" ); MVCR("x);" " $x = new X;" " var_dump($x->x);" "}" "test();"); MVCR("p = \"changed\";\n" " $x = $this;\n" " }\n" "}\n" "$c = new C();\n" "var_dump($c);\n" "$c = null;\n" "$y = 140;\n" "var_dump($x);\n" "$x = null;\n"); MVCR("foo();" " }" "}" "test(45, 0);" "test(77, 1);"); MVCR("{__fUNCTION__} = 1;\n" " $obj->{__cLASS__} = 2;\n" " $obj->__FuNCTION__ = 3;\n" " $obj->__ClASS__ = 4;\n" " $obj->{__FUnCTION__}();\n" " $obj->{__CLaSS__}();\n" " $obj->__FUNcTION__();\n" " $obj->__CLAsS__();\n" " $arr = array();\n" " foreach ($obj as $k => $v) {\n" " $arr[$k] = $v;\n" " }\n" " ksort($arr);\n" " var_dump($arr);\n" " }\n" "}\n" "tEst::eXclaiM();\n"); return true; } bool TestCodeRun::TestObjectProperty() { MVCR("a);\n" "var_dump($old);\n" "\n" "$new = new A;\n" "unset($new->b);\n" "var_dump($new);\n" "\n" "foreach ($new as $property => $value) {\n" " $old->$property = $value;\n" "}\n" "var_dump($old->a);\n" "var_dump($old->b);\n" // We can't really maintain the same order as PHP does, even though we // can move unset and reset properties to the back of the list, but // then we can't really tell who's added back first if there are two :-( //"var_dump($old);\n" ); MVCR("a), property_exists($obj, 'a'));\n" "$obj->a = null;\n" "var_dump(isset($obj->a), property_exists($obj, 'a'));\n" "unset($obj->a);\n" "var_dump(isset($obj->a), property_exists($obj, 'a'));\n" "$obj->a = 123;\n" "var_dump(isset($obj->a), property_exists($obj, 'a'));\n" "$obj->a = null;\n" "var_dump(isset($obj->a), property_exists($obj, 'a'));\n" ); MVCR("$name;\n" " }}\n" "\n" "$obj = new A();\n" "var_dump($obj->prop);\n" ); MVCR("a = 20;} } " "class B extends A { public $a = 'test';} " "$obj = new B(); $obj->foo(); var_dump($obj->a);"); MVCR("a);} } " "class C extends B { public $a = 'test';} " "$obj = new C(); $obj->foo();"); MVCR(" $v) {" " var_dump($v);" " }" " }" "}" "class d extends c {" " public $a = 'a';" " private $b = 'b';" " protected $c = 'c';" " function t2($y) {" " foreach ($this as $k => $v) {" " var_dump($v);" " }" " foreach ($y as $k => $v) {" " var_dump($v);" " }" " foreach ($y as $k => $v) {" " var_dump($v);" " }" " }" "}" "$x = new d;" "$x->surprise = 1;" "$y = new d;" "$y->shock = 2;" "echo \"t2\n\";" "$x->t2($y);" "echo \"t1\n\";" "$x->t1($y);" "$z = new c;" "echo \"t12\n\";" "$z->t1($x);" "foreach ($x as $k => $v) {" " var_dump($v);" "}"); MVCR(" 1, 'version'=>2);" "var_dump(isset($one->cluster));" "var_dump(empty($one->cluster));" "$two = 'hello';" "var_dump(isset($two->scalar));"); MVCR("pri);" " $pri = $q ? 'zz' : 'p'.'ri';" " var_dump($this->$pri);" " }" " function bar2() {" " var_dump($this->pro);" " }" "}" "class B extends A {" " private $pri = 'b-pri';" " function bar() {" " parent::bar();" " var_dump($this->pri);" " }" "}" "$obj = new B(); $obj->bar();" "class C extends B {" " public $pri = 'c-pri';" " public $pro = 'c-pro';" " function bar2() {" " parent::bar2();" " var_dump($this->pro);" " }" "}" "$obj = new C; $obj->bar(); $obj->bar2();" "var_dump(serialize($obj));" "class Base {" " protected $pro = 1;" " private $pri = 'base-pri';" " function q0() {" " var_dump($this->pri);" " }" "}" "" "class R extends Base {" " public $rpub = 1;" " protected $pro = 2;" " private $pri = 'r-pri';" " function q() {" " var_dump($this->pri);" " }" "}" "" "class D extends R {" " public $dpub = 'd';" " protected $pro = 'pro';" " private $pri = 'd-pri';" " function qq() {" " var_dump($this->pri);" " }" "}" "" "class DD extends D {" " private $pri = 'dd-pri';" " function qqq() {" " var_dump($this->pri);" " }" "}" "" "if (false) {" " class R{}" "}" "$d = new D;" "$d->qq();" "$d->q();" "$d->q0();" "$d = new DD;" "$d->qqq();" "$d->qq();" "$d->q();" "$d->q0();" ); MVCR("$f = 100;\n" "var_dump($a);\n" "unset($a->$f);\n" "var_dump($a);\n"); MVCR("y(f(),$x->x);" " var_dump($x);" " $x->y(0,$x->x);" " var_dump($x);" "}" "test();"); MVCR("b);" " var_dump($b);" " foreach ($b as $prop => $value) {" " var_dump($prop);" " }" " }" "}" "A::foo();"); MVCR("foo));" "var_dump(isset($x->baz));" "var_dump(isset($x->buz));" "var_dump(isset($x->pub_var));" "var_dump(isset($x->pub_set));" "var_dump(isset($x->priv_var));" "var_dump(empty($x->foo));" "var_dump(empty($x->baz));" "var_dump(empty($x->buz));" "var_dump(empty($x->pub_var));" "var_dump(empty($x->pub_set));" "var_dump(empty($x->priv_var));" "unset($x->pub_var);" "var_dump(isset($x->pub_var));" "var_dump(empty($x->pub_var));"); MVCR(" &$v) { var_dump($k); $v = 100; }\n" " var_dump($this);\n" " }\n" "}\n" "$b = new B();\n" "$b->f();\n" "function f() {\n" " $o = new B();\n" " foreach ($o as $k => &$v) { var_dump($k); $v = 100; }\n" " var_dump($o);\n" "}\n" "f();\n"); // empty property name shouldn't crash MVCR(" 30);" " public static function foo($type, $key) {" " return isset( self::${$type}[$key] );" " }" "}" "var_dump(Test::foo('color', 'gray'));"); MVCR("v = array(1, 2);" " return $x;" "}" "foo()->v[0] += 5;" "var_dump(shuffle(foo()->v));"); MVCR("data = $result;" " }" "}" "function foo($obj) {" " $obj->data = new A;" " $a = $obj->data;" " var_dump($a);" " $obj->setData(null);" " $a = $obj->data;" " var_dump($a);" "}" "foo(new B);"); MVCR("b = true;" " $this->i = 5;" " $this->a = array(1,2,3);" " $this->s = 'goodbye';" " }" " function foo() {" " var_dump($this->b, $this->i, $this->a, $this->s);" " }" "}" "function test() {" " $x = new X;" " $x->set();" " $s = serialize($x);" " $y = unserialize($s);" " $y->foo();" " var_dump($y);" "}" "test();"); MVCR("$v)); }" "test(false, \"\");" "test(false, \"\\0foo\");" "test(true, \"\");" "test(true, \"\\0foo\");" "test(new stdclass, \"\");" "test(new stdclass, \"\\0foo\");"); MVCRNW("$v); }" "test(false, \"\");" "test(false, \"\\0foo\");" "test(true, \"\");" "test(true, \"\\0foo\");" "test(new stdclass, \"\");"); MVCRNW("$v); }" "test(new stdclass, \"\\0foo\");"); MVCRNW("$v = 1); }" "test(true, \"\");" "test(true, \"\\0foo\");" "test(false, \"\");"); MVCRNW("$v = 1); }" "test(false, \"\\0foo\");"); MVCRNW("$v = 1); }" "test(new stdclass, \"\");"); MVCRNW("$v = 1); }" "test(new stdclass, \"\\0foo\");"); MVCRNW("$v++); }" "test(true, \"\");" "test(true, \"\\0foo\");" "test(false, \"\");"); MVCRNW("$v++); }" "test(false, \"\\0foo\");"); MVCRNW("$v++); }" "test(new stdclass, \"\");"); MVCRNW("$v++); }" "test(new stdclass, \"\\0foo\");"); MVCRNW("$v += 1); }" "test(true, \"\");" "test(true, \"\\0foo\");" "test(false, \"\");"); MVCRNW("$v += 1); }" "test(false, \"\\0foo\");"); MVCRNW("$v += 1); }" "test(new stdclass, \"\");"); MVCRNW("$v += 1); }" "test(new stdclass, \"\\0foo\");"); MVCRNW("$v); var_dump($x); }" "test(false, \"\");" "test(false, \"\\0foo\");" "test(true, \"\");" "test(true, \"\\0foo\");" "test(new stdclass, \"\");"); MVCRNW("$v); var_dump($x); }" "test(new stdclass, \"\\0foo\");"); MVCRNW("$y);"); MVCRNW("$y =& $z);"); MVCR("foo()->bar);" " var_dump($x->foo()->bar);" " var_dump($x->foo()->bar);" " var_dump(foo()->bar);" " foo()->bar = 6;" " var_dump(foo()->bar);" " foo()->bar = 7;" " var_dump(foo()->bar);" " foo()->bar = 8;" " var_dump(foo()->bar);" " bar()->bar = 6;" " var_dump(bar()->bar);" " bar()->bar = 7;" " var_dump(bar()->bar);" " bar()->bar = 8;" " var_dump(bar()->bar);" "}" "test();"); // Testing object property that can be inferred but is null at // runtime MVCR("foo = new f;\n" " }\n" " }\n" " function get() {\n" " return $this->foo->bar;\n" " }\n" "}\n" "function main() {\n" " set_error_handler('error_handler');\n" " $c = new c(false);\n" " $c->get();\n" " echo \"Error\\n\";\n" "}\n" "main();\n"); return true; } bool TestCodeRun::TestObjectMethod() { MVCR("test(); $obj = 1;"); // calling a function that's implemented in a derived class MVCR("test();} }" "class R extends T { function test() { var_dump('test'); }} " "$obj = new R(); $obj->test(); $obj->foo();"); MVCR("test();}} " "class B extends A { function test() { print 'B';}} " "$obj = new A(); $obj = new B(); $obj->foo();"); MVCR("test();}}" "$obj = new AA(); $b = new B(); $b->foo($obj);" ); // calling a virtual function MVCR("test();} }" "class R extends T { function test() { var_dump('test'); }} " "$obj = new R(); $obj->test(); $obj->foo();"); // calling a virtual function MVCR("test();"); MVCR("test2();" "foo::test1();" "foo::test2();" "foo::test3();" "$obj->test3();" "$obj->test4();"); // calling instance method statically MVCR("a);" " }" " function g() {" " $this->a = 100;" " call_user_func(array('self', 'f'));" " }" "}"); MVCR("foo(meh());" " $p = null;" "}" "z();"); MVCR("f();" "function g() {" " $y = new m3;" " var_dump($y->meth());" "}" "g();"); MVCR("x();"); MVCR("privateData = 1;" " var_dump('ok');" " }" " public function f2() {" " $this->f1();" " }" "}" "function foo() {" " $obj = new Test();" " $obj->f2();" " $obj->privateData = 2;" " $obj = new Base();" "}" "foo();"); #define TEST_BODY_FOR_IS_CALLABLE \ "var_dump(is_callable('A::a_spub'));" \ "var_dump(is_callable('A::a_spro'));" \ "var_dump(is_callable('A::a_spri'));" \ "var_dump(is_callable('A::a_pro'));" \ "var_dump(is_callable('A::a_pri'));" \ "var_dump(is_callable('a_spub'));" \ "var_dump(is_callable('a_spro'));" \ "var_dump(is_callable('a_spri'));" \ "var_dump(is_callable('a_pub'));" \ "var_dump(is_callable('a_pro'));" \ "var_dump(is_callable('a_pri'));" \ "var_dump(is_callable('B::b_spub'));" \ "var_dump(is_callable('B::b_spro'));" \ "var_dump(is_callable('B::b_spri'));" \ "var_dump(is_callable('B::b_pro'));" \ "var_dump(is_callable('B::b_pri'));" \ "var_dump(is_callable('b_spub'));" \ "var_dump(is_callable('b_spro'));" \ "var_dump(is_callable('b_spri'));" \ "var_dump(is_callable('b_pub'));" \ "var_dump(is_callable('b_pro'));" \ "var_dump(is_callable('b_pri'));" \ "var_dump(is_callable(array('A', 'a_spub')));" \ "var_dump(is_callable(array('A', 'a_spro')));" \ "var_dump(is_callable(array('A', 'a_spri')));" \ "var_dump(is_callable(array('A', 'a_pub')));" \ "var_dump(is_callable(array('A', 'a_pro')));" \ "var_dump(is_callable(array('A', 'a_pri')));" \ "var_dump(is_callable(array('A', 'A::a_spub')));" \ "var_dump(is_callable(array('A', 'A::a_spro')));" \ "var_dump(is_callable(array('A', 'A::a_spri')));" \ "var_dump(is_callable(array('A', 'A::a_pro')));" \ "var_dump(is_callable(array('A', 'A::a_pri')));" \ "var_dump(is_callable(array('A', 'A::A::a_spub')));" \ "var_dump(is_callable(array('A', 'A::A::a_spro')));" \ "var_dump(is_callable(array('A', 'A::A::a_spri')));" \ "var_dump(is_callable(array('A', 'A::A::a_pro')));" \ "var_dump(is_callable(array('A', 'A::A::a_pri')));" \ "var_dump(is_callable(array('A', 'C::a_spub')));" \ "var_dump(is_callable(array('A', 'C::a_spro')));" \ "var_dump(is_callable(array('A', 'C::a_spri')));" \ "var_dump(is_callable(array('A', 'C::a_pub')));" \ "var_dump(is_callable(array('A', 'C::a_pro')));" \ "var_dump(is_callable(array('A', 'C::a_pri')));" \ "var_dump(is_callable(array('A', 'A::C::a_spub')));" \ "var_dump(is_callable(array('A', 'A::C::a_spro')));" \ "var_dump(is_callable(array('A', 'A::C::a_spri')));" \ "var_dump(is_callable(array('A', 'A::C::a_pub')));" \ "var_dump(is_callable(array('A', 'A::C::a_pro')));" \ "var_dump(is_callable(array('A', 'A::C::a_pri')));" \ "var_dump(is_callable(array('A', 'b_spub')));" \ "var_dump(is_callable(array('A', 'b_spro')));" \ "var_dump(is_callable(array('A', 'b_spri')));" \ "var_dump(is_callable(array('A', 'b_pub')));" \ "var_dump(is_callable(array('A', 'b_pro')));" \ "var_dump(is_callable(array('A', 'b_pri')));" \ "var_dump(is_callable(array('A', 'B::a_spub')));" \ "var_dump(is_callable(array('A', 'B::a_spro')));" \ "var_dump(is_callable(array('A', 'B::a_spri')));" \ "var_dump(is_callable(array('A', 'B::a_pub')));" \ "var_dump(is_callable(array('A', 'B::a_pro')));" \ "var_dump(is_callable(array('A', 'B::a_pri')));" \ "var_dump(is_callable(array('A', 'B::B::a_spub')));" \ "var_dump(is_callable(array('A', 'B::B::a_spro')));" \ "var_dump(is_callable(array('A', 'B::B::a_spri')));" \ "var_dump(is_callable(array('A', 'B::B::a_pub')));" \ "var_dump(is_callable(array('A', 'B::B::a_pro')));" \ "var_dump(is_callable(array('A', 'B::B::a_pri')));" \ "var_dump(is_callable(array('B', 'a_spub')));" \ "var_dump(is_callable(array('B', 'a_spro')));" \ "var_dump(is_callable(array('B', 'a_spri')));" \ "var_dump(is_callable(array('B', 'a_pub')));" \ "var_dump(is_callable(array('B', 'a_pro')));" \ "var_dump(is_callable(array('B', 'a_pri')));" \ "var_dump(is_callable(array('B', 'A::a_spub')));" \ "var_dump(is_callable(array('B', 'A::a_spro')));" \ "var_dump(is_callable(array('B', 'A::a_spri')));" \ "var_dump(is_callable(array('B', 'A::a_pro')));" \ "var_dump(is_callable(array('B', 'A::a_pri')));" \ "var_dump(is_callable(array('B', 'A::A::a_spub')));" \ "var_dump(is_callable(array('B', 'A::A::a_spro')));" \ "var_dump(is_callable(array('B', 'A::A::a_spri')));" \ "var_dump(is_callable(array('B', 'A::A::a_pro')));" \ "var_dump(is_callable(array('B', 'A::A::a_pri')));" \ "var_dump(is_callable(array('B', 'C::a_spub')));" \ "var_dump(is_callable(array('B', 'C::a_spro')));" \ "var_dump(is_callable(array('B', 'C::a_spri')));" \ "var_dump(is_callable(array('B', 'C::a_pub')));" \ "var_dump(is_callable(array('B', 'C::a_pro')));" \ "var_dump(is_callable(array('B', 'C::a_pri')));" \ "var_dump(is_callable(array('B', 'B::C::a_spub')));" \ "var_dump(is_callable(array('B', 'B::C::a_spro')));" \ "var_dump(is_callable(array('B', 'B::C::a_spri')));" \ "var_dump(is_callable(array('B', 'B::C::a_pub')));" \ "var_dump(is_callable(array('B', 'B::C::a_pro')));" \ "var_dump(is_callable(array('B', 'B::C::a_pri')));" \ "var_dump(is_callable(array('B', 'b_spub')));" \ "var_dump(is_callable(array('B', 'b_spro')));" \ "var_dump(is_callable(array('B', 'b_spri')));" \ "var_dump(is_callable(array('B', 'b_pub')));" \ "var_dump(is_callable(array('B', 'b_pro')));" \ "var_dump(is_callable(array('B', 'b_pri')));" \ "var_dump(is_callable(array('B', 'B::a_spub')));" \ "var_dump(is_callable(array('B', 'B::a_spro')));" \ "var_dump(is_callable(array('B', 'B::a_spri')));" \ "var_dump(is_callable(array('B', 'B::a_pub')));" \ "var_dump(is_callable(array('B', 'B::a_pro')));" \ "var_dump(is_callable(array('B', 'B::a_pri')));" \ "var_dump(is_callable(array('B', 'B::A::a_spub')));" \ "var_dump(is_callable(array('B', 'B::A::a_spro')));" \ "var_dump(is_callable(array('B', 'B::A::a_spri')));" \ "var_dump(is_callable(array('B', 'B::A::a_pro')));" \ "var_dump(is_callable(array('B', 'B::A::a_pri')));" \ "var_dump(is_callable(array('B', 'B::B::a_spub')));" \ "var_dump(is_callable(array('B', 'B::B::a_spro')));" \ "var_dump(is_callable(array('B', 'B::B::a_spri')));" \ "var_dump(is_callable(array('B', 'B::B::a_pub')));" \ "var_dump(is_callable(array('B', 'B::B::a_pro')));" \ "var_dump(is_callable(array('B', 'B::B::a_pri')));" \ "var_dump(is_callable(array(new A(), 'a_spub')));" \ "var_dump(is_callable(array(new A(), 'a_spro')));" \ "var_dump(is_callable(array(new A(), 'a_spri')));" \ "var_dump(is_callable(array(new A(), 'a_pub')));" \ "var_dump(is_callable(array(new A(), 'a_pro')));" \ "var_dump(is_callable(array(new A(), 'a_pri')));" \ "var_dump(is_callable(array(new A(), 'A::a_spub')));" \ "var_dump(is_callable(array(new A(), 'A::a_spro')));" \ "var_dump(is_callable(array(new A(), 'A::a_spri')));" \ "var_dump(is_callable(array(new A(), 'A::a_pro')));" \ "var_dump(is_callable(array(new A(), 'A::a_pri')));" \ "var_dump(is_callable(array(new A(), 'A::A::a_spub')));" \ "var_dump(is_callable(array(new A(), 'A::A::a_spro')));" \ "var_dump(is_callable(array(new A(), 'A::A::a_spri')));" \ "var_dump(is_callable(array(new A(), 'A::A::a_pro')));" \ "var_dump(is_callable(array(new A(), 'A::A::a_pri')));" \ "var_dump(is_callable(array(new A(), 'C::a_spub')));" \ "var_dump(is_callable(array(new A(), 'C::a_spro')));" \ "var_dump(is_callable(array(new A(), 'C::a_spri')));" \ "var_dump(is_callable(array(new A(), 'C::a_pub')));" \ "var_dump(is_callable(array(new A(), 'C::a_pro')));" \ "var_dump(is_callable(array(new A(), 'C::a_pri')));" \ "var_dump(is_callable(array(new A(), 'A::C::a_spub')));" \ "var_dump(is_callable(array(new A(), 'A::C::a_spro')));" \ "var_dump(is_callable(array(new A(), 'A::C::a_spri')));" \ "var_dump(is_callable(array(new A(), 'A::C::a_pub')));" \ "var_dump(is_callable(array(new A(), 'A::C::a_pro')));" \ "var_dump(is_callable(array(new A(), 'A::C::a_pri')));" \ "var_dump(is_callable(array(new A(), 'b_spub')));" \ "var_dump(is_callable(array(new A(), 'b_spro')));" \ "var_dump(is_callable(array(new A(), 'b_spri')));" \ "var_dump(is_callable(array(new A(), 'b_pub')));" \ "var_dump(is_callable(array(new A(), 'b_pro')));" \ "var_dump(is_callable(array(new A(), 'b_pri')));" \ "var_dump(is_callable(array(new A(), 'B::a_spub')));" \ "var_dump(is_callable(array(new A(), 'B::a_spro')));" \ "var_dump(is_callable(array(new A(), 'B::a_spri')));" \ "var_dump(is_callable(array(new A(), 'B::a_pub')));" \ "var_dump(is_callable(array(new A(), 'B::a_pro')));" \ "var_dump(is_callable(array(new A(), 'B::a_pri')));" \ "var_dump(is_callable(array(new A(), 'B::A::a_spub')));" \ "var_dump(is_callable(array(new A(), 'B::A::a_spro')));" \ "var_dump(is_callable(array(new A(), 'B::A::a_spri')));" \ "var_dump(is_callable(array(new A(), 'B::A::a_pro')));" \ "var_dump(is_callable(array(new A(), 'B::A::a_pri')));" \ "var_dump(is_callable(array(new B(), 'b_spub')));" \ "var_dump(is_callable(array(new B(), 'b_spro')));" \ "var_dump(is_callable(array(new B(), 'b_spri')));" \ "var_dump(is_callable(array(new B(), 'b_pub')));" \ "var_dump(is_callable(array(new B(), 'b_pro')));" \ "var_dump(is_callable(array(new B(), 'b_pri')));" \ "var_dump(is_callable(array(new B(), 'B::b_spub')));" \ "var_dump(is_callable(array(new B(), 'B::b_spro')));" \ "var_dump(is_callable(array(new B(), 'B::b_spri')));" \ "var_dump(is_callable(array(new B(), 'B::b_pro')));" \ "var_dump(is_callable(array(new B(), 'B::b_pri')));" \ "var_dump(is_callable(array(new B(), 'B::B::b_spub')));" \ "var_dump(is_callable(array(new B(), 'B::B::b_spro')));" \ "var_dump(is_callable(array(new B(), 'B::B::b_spri')));" \ "var_dump(is_callable(array(new B(), 'B::B::b_pro')));" \ "var_dump(is_callable(array(new B(), 'B::B::b_pri')));" \ "var_dump(is_callable(array(new B(), 'C::b_spub')));" \ "var_dump(is_callable(array(new B(), 'C::b_spro')));" \ "var_dump(is_callable(array(new B(), 'C::b_spri')));" \ "var_dump(is_callable(array(new B(), 'C::b_pub')));" \ "var_dump(is_callable(array(new B(), 'C::b_pro')));" \ "var_dump(is_callable(array(new B(), 'C::b_pri')));" \ "var_dump(is_callable(array(new B(), 'B::C::b_spub')));" \ "var_dump(is_callable(array(new B(), 'B::C::b_spro')));" \ "var_dump(is_callable(array(new B(), 'B::C::b_spri')));" \ "var_dump(is_callable(array(new B(), 'B::C::b_pub')));" \ "var_dump(is_callable(array(new B(), 'B::C::b_pro')));" \ "var_dump(is_callable(array(new B(), 'B::C::b_pri')));" \ "var_dump(is_callable(array(new B(), 'a_spub')));" \ "var_dump(is_callable(array(new B(), 'a_spro')));" \ "var_dump(is_callable(array(new B(), 'a_spri')));" \ "var_dump(is_callable(array(new B(), 'a_pub')));" \ "var_dump(is_callable(array(new B(), 'a_pro')));" \ "var_dump(is_callable(array(new B(), 'a_pri')));" \ "var_dump(is_callable(array(new B(), 'A::B::b_spub')));" \ "var_dump(is_callable(array(new B(), 'A::B::b_spro')));" \ "var_dump(is_callable(array(new B(), 'A::B::b_spri')));" \ "var_dump(is_callable(array(new B(), 'A::B::b_pro')));" \ "var_dump(is_callable(array(new B(), 'A::B::b_pri')));" \ MVCRNW("a_sf();" "$obj->b_sf();" "$obj->a_f();" "$obj->b_f();"); MVCR("foo(); }" "}" "function test($y,$z) {" " $y->$z($y);" "}" "test(new Y, 'bar');"); MVCR("id.\")>\"; }\n" " private function f4helper($a) { return $x=$a+12; }\n" "}\n" "class G extends B {\n" " public $pointless;\n" " function __call($name, $arguments) {\n" " // keep f4bogus from fatalling\n" " echo \"Calling G object method '$name' \" . " "implode(', ', $arguments). \"\\n\";\n" " }\n" " function __construct($i) { $this->id=$i; }\n" " function f($a) { $this->trace(\"G::f\"); return $a; }\n" " function f1($a) { return $a; } // override\n" " function flongerthan8($a,$b,$c) { return $a+$b+$c+1; }\n" " function f4($a) { return B::f4($a); } \n" " // check SimpleFunctionCall::outputCPPParamOrderControlled\n" " /// !m_valid, !m_className.empty() case\n" " // called method must not exist anywhere even though it\n" " // looks like it might\n" " function f4missing($a) { \n" " // check SimpleFunctionCall::outputCPPParamOrderControlled\n" " // !m_valid, !m_className.empty() cases\n" "\n" " // m_validClass \n" " echo \"Calling G object 'f4missing' 3 == \"; \n" " //php53 echo parent::f4missing(3),\"\\n\"; // fatals in PHP\n" "\n" " // !m_validClass, m_class\n" " $b=\"B\"; // $b::f4(4); // task 217171\n" " echo \"static parent method B::f4, 16 == \", B::f4(4),\"\\n\"; " " // should work\n" " \n" " // call an non-existant method on the one object via dynamic " "class name\n" " //php53 if($fix249639) echo \"Calling G object method 'f4bogus' " "5 == \", $b::f4bogus(5); __call, \n" " // call existing method on the one object via dynamic class name\n" " //php53 if($fix249639) echo \"Calling G object method 'f4missing' " "5 == \", $b::f4missing(5); \n" " // $b=\"Bbogus\"; $b::f4bogus(6); // report error\n" " // !m_validClass, !m_class // DDD need this test yet \n" " //echo \"missing 3 \", Bbogus::f4bogus(6),\"\\n\"; " "// fatals in PHP\n" "\n" " } \n" " function f5($a) { return H::f4($a); } // static call\n" "}\n" "class H {\n" " function f($a) { global $trace; $trace=\"H::f,\"; return \"\"; }\n" " function f3($a) { return \"\"; }\n" " function f4($a) { return $a+12; }\n" " function f7($a) { return \"\"; }\n" "}\n" "\n" "class J {\n" " function __call($name, $arguments) {\n" " echo \"Calling object method '$name' \" . implode(', ', " "$arguments). \"\\n\";\n" " }\n" " function f6($a) { return \"\"; }\n" "}\n" "\n" "function error_handler ($errnor, $errstr, $errfile, $errline) {\n" " // Should catch these undefined methods here, but task 333319\n" " // is blocking their being caught. For now, suppress the PHP error\n" " // so as to match the missing HPHP one.\n" " //echo \"error handler<<<\\n\";\n" " //var_dump($errnor, $errstr, $errfile, $errline) ;\n" " //echo \">>>\\n\";\n" " return true;\n" "}\n" "// test invoke_builtin_static_method\n" "//echo \"bar == \", \n" " // call_user_func_array(array('Normalizer','normalize')," "array(\"bar\")), \"\\n\";\n" "\n" "$g = new G(5);\n" "// test simple function case\n" "echo \"600 == \",\n" " call_user_func_array('f2',array(call_user_func_array('f4',array(0))))" ", " "\"\\n\";\n" "\n" "// test C::o_invoke, C::o_invoke_few_args, lookup in call_user_func\n" "// static method call (in G::f4).\n" "echo \"1 1 13 34 12 == \",$g->f(1),\" \", $g->f1(1),\" \", \n" " $g->f2(1),\" \",$g->flongerthan8(10,11,12,13,14,15,16),\n" " \" \",$g->f4(0),\"\\n\";\n" "// check case insensitive\n" "echo \"1 1 13 34 12 == \",$g->F(1),\" \", $g->F1(1),\" \", \n" " $g->F2(1),\" \",$g->Flongerthan8(10,11,12,13,14,15,16),\n" " \" \",$g->F4(0),\"\\n\";\n" "\n" "// check SimpleFunctionCall::outputCPPParamOrderControlled\n" "$prev_handler=set_error_handler(\"error_handler\");\n" "$g->f4missing(3);\n" "// $b=\"G\"; $b::f4(4); \n" "\n" "// For those dynamic cases, check:\n" "// 1) A call to an existing method\n" "// 2) A call to a method which exists, but not in this class (exists " "in methodMap)\n" "// 3) A call to a method which does not exist anywhere\n" "\n" "// $func=\"f3\"; echo \"{G::f3}(3) = \",$g->$func(3),\"\\n\";\n" "// $func=\"missing\"; echo \"{G::missing}(3) = \",$g->$func(3),\"\\n\";" "\n" "// tests direct dynamic call \n" "$f='f'; $f1='f1';\n" "echo \"1 1 == \",$g->{$f}(1),\" \", $g->{$f1}(1),\"\\n\"; \n" "echo \"1 1 == \",$g->{'F'}(1),\" \", $g->{$f1}(1),\"\\n\"; \n" "\n" "$res = call_user_func_array(\"H::f\",array(2)); // ok\n" "\n" "// tests methodIndexLookup and this variety of dynamic calls\n" "// trying to exhause f_call_user_func_array cases\n" "$res = call_user_func_array(array($g,'f'),array(20)); // ok\n" "echo \"dynamic call \\$g->'f' $trace, 20 == $res\\n\"; \n" "$res= call_user_func_array(array($g,'G::f'),array(21)); // G::G::f a " "bit wierd\n" "echo \"dynamic call \\$g->'G::f' $trace, 21 == $res\\n\";\n" "//echo \"dynamic call \\$g->'H::f' $trace, FAIL = \",\n" "// call_user_func_array(array($g,'H::f'),array(22)),\"\\n\"; " "// G::H::f better break\n" "\n" "// Test on static class, dynamic method name, static call\n" "$f = 'f1';\n" "echo \"31 == \",G::$f(31),\"\\n\"; // G::f exists\n" "$f = 'f3';\n" "if ($fix249639) echo \"(32) == \",G::$f(32),\"\\n\"; " "// H::f3 exists, but not G::f3\n" "$f = 'missing';\n" "if ($fix249639) echo \"(33) == \",G::$f(33),\"\\n\"; " "// missing does not exist \n" "\n" "// Test dynamic class, dynamic method name, static call\n" "$cls='G';\n" "$f = 'f1';\n" "\n" "//php53 echo \"31 == \",$cls::$f(31),\"\\n\"; // G::f1 exists\n" "$f = 'f3';\n" "//php53 if ($fix249639) echo \"(32) == \"," "$cls::$f(32),\"\\n\"; // H::f3 exists, but not G::f3\n" "$f = 'missing';\n" "//php53 if ($fix249639) echo \"(33) == \"," "$cls::$f(33),\"\\n\"; // missing does not exist \n" "\n" "\n" "// test methodIndexLookupReverse\n" "echo \"dynamic call \\$g->'missing' $trace, Calling G object method " "'missing' 2 = \", call_user_func_array(array($g,'missing')," "array(2)),\"\\n\";\n" "echo \"dynamic call 'missing(2)' $trace, FAIL =\", " "call_user_func_array('missing',array(2)),\"\\n\";\n" "\n" "// more __call testing\n" "$j = new J();\n" "echo \"Calling object method 'missing' 3 = \";\n" "call_user_func_array(array($j,'missing'),array(3)); \n" "\n" "// test mapping for system function names\n" "$ourFileName = \"testFile.txt\";\n" "$ourFileHandle = fopen($ourFileName, 'w') or die(\"can't open file\");\n" "fclose($ourFileHandle);\n" "unlink($ourFileName);\n" "\n" "echo \"done\\n\";"); MVCR("bar();" " }" " private function bar() {" " var_dump('in B::bar...');" " }" "}" "class C extends B {" " private function bar() {" " var_dump('in C::bar!');" " }" "}" "$obj = new C;" "$obj->foo();"); return true; } bool TestCodeRun::TestClassMethod() { MVCR( "bar)) {\n" " echo \"isset\\n\";\n" " }\n" " var_dump($this);\n" " }\n" "} Foo::Bar(); $obj = new Foo(); $obj->Bar();\n" ); MVCR( "whatever();\n" ); MVCR(" $v) {}\n"); MVCR("writeMsg('error', $error);" "class AdsConsoleRenderer {" " public static function getInstance() {" " return new AdsConsoleRenderer();" " }" "" " function writeMsg($classname = '', $s = '') {" " echo $classname . \"::\" . $s;" " }" "}"); MVCR("{'f'}();"); MVCR("foo(1);", "1 \n"); MVCR("test();\n" ); MVCR("foo = 1; $this->bar = 2;} " " public function __sleep() { $this->foo = 3; return array('foo');} " "}" " $a = new A(); var_dump(serialize($a));"); MVCR("a[$name] = $value.'set';} " " function __get($name) { return $this->a[$name].'get';} " "} " "$obj = new A(); $obj->test = 'test'; var_dump($obj->test);"); MVCR("a);" "var_dump($obj->b);" "$obj = new B();" "var_dump($obj->a);" "var_dump($obj->b);"); MVCR("a[$name] = $value;} " " function __get($name) { return $this->a[$name];} " "} " "$obj = new A(); $obj->test = 'test'; var_dump($obj->test);"); MVCR("test = 'test'; var_dump($obj->test);"); MVCR("test($a, 'ss');"); /* MVCR("a[$name] = $value;} " " function __get($name) { return $this->a[$name];} " "} " "$obj = new A(); $obj->test = 'test'; var_dump($obj->test);"); */ MVCR("data[$name] = $value;" " }" " public function __get($name) {" " echo \"Getting '$name'\n\";" " if (array_key_exists($name, $this->data)) {" " return $this->data[$name];" " }" " return null;" " }" " public function __unset($name) {" " echo \"Unsetting '$name'\n\";" " unset($this->data[$name]);" " return 1;" " }" "}" "$obj = new MemberTest;" "$obj->a = 1;" "var_dump($obj->a);" "var_dump(isset($obj->a));" "unset($obj->a);"); MVCR("foo);\n"); MVCR("f2);" " }" "}" "class c extends b{" " private $f = 10;" " private static $sf = 10;" " function __get($n) {" " echo 'got';" " return 1;" " }" " function t() {" " var_dump($this->f2);" " }" "}" "$x = new c;" "var_dump($x->f);" "$x->t();" "$x->t2();"); MVCR("x = 'baz'; $b = $foo->x .= 'bar';" "var_dump($a,$b);"); MVCR("a[$n] = $v; }\n" " function __get($n) { return $this->a[$n]; }\n" " function f() { $this->f = 100; $this->f += 100; }\n" "}\n" "function test() {\n" " $a = new A();\n" " $a->f();\n" " var_dump($a);\n" "}\n" "test();\n"); MVCR("foo;" " var_dump($x->bar++);" " $x->real++;" " var_dump($x);" "}" "test(new X);"); MVCR(" 10;\n" " }\n" "}\n" "$c = new C1;\n" "$d = new D1;\n" "$e = new E1;\n" "$c(0, 1);\n" "$d(0, 1);\n" "$e(0, 1);\n" "call_user_func($c, 0, 1);\n" "call_user_func($d, 0, 1);\n" "call_user_func($e, 0, 1);\n" "call_user_func_array($c, array(0, 1));\n" "call_user_func_array($d, array(0, 1));\n" "call_user_func_array($e, array(0, 1));\n" "$c->__invoke(0, 1);\n" "$d->__invoke(0, 1);\n" "$e->__invoke(0, 1);\n" "C1::__invoke(0, 1);\n" "D1::__invoke(0, 1);\n" "E1::__invoke(0, 1);\n" "function mk($n) { return $n . '::__invoke'; }\n" "call_user_func(mk('C1'), 0, 1);\n" "call_user_func(mk('D1'), 0, 1);\n" "call_user_func(mk('E1'), 0, 1);\n" "var_dump(array_filter(array(0, 1, 11, 13), new F1));\n"); // this differs from regular PHP behavior MVCR("test();\n" "$y = new Y;\n" "$y->test($x);\n"); MVCR("__invoke($y); }\n" "function f2(A $x, $y) { $x($y); $x->__invoke($y); }\n" "function f3(IfaceInvoke $x, $y) { $x($y); $x->__invoke($y); }\n" "$t1 = new Test1;\n" "$t2 = new Test2;\n" "f1($t1, 1);\n" "f1($t2, 2);\n" "f2($t1, 1);\n" "f3($t2, 2);\n"); return true; } bool TestCodeRun::TestObjectAssignment() { MVCR("val = 1;" " }" " function bar() {" " echo $this->val;" " $ref = &$this;" " $ref->val = 2;" " echo $this->val;" " $ref2 = $this;" " $ref2->val = 3;" " echo $this->val;" " $x = new foo();" " echo $x->val;" " $ref3 = &$x;" " $ref3->val = 4;" " echo $x->val;" " $ref4 = $x;" " $ref4->val = 5;" " echo $x->val;" " }" " var $val;" "}" "$x = new foo();" "$x->bar();" "$ref5 = $x;" "$ref5->val = 6;" "echo $x->val;" "$ref6 = &$x;" "$ref6->val = 7;" "echo $x->val;"); return true; } bool TestCodeRun::TestNewObjectExpression() { MVCR("num = 1;" "print($a->num);"); MVCR("id = $id;" " }" "}" "class B1 extends A1 {" "}" "class C1 extends B1 {" " public function __construct($id) {" " parent::__construct($id);" " }" " function zz($id) {" " parent::__construct($id);" " }" "}" "" "$x = new C1(100);" "echo $x->id.\"\\n\";" "$x->zz(1);" "echo $x->id.\"\\n\";"); MVCRO("blah->prop->foo->bar = \"string\";" " var_dump($this->blah);" " }" "}" "$t = new test;" "$t->foo();"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c = new C1();" "$c->a = 1;" "$c->a .= 1;" "print $c->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C2 {" " public $p2;" "}" "$c2 = new C2();" "$c2->p = new C1();" "$c2->p->a = 1;" "$c2->p->a .= 1;" "print $c2->p->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C2 {" " public $p2;" "}" "class C3 {" " public $p3;" "}" "$c3 = new C3();" "$c3->p3 = new C2();" "$c3->p3->p2 = new C1();" "$c3->p3->p2->a = 1;" "$c3->p3->p2->a .= 1;" "print $c3->p3->p2->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C1\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C2 {" " public function __get( $what ) {" " echo \"get C2\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C2\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C3 {" " public function __get( $what) {" " echo \"get C3\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C3\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c3 = new C3();" "$c3->p3 = new C2();" "$c3->p3->p2 = new C1();" "$c3->p3->p2->a = 1;" "$c3->p3->p2->a .= 1;" "print $c3->p3->p2->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C1\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C2 {" " public function __get( $what ) {" " echo \"get C2\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C2\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C3 {" " public function __get( $what) {" " echo \"get C3\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C3\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c3 = new C3();" "$c3->p3 = new C2();" "$c3->p3->p2 = new C1();" "$c3->p3->p2->a = 1;" "$c3->p3->p2->a .= 1;" "print $c3->p3->p2->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C1\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C2 {" " public function __get( $what ) {" " echo \"get C2\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C2\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C3 {" " public function __get( $what) {" " echo \"get C3\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C3\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c3 = new C3();" "$c3->p3 = new C2();" "$c3->p3->p2 = new C1();" "$c3->p3->p2->a = 1;" "$c3->p3->p2->a .= 1;" "print $c3->p3->p2->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c = new C1();" "$c->a += 1;" "print $c->a;" "$c->a += 10;" "print $c->a;" "$c->a -= 2;" "print $c->a;" "$c->a *= 3;" "print $c->a;" "$c->a /= 2;" "print $c->a;" "$c->a %= 8;" "print $c->a;" "$c->a <<= 3;" "print $c->a;" "$c->a >>= 2;" "print $c->a;" "$c->a ^= 18;" "print $c->a;" "$c->a &= 333;" "print $c->a;" "$c->a |= 7;" "print $c->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C2\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C3 {" " public function __get( $what ) {" " echo \"get C3\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C3\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "function assign_ref(&$v) {" " $v = 22;" "}" "$c3 = new C3();" "$c3->p3 = new C2();" "$c3->p3->p2 = new C1();" "$c3->p3->p2->a = 1;" "$c3->p3->p2->a .= 1;" "print $c3->p3->p2->a;" "assign_ref($c3->p3->p2->a);" "print $c3->p3->p2->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C1\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C2 {" " public function __get( $what ) {" " echo \"get C2\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C2\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C3 {" " public function __get( $what ) {" " echo \"get C3\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C3\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "function assign_ref(&$v) {" " $v = 22;" "}" "$c3 = new C3();" "$c3->p3 = new C2();" "$c3->p3->p2 = new C1();" "$c3->p3->p2->a = 1;" "$c3->p3->p2->a .= 1;" "print $c3->p3->p2->a;" "assign_ref($c3->p3->p2->a);" "print $c3->p3->p2->a;"); MVCR("a);" "var_dump($b);"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C1\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c1 = new C1();" "$c1->a = new C1();" "$c1->a->b = new C1();" "$c1->a->b->c = 10;" "var_dump($c1->a->b->c);" "$c1->a->b->c .= 10;" "var_dump($c1->a->b->c);"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C1\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c1 = new C1();" "$c1->a = new C1();" "$c1->a->b = new C1();" "for ($i = 0; $i < 2048; $i++) {" " $c1->a->b->c = 10;" "}" "var_dump($c1->a->b->c);"); MVCR("a = array('x' => new Y);" " }" " function bar() {" " var_dump('bar');" " $this->qq = new Y;" " $this->qq->x = $this->qq->y = 1;" " return $this->qq;" " }" "}" "function foo() { var_dump('foo'); return 'foo'; }" "function test($x, $a, $s) {" " $t = &$s->t;" " unset($x->bar()->x);" " unset($x->q->r->s->${foo()});" " unset($x->y->a->b->c);" " unset($x->a['x']->y->a->b->c);" " unset($a['a']['y'][foo()]);" " unset($a['b']->y->z);" " unset($a->c->d);" " var_dump($x, $a, $s);" "}" "test(new X, array(), false);"); MVCR("a);" "var_dump($this);" "}" "}" "$x = new X;" "$x->foo('this');"); MVCR("q = $q;" " }" "}" "function test() {" " $x = new X;" " $x->foo('hello');" " var_dump($x);" "}" "test();"); if (Option::EnableEval >= Option::FullEval) { MVCRONW("ref($this->priv);" " }" "};" "class Y extends X { private $priv; }" "class Z extends Y {}" "$z = new Z;" "$z->bar();" "var_dump($z);" "$y = new Y;" "$y->bar();" "var_dump($y);" , "object(Z)#1 (2) {\n" " [\"priv\":\"Y\":private]=>\n" " NULL\n" " [\"priv\"]=>\n" " int(1)\n" "}\n"); } return true; } bool TestCodeRun::TestCollectionClasses() { MVCRO(" $v) {\n" " var_dump($v);\n" " var_dump($vec[$k]);\n" " var_dump(isset($v));\n" " var_dump(isset($vec[$k]));\n" " var_dump(empty($v));\n" " var_dump(empty($vec[$k]));\n" " echo \"\\n\";\n" "}\n" "echo \"=====================\\n\\n\";\n" "$mp = Map::fromArray($arr);\n" "foreach ($arr as $k => $v) {\n" " var_dump($mp[$k]);\n" " var_dump(isset($mp[$k]));\n" " var_dump(empty($mp[$k])); \n" " echo \"\\n\";\n" "}\n" "$new_arr = array();\n" "foreach ($mp as $k => $v) {\n" " $new_arr[$k] = $v;\n" "}\n" "ksort($new_arr);\n" "var_dump($new_arr);\n" "echo \"=====================\\n\\n\";\n" "$smp = StableMap::fromArray($arr);\n" "foreach ($smp as $k => $v) {\n" " var_dump($v);\n" " var_dump($smp[$k]);\n" " var_dump(isset($v));\n" " var_dump(isset($smp[$k]));\n" " var_dump(empty($v));\n" " var_dump(empty($smp[$k]));\n" " echo \"\\n\";\n" "}\n" "echo \"Done\\n\";\n" , "NULL\n" "NULL\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "int(0)\n" "int(0)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "int(1)\n" "int(1)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "float(0)\n" "float(0)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "float(1)\n" "float(1)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(0) \"\"\n" "string(0) \"\"\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "string(1) \"0\"\n" "string(1) \"0\"\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "string(1) \"1\"\n" "string(1) \"1\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(3) \"0.0\"\n" "string(3) \"0.0\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(3) \"1.0\"\n" "string(3) \"1.0\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(2) \"0 \"\n" "string(2) \"0 \"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "=====================\n" "\n" "NULL\n" "bool(false)\n" "bool(true)\n" "\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "\n" "int(0)\n" "bool(true)\n" "bool(true)\n" "\n" "int(1)\n" "bool(true)\n" "bool(false)\n" "\n" "float(0)\n" "bool(true)\n" "bool(true)\n" "\n" "float(1)\n" "bool(true)\n" "bool(false)\n" "\n" "string(0) \"\"\n" "bool(true)\n" "bool(true)\n" "\n" "string(1) \"0\"\n" "bool(true)\n" "bool(true)\n" "\n" "string(1) \"1\"\n" "bool(true)\n" "bool(false)\n" "\n" "string(3) \"0.0\"\n" "bool(true)\n" "bool(false)\n" "\n" "string(3) \"1.0\"\n" "bool(true)\n" "bool(false)\n" "\n" "string(2) \"0 \"\n" "bool(true)\n" "bool(false)\n" "\n" "string(3) \"foo\"\n" "bool(true)\n" "bool(false)\n" "\n" "array(14) {\n" " [0]=>\n" " NULL\n" " [1]=>\n" " bool(false)\n" " [2]=>\n" " bool(true)\n" " [3]=>\n" " int(0)\n" " [4]=>\n" " int(1)\n" " [5]=>\n" " float(0)\n" " [6]=>\n" " float(1)\n" " [7]=>\n" " string(0) \"\"\n" " [8]=>\n" " string(1) \"0\"\n" " [9]=>\n" " string(1) \"1\"\n" " [10]=>\n" " string(3) \"0.0\"\n" " [11]=>\n" " string(3) \"1.0\"\n" " [12]=>\n" " string(2) \"0 \"\n" " [13]=>\n" " string(3) \"foo\"\n" "}\n" "=====================\n" "\n" "NULL\n" "NULL\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "int(0)\n" "int(0)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "int(1)\n" "int(1)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "float(0)\n" "float(0)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "float(1)\n" "float(1)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(0) \"\"\n" "string(0) \"\"\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "string(1) \"0\"\n" "string(1) \"0\"\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "string(1) \"1\"\n" "string(1) \"1\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(3) \"0.0\"\n" "string(3) \"0.0\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(3) \"1.0\"\n" "string(3) \"1.0\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(2) \"0 \"\n" "string(2) \"0 \"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "Done\n" ); MVCRO("toArray());\n" "var_dump($v->pop());\n" "var_dump($v->toArray());\n" , "array(1) {\n" " [0]=>\n" " int(123)\n" "}\n" "int(123)\n" "array(0) {\n" "}\n" ); MVCRO("contains(1);\n" " try {\n" " $v->contains('foo');\n" " } catch (Exception $e) {\n" " echo 'A';\n" " }\n" " try {\n" " $v->contains(1.0);\n" " } catch (Exception $e) {\n" " echo 'B';\n" " }\n" " $methods = Vector::fromArray(array('contains','remove'," "'discard'));\n" " foreach ($methods as $method) {\n" " $m = new Map();\n" " $m->$method(1);\n" " $m->$method('foo');\n" " try {\n" " $m->$method(1.0);\n" " } catch (Exception $e) {\n" " echo 'C';\n" " }\n" " $s = new StableMap();\n" " $s->$method(1);\n" " $s->$method('foo');\n" " try {\n" " $s->$method(1.0);\n" " } catch (Exception $e) {\n" " echo 'D';\n" " }\n" " echo \"\\n\";\n" " }\n" "} catch (Exception $e) {\n" " echo \"Test failed\\n\";\n" "}\n" , "ABCD\n" "CD\n" "CD\n" ); MVCRO("foo;\n" " } catch (RuntimeException $e) {\n" " echo $i;\n" " }\n" " ++$i;\n" " try {\n" " $obj->foo = 123;\n" " } catch (RuntimeException $e) {\n" " echo $i;\n" " }\n" " ++$i;\n" " }\n" "} catch (Exception $e) {\n" " echo \"Fail!\\n\";\n" "}\n" "echo \"Done\\n\";\n" , "012345Done\n" ); MVCRO("\n" " int(7)\n" " [1]=>\n" " string(3) \"foo\"\n" "}\n" "Vector Object\n" "(\n" " [0] => 7\n" " [1] => foo\n" ")\n" "[7,\"foo\"]\n" "Vector::__set_state(array(\n" " 0 => 7,\n" " 1 => 'foo',\n" "))\n" "object(Vector)#2 (2) {\n" " [0]=>\n" " int(7)\n" " [1]=>\n" " string(3) \"foo\"\n" "}\n" "Vector Object\n" "(\n" " [0] => 7\n" " [1] => foo\n" ")\n" "[7,\"foo\"]\n" "Vector::__set_state(array(\n" " 0 => 7,\n" " 1 => 'foo',\n" "))\n" ); MVCRO("\n" " string(3) \"foo\"\n" "}\n" "Map Object\n" "(\n" " [3] => foo\n" ")\n" "{\"3\":\"foo\"}\n" "Map::__set_state(array(\n" " 3 => 'foo',\n" "))\n" "object(Map)#2 (1) {\n" " [3]=>\n" " string(3) \"foo\"\n" "}\n" "Map Object\n" "(\n" " [3] => foo\n" ")\n" "{\"3\":\"foo\"}\n" "Map::__set_state(array(\n" " 3 => 'foo',\n" "))\n" "=========================\n" "string(28) \"K:3:\"Map\":1:{s:3:\"bar\";i:7;}\"\n" "=========================\n" "object(Map)#3 (1) {\n" " [\"bar\"]=>\n" " int(7)\n" "}\n" "Map Object\n" "(\n" " [bar] => 7\n" ")\n" "{\"bar\":7}\n" "Map::__set_state(array(\n" " 'bar' => 7,\n" "))\n" "object(Map)#4 (1) {\n" " [\"bar\"]=>\n" " int(7)\n" "}\n" "Map Object\n" "(\n" " [bar] => 7\n" ")\n" "{\"bar\":7}\n" "Map::__set_state(array(\n" " 'bar' => 7,\n" "))\n" ); MVCRO("\n" " string(3) \"foo\"\n" " [\"bar\"]=>\n" " int(7)\n" "}\n" "StableMap Object\n" "(\n" " [3] => foo\n" " [bar] => 7\n" ")\n" "{\"3\":\"foo\",\"bar\":7}\n" "StableMap::__set_state(array(\n" " 3 => 'foo',\n" " 'bar' => 7,\n" "))\n" "object(StableMap)#2 (2) {\n" " [3]=>\n" " string(3) \"foo\"\n" " [\"bar\"]=>\n" " int(7)\n" "}\n" "StableMap Object\n" "(\n" " [3] => foo\n" " [bar] => 7\n" ")\n" "{\"3\":\"foo\",\"bar\":7}\n" "StableMap::__set_state(array(\n" " 3 => 'foo',\n" " 'bar' => 7,\n" "))\n" "=========================\n" "string(48) \"K:9:\"StableMap\":2:{s:3:\"bar\";i:7;i:3;" "s:3:\"foo\";}\"\n" "=========================\n" "object(StableMap)#3 (2) {\n" " [\"bar\"]=>\n" " int(7)\n" " [3]=>\n" " string(3) \"foo\"\n" "}\n" "StableMap Object\n" "(\n" " [bar] => 7\n" " [3] => foo\n" ")\n" "{\"bar\":7,\"3\":\"foo\"}\n" "StableMap::__set_state(array(\n" " 'bar' => 7,\n" " 3 => 'foo',\n" "))\n" "object(StableMap)#4 (2) {\n" " [\"bar\"]=>\n" " int(7)\n" " [3]=>\n" " string(3) \"foo\"\n" "}\n" "StableMap Object\n" "(\n" " [bar] => 7\n" " [3] => foo\n" ")\n" "{\"bar\":7,\"3\":\"foo\"}\n" "StableMap::__set_state(array(\n" " 'bar' => 7,\n" " 3 => 'foo',\n" "))\n" ); MVCRO("at(0));\n" "var_dump($v->get(0));\n" "var_dump($v->get(1));\n" "$m = Map::fromArray(array('foo'));\n" "var_dump($m[0]);\n" "var_dump($m->at(0));\n" "var_dump($m->get(0));\n" "var_dump($m->get(1));\n" "$sm = StableMap::fromArray(array('foo'));\n" "var_dump($sm[0]);\n" "var_dump($sm->at(0));\n" "var_dump($sm->get(0));\n" "var_dump($sm->get(1));\n" , "string(3) \"foo\"\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "NULL\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "NULL\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "NULL\n" ); MVCRO(" 'foo'));\n" "var_dump($m['a']);\n" "var_dump($m->at('a'));\n" "var_dump($m->get('a'));\n" "var_dump($m->get('b'));\n" "$sm = StableMap::fromArray(array('a' => 'foo'));\n" "var_dump($sm['a']);\n" "var_dump($sm->at('a'));\n" "var_dump($sm->get('a'));\n" "var_dump($sm->get('b'));\n" , "string(3) \"foo\"\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "NULL\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "NULL\n" ); MVCRO(" $val) {\n" " echo $key . ' ' . $val . \"\\n\";\n" "}\n" "echo \"=======\\n\";\n" "$s = new StableMap;\n" "$s['w'] = 2;\n" "$s['v'] = 4;\n" "$s['y'] = 3;\n" "$s['x'] = 5;\n" "$s['z'] = 1;\n" "ksort($s);\n" "foreach ($s as $key => $val) {\n" " echo $key . ' ' . $val . \"\\n\";\n" "}\n" "echo \"=======\\n\";\n" "asort($s);\n" "foreach ($s as $key => $val) {\n" " echo $key . ' ' . $val . \"\\n\";\n" "}\n" , "0 a\n" "1 b\n" "2 c\n" "=======\n" "v 4\n" "w 2\n" "x 5\n" "y 3\n" "z 1\n" "=======\n" "z 1\n" "w 2\n" "y 3\n" "v 4\n" "x 5\n" ); MVCRO(" $y) return -1;\n" " return 0;\n" "}\n" "$v = new Vector;\n" "$v[] = 'c';\n" "$v[] = 'a';\n" "$v[] = 'b';\n" "usort($v, 'cmp');\n" "foreach ($v as $key => $val) {\n" " echo $key . ' ' . $val . \"\\n\";\n" "}\n" "echo \"=======\\n\";\n" "$s = new StableMap;\n" "$s['w'] = 2;\n" "$s['v'] = 4;\n" "$s['y'] = 3;\n" "$s['x'] = 5;\n" "$s['z'] = 1;\n" "uksort($s, 'cmp');\n" "foreach ($s as $key => $val) {\n" " echo $key . ' ' . $val . \"\\n\";\n" "}\n" "echo \"=======\\n\";\n" "uasort($s, 'cmp');\n" "foreach ($s as $key => $val) {\n" " echo $key . ' ' . $val . \"\\n\";\n" "}\n" , "0 c\n" "1 b\n" "2 a\n" "=======\n" "z 1\n" "y 3\n" "x 5\n" "w 2\n" "v 4\n" "=======\n" "x 5\n" "v 4\n" "y 3\n" "w 2\n" "z 1\n" ); MVCRO(" 1, 'b' => 2});\n" "\n" " var_dump(Vector {});\n" " var_dump(Map {});\n" " var_dump(Vector {1, 2});\n" " var_dump(StableMap {'a' => 1, 'b' => 2});\n" "}\n" "f();\n" , "object(Vector)#1 (0) {\n" "}\n" "object(Map)#1 (0) {\n" "}\n" "object(Vector)#1 (2) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" "}\n" "object(StableMap)#1 (2) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " int(2)\n" "}\n" "object(Vector)#1 (0) {\n" "}\n" "object(Map)#1 (0) {\n" "}\n" "object(Vector)#1 (2) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" "}\n" "object(StableMap)#1 (2) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " int(2)\n" "}\n" ); MVCRO(" $v1, $k2 => $v2};\n" " return $m;\n" "}\n" "var_dump(f(42, 123.456, 'blah', array(3, 5, 7)));\n" "var_dump(g('foo', 1, 2, 'bar'));\n" , "object(Vector)#1 (4) {\n" " [0]=>\n" " int(42)\n" " [1]=>\n" " float(123.456)\n" " [2]=>\n" " string(4) \"blah\"\n" " [3]=>\n" " array(3) {\n" " [0]=>\n" " int(3)\n" " [1]=>\n" " int(5)\n" " [2]=>\n" " int(7)\n" " }\n" "}\n" "object(Map)#1 (2) {\n" " [\"foo\"]=>\n" " int(1)\n" " [2]=>\n" " string(3) \"bar\"\n" "}\n" ); MVCRO("getMessage());\n" " }\n" " try {\n" " $c[PHP_INT_MAX];\n" " } catch (Exception $e) {\n" " var_dump($e->getMessage());\n" " }\n" " try {\n" " $c[~PHP_INT_MAX];\n" " } catch (Exception $e) {\n" " var_dump($e->getMessage());\n" " }\n" " if ($ctype === 'Vector') {\n" " continue;\n" " }\n" " try {\n" " $c['abc'];\n" " } catch (Exception $e) {\n" " var_dump($e->getMessage());\n" " }\n" " try {\n" " $c['abcdefghijklmnopqrst'];\n" " } catch (Exception $e) {\n" " var_dump($e->getMessage());\n" " }\n" " try {\n" " $c['abcdefghijklmnopqrstu'];\n" " } catch (Exception $e) {\n" " var_dump($e->getMessage());\n" " }\n" " try {\n" " $c[\"abcdefghij\\000klmnopqrst\"];\n" " } catch (Exception $e) {\n" " $str = $e->getMessage();\n" " $i = 0;\n" " for (;;) {\n" " echo(ord($str[$i]));\n" " ++$i;\n" " if ($i >= strlen($str)) {\n" " break;\n" " }\n" " if (($i % 8) === 0) {\n" " echo \"\\n\";\n" " } else {\n" " echo ' ';\n" " }\n" " }\n" " echo \"\\n\";\n" " }\n" "}\n" , "=== Vector ===\n" "string(30) \"Integer key 0 is out of bounds\"\n" "string(48) \"Integer key 9223372036854775807 is out of bounds\"\n" "string(49) \"Integer key -9223372036854775808 is out of bounds\"\n" "=== Map ===\n" "string(28) \"Integer key 0 is not defined\"\n" "string(46) \"Integer key 9223372036854775807 is not defined\"\n" "string(47) \"Integer key -9223372036854775808 is not defined\"\n" "string(31) \"String key \"abc\" is not defined\"\n" "string(48) \"String key \"abcdefghijklmnopqrst\" is not defined\"\n" "string(48) \"String key \"abcdefghijklmnopq...\" is not defined\"\n" "83 116 114 105 110 103 32 107\n" "101 121 32 34 97 98 99 100\n" "101 102 103 104 105 106 0 107\n" "108 109 110 111 112 46 46 46\n" "34 32 105 115 32 110 111 116\n" "32 100 101 102 105 110 101 100\n" "=== StableMap ===\n" "string(28) \"Integer key 0 is not defined\"\n" "string(46) \"Integer key 9223372036854775807 is not defined\"\n" "string(47) \"Integer key -9223372036854775808 is not defined\"\n" "string(31) \"String key \"abc\" is not defined\"\n" "string(48) \"String key \"abcdefghijklmnopqrst\" is not defined\"\n" "string(48) \"String key \"abcdefghijklmnopq...\" is not defined\"\n" "83 116 114 105 110 103 32 107\n" "101 121 32 34 97 98 99 100\n" "101 102 103 104 105 106 0 107\n" "108 109 110 111 112 46 46 46\n" "34 32 105 115 32 110 111 116\n" "32 100 101 102 105 110 101 100\n" ); MVCRO(" 1, 'b' => 2, 'c' => 3, 'd' => 4};\n" " unset($x['a']);\n" " unset($x['c']);\n" " foreach ($x as $k => $v) {\n" " echo $k . ' ' . $v . \"\\n\";\n" " }\n" "}\n" "f();\n" , "b 2\n" "d 4\n" ); MVCRO(" 1, 'b' => 2, 'c' => 3, 'd' => 4};\n" "$m1->remove('a');\n" "$m1->remove('c');\n" "$m2 = Map {'b' => 2, 'd' => 4};\n" "var_dump($m1 == $m2);\n" "$m1->remove('d');\n" "var_dump($m1 == $m2);\n" "$m2->remove('d');\n" "var_dump($m1 == $m2);\n" "$m1['d'] = 4;\n" "var_dump($m1 == $m2);\n" "$m2['d'] = 4;\n" "var_dump($m1 == $m2);\n" "echo \"============\\n\";\n" "$m = Map {};\n" "var_dump($m == null);\n" "var_dump($m == false);\n" "var_dump($m == true);\n" "var_dump($m == 1);\n" "var_dump($m == \"Map\");\n" "echo \"============\\n\";\n" "$m = Map {'x' => 7};\n" "var_dump($m == null);\n" "var_dump($m == false);\n" "var_dump($m == true);\n" "var_dump($m == 1);\n" "var_dump($m == \"Map\");\n" , "bool(true)\n" "bool(true)\n" "bool(false)\n" "============\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "============\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "============\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" ); MVCRO(" 1, 'b' => 2};\n" "$s2 = StableMap {'b' => 2, 'a' => 1};\n" "var_dump($s1 == $s2);\n" "$s2->remove('b');\n" "$s2['b'] = 2;\n" "var_dump($s1 == $s2);\n" "$s1['b'] = \"2\";\n" "var_dump($s1 == $s2);\n" "$s1['b'] = 3;\n" "var_dump($s1 == $s2);\n" "echo \"============\\n\";\n" "$m = StableMap {};\n" "var_dump($m == null);\n" "var_dump($m == false);\n" "var_dump($m == true);\n" "var_dump($m == 1);\n" "var_dump($m == \"StableMap\");\n" "echo \"============\\n\";\n" "$m = StableMap {'x' => 7};\n" "var_dump($m == null);\n" "var_dump($m == false);\n" "var_dump($m == true);\n" "var_dump($m == 1);\n" "var_dump($m == \"StableMap\");\n" , "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "============\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "============\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" ); { HipHopSyntax w1(this); MVCRO(" 1, 2 => 'b'};\n" " $v = new Vector($m);\n" " var_dump($v);\n" "}\n" "function h() {\n" " $arr1 = array(11, 22, 33);\n" " var_dump(new Vector($arr1));\n" " var_dump(new Map($arr1));\n" " $arr2 = array('a' => 1, 2 => 'b');\n" " var_dump(new Vector($arr2));\n" " var_dump(new StableMap($arr2));\n" "}\n" "function gen() {\n" " yield 42;\n" " yield 72;\n" "}\n" "function j() {\n" " $v = new Vector(gen());\n" " var_dump($v);\n" "}\n" "f();\n" "g();\n" "h();\n" "j();\n" , "object(Map)#2 (3) {\n" " [0]=>\n" " string(1) \"a\"\n" " [1]=>\n" " string(1) \"b\"\n" " [2]=>\n" " string(1) \"c\"\n" "}\n" "object(StableMap)#3 (3) {\n" " [0]=>\n" " string(1) \"a\"\n" " [1]=>\n" " string(1) \"b\"\n" " [2]=>\n" " string(1) \"c\"\n" "}\n" "object(Vector)#2 (2) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " string(1) \"b\"\n" "}\n" "object(Vector)#1 (3) {\n" " [0]=>\n" " int(11)\n" " [1]=>\n" " int(22)\n" " [2]=>\n" " int(33)\n" "}\n" "object(Map)#1 (3) {\n" " [0]=>\n" " int(11)\n" " [1]=>\n" " int(22)\n" " [2]=>\n" " int(33)\n" "}\n" "object(Vector)#1 (2) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " string(1) \"b\"\n" "}\n" "object(StableMap)#1 (2) {\n" " [\"a\"]=>\n" " int(1)\n" " [2]=>\n" " string(1) \"b\"\n" "}\n" "object(Vector)#1 (2) {\n" " [0]=>\n" " int(42)\n" " [1]=>\n" " int(72)\n" "}\n" ); MVCRO("count());\n" " var_dump($t->isEmpty());\n" " echo \"==========\\n\";\n" " $c = new C;\n" " $t = $c->t;\n" " var_dump(count($t));\n" " var_dump($t->count());\n" " var_dump($t->isEmpty());\n" " g($t);\n" " echo \"==========\\n\";\n" " foreach ($t as $k => $v) {\n" " var_dump($k, $v);\n" " }\n" " echo \"==========\\n\";\n" " var_dump($t[0], $t[1], $t[2]);\n" " echo \"==========\\n\";\n" " var_dump($t->at(0), $t->at(1), $t->at(2));\n" " echo \"==========\\n\";\n" " var_dump($t->get(0), $t->get(1), $t->get(2), $t->get(3));\n" " echo \"==========\\n\";\n" " var_dump((array)$t);\n" " echo \"==========\\n\";\n" " var_dump(serialize($t));\n" " var_dump(unserialize(serialize($t)));\n" " echo \"==========\\n\";\n" " var_dump($t->count());\n" " echo \"==========\\n\";\n" " var_dump($t->getIterator() instanceof Iterator);\n" " var_dump($t->getIterator() instanceof KeyedIterator);\n" " foreach ($t->getIterator() as $k => $v) {\n" " var_dump($k, $v);\n" " }\n" " echo \"==========\\n\";\n" " var_dump((array)$t);\n" " var_dump($t->toArray());\n" " echo \"==========\\n\";\n" " var_dump(clone $t);\n" "}\n" "f();\n" , "int(32)\n" "int(32)\n" "bool(false)\n" "==========\n" "int(3)\n" "int(3)\n" "bool(false)\n" "==========\n" "int(0)\n" "string(3) \"foo\"\n" "int(1)\n" "int(42)\n" "int(2)\n" "string(1) \"!\"\n" "==========\n" "string(3) \"foo\"\n" "int(42)\n" "string(1) \"!\"\n" "==========\n" "string(3) \"foo\"\n" "int(42)\n" "string(1) \"!\"\n" "==========\n" "string(3) \"foo\"\n" "int(42)\n" "string(1) \"!\"\n" "NULL\n" "==========\n" "array(3) {\n" " [0]=>\n" " string(3) \"foo\"\n" " [1]=>\n" " int(42)\n" " [2]=>\n" " string(1) \"!\"\n" "}\n" "==========\n" "string(39) \"V:5:\"Tuple\":3:{s:3:\"foo\";i:42;s:1:\"!\";}\"\n" "object(Tuple)#6 (3) {\n" " [0]=>\n" " string(3) \"foo\"\n" " [1]=>\n" " int(42)\n" " [2]=>\n" " string(1) \"!\"\n" "}\n" "==========\n" "int(3)\n" "==========\n" "bool(true)\n" "bool(true)\n" "int(0)\n" "string(3) \"foo\"\n" "int(1)\n" "int(42)\n" "int(2)\n" "string(1) \"!\"\n" "==========\n" "array(3) {\n" " [0]=>\n" " string(3) \"foo\"\n" " [1]=>\n" " int(42)\n" " [2]=>\n" " string(1) \"!\"\n" "}\n" "array(3) {\n" " [0]=>\n" " string(3) \"foo\"\n" " [1]=>\n" " int(42)\n" " [2]=>\n" " string(1) \"!\"\n" "}\n" "==========\n" "object(Tuple)#6 (3) {\n" " [0]=>\n" " string(3) \"foo\"\n" " [1]=>\n" " int(42)\n" " [2]=>\n" " string(1) \"!\"\n" "}\n" ); } MVCRO("keys() as $x) {\n" " var_dump($x);\n" "}\n" "$mp = StableMap {'a' => 1, 2 => 'b', 'z' => 9};\n" "foreach ($mp->keys() as $x) {\n" " var_dump($x);\n" "}\n" "var_dump(new Vector($mp->keys()));\n" , "int(0)\n" "int(1)\n" "int(2)\n" "string(1) \"a\"\n" "int(2)\n" "string(1) \"z\"\n" "object(Vector)#7 (3) {\n" " [0]=>\n" " string(1) \"a\"\n" " [1]=>\n" " int(2)\n" " [2]=>\n" " string(1) \"z\"\n" "}\n" ); MVCRO("items() as $x) {\n" " var_dump($x);\n" "}\n" "$mp1 = StableMap {'a' => 1, 2 => 'b', 'z' => 9};\n" "foreach ($mp1->items() as $t) {\n" " var_dump($t[0], $t[1]);\n" "}\n" "var_dump(new Vector($mp1->items()));\n" "echo \"==========\\n\";\n" "$vec2 = Vector::fromItems($mp1->items());\n" "var_dump($vec2);\n" "$mp2 = StableMap::fromItems($mp1->items());\n" "var_dump($mp2);\n" "echo \"==========\\n\";\n" "$tuples = Vector {Tuple {'a', 1}, Tuple {2, 'b'}, Tuple {'z', 9}};\n" "$mp3 = StableMap::fromItems($tuples);\n" "var_dump($mp3);\n" , "int(11)\n" "int(42)\n" "int(73)\n" "string(1) \"a\"\n" "int(1)\n" "int(2)\n" "string(1) \"b\"\n" "string(1) \"z\"\n" "int(9)\n" "object(Vector)#10 (3) {\n" " [0]=>\n" " object(Tuple)#15 (2) {\n" " [0]=>\n" " string(1) \"a\"\n" " [1]=>\n" " int(1)\n" " }\n" " [1]=>\n" " object(Tuple)#16 (2) {\n" " [0]=>\n" " int(2)\n" " [1]=>\n" " string(1) \"b\"\n" " }\n" " [2]=>\n" " object(Tuple)#17 (2) {\n" " [0]=>\n" " string(1) \"z\"\n" " [1]=>\n" " int(9)\n" " }\n" "}\n" "==========\n" "object(Vector)#21 (3) {\n" " [0]=>\n" " object(Tuple)#22 (2) {\n" " [0]=>\n" " string(1) \"a\"\n" " [1]=>\n" " int(1)\n" " }\n" " [1]=>\n" " object(Tuple)#23 (2) {\n" " [0]=>\n" " int(2)\n" " [1]=>\n" " string(1) \"b\"\n" " }\n" " [2]=>\n" " object(Tuple)#24 (2) {\n" " [0]=>\n" " string(1) \"z\"\n" " [1]=>\n" " int(9)\n" " }\n" "}\n" "object(StableMap)#29 (3) {\n" " [\"a\"]=>\n" " int(1)\n" " [2]=>\n" " string(1) \"b\"\n" " [\"z\"]=>\n" " int(9)\n" "}\n" "==========\n" "object(StableMap)#34 (3) {\n" " [\"a\"]=>\n" " int(1)\n" " [2]=>\n" " string(1) \"b\"\n" " [\"z\"]=>\n" " int(9)\n" "}\n" ); MVCRO("containsKey(0));\n" " var_dump($vec->containsKey(1));\n" " var_dump($vec->containsKey(2));\n" " echo \"==========\\n\";\n" " $mp = Map {'a' => 1, 2 => 'b'};\n" " var_dump($mp->containsKey('a'));\n" " var_dump($mp->containsKey(2));\n" " var_dump($mp->containsKey('b'));\n" " echo \"==========\\n\";\n" " $smp = StableMap {'a' => 1, 2 => 'b'};\n" " var_dump($smp->containsKey('a'));\n" " var_dump($smp->containsKey(2));\n" " var_dump($smp->containsKey('b'));\n" " echo \"==========\\n\";\n" " $tup = Tuple {1, 'b'};\n" " var_dump($tup->containsKey(0));\n" " var_dump($tup->containsKey(1));\n" " var_dump($tup->containsKey(2));\n" "}\n" "f();\n" , "bool(true)\n" "bool(true)\n" "bool(false)\n" "==========\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "==========\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "==========\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" ); MVCRO(" 1, 2 => 'b', 'c' => array()};\n" " $mp2 = StableMap {};\n" " $mp3 = StableMap {};\n" " foreach ($mp1->items() as $t) {\n" " $mp2->add($t);\n" " }\n" " var_dump($mp2);\n" " foreach ($mp1->items() as $t) {\n" " $mp3[] = $t;\n" " }\n" " var_dump($mp3);\n" "}\n" "f();\n" , "object(StableMap)#2 (3) {\n" " [\"a\"]=>\n" " int(1)\n" " [2]=>\n" " string(1) \"b\"\n" " [\"c\"]=>\n" " array(0) {\n" " }\n" "}\n" "object(StableMap)#3 (3) {\n" " [\"a\"]=>\n" " int(1)\n" " [2]=>\n" " string(1) \"b\"\n" " [\"c\"]=>\n" " array(0) {\n" " }\n" "}\n" ); return true; } /////////////////////////////////////////////////////////////////////////////// // comparisons #define COMPARE(a, op, b) \ "print ++$i; print \"\\t\"; " \ "print (" #a #op #b ") ? 'Y' : 'N'; " \ "$a = 1; $a = 't'; $a = " #a "; " \ "print ($a " #op #b ") ? 'Y' : 'N'; " \ "$b = 1; $b = 't'; $b = " #b "; " \ "print (" #a #op "$b) ? 'Y' : 'N'; " \ "print ($a " #op "$b) ? 'Y' : 'N'; " \ "print \"\\t\"; " \ "print \"" #a " " #op " " #b "\t\"; " \ "print \"\\n\"; " \ #define COMPARE_ALL(a, op) \ COMPARE(a, op, true) \ COMPARE(a, op, false) \ COMPARE(a, op, 1) \ COMPARE(a, op, 0) \ COMPARE(a, op, -1) \ COMPARE(a, op, '1') \ COMPARE(a, op, '0') \ COMPARE(a, op, '-1') \ COMPARE(a, op, nullptr) \ COMPARE(a, op, array()) \ COMPARE(a, op, array(1)) \ COMPARE(a, op, array(2)) \ COMPARE(a, op, array('1')) \ COMPARE(a, op, array('0' => '1')) \ COMPARE(a, op, array('a')) \ COMPARE(a, op, array('a' => 1)) \ COMPARE(a, op, array('b' => 1)) \ COMPARE(a, op, array('a' => 1, 'b' => 2)) \ COMPARE(a, op, array(array('a' => 1))) \ COMPARE(a, op, array(array('b' => 1))) \ COMPARE(a, op, 'php') \ COMPARE(a, op, '') \ #define COMPARE_OP(op) \ MVCR(" '1'), op)); \ MVCR(" 1), op)); \ MVCR(" 1), op)); \ MVCR(" 1, 'b' => 2), op)); \ MVCR(" 1)), op)); \ MVCR(" 1)), op)); \ MVCR(" 1, 2 => 1) == array(2 => 1, 1 => 1));"); MVCR(" 1, 2 => 1) === array(2 => 1, 1 => 1));"); MVCR("1,'b'=> 1) == array('b'=>1,'a'=> 1));"); MVCR("1,'b'=> 1) === array('b'=>1,'a'=> 1));"); MVCR("); COMPARE_OP(!==); COMPARE_OP(<); COMPARE_OP(>); COMPARE_OP(<=); COMPARE_OP(>=); MVCR("x = 1;" "$y = new c;" "var_dump($x > $y);" "var_dump(array($x) == array($y));"); MVCR(" '') {" " echo 'yes';" " } else {" " echo 'no';" " }" "}" "foo(false);"); MVCR(" 0);\n" "var_dump ($x >= 1);\n" "var_dump ($x < 5);\n" "var_dump ($x <= 1);\n"); MVCR("foo = 2;\n" "var_dump($a < $b);\n" "var_dump($a <= $b);\n" "var_dump($a > $b);\n" "var_dump($a >= $b);\n" "var_dump($b < $a);\n" "var_dump($b <= $a);\n" "var_dump($b > $a);\n" "var_dump($b >= $a);\n"); return true; } /////////////////////////////////////////////////////////////////////////////// // semantics bool TestCodeRun::TestUnset() { MVCR("arr[] = 'test';" "var_dump($obj->arr); unset($obj->arr); var_dump($obj->arr);"); MVCR("a = $p;" " }" "};" "$obj = new A(1);" "var_dump($obj);" "unset($obj->a);" "var_dump($obj);" "$obj->a = 2;" "var_dump($obj);" "$obj->b = 3;" "var_dump($obj);" "unset($obj->b);" "var_dump($obj);" "$obj->a = 2;" "var_dump($obj);" "$obj->b = 3;" "var_dump($obj);" "unset($obj->a, $obj->b);" "var_dump($obj);"); MVCR("foo(); \n" "$obj->bar();\n" "A::bar();\n" "goo();\n" "unset($this);\n" "var_dump($this);\n"); MVCR(" 'foo');\n" "unset($a[null]);\n" "var_dump($a);\n"); return true; } bool TestCodeRun::TestReference() { MVCR(" 1240430476);" "$idxa = &$idxa['a'];"); MVCR(" &$v) { $v = 'ok';} var_dump($a, $b);"); MVCR(" &$a); var_dump($b); " "$a = 20; var_dump($b);"); MVCR("b = 10; f($a->b); var_dump($a);"); MVCR("b = 10; f($a->b); var_dump($a);"); MVCR("b = 10; f($a->b); var_dump($a);"); // reference returns MVCR(" &$a); var_dump($a);"); //VCR(" &$a); $b = array($a); var_dump($b);"); MVCR(" &$b); $a['r'] = 6; test($a); var_dump($a);"); MVCR("0);" "$ref = &$a['a'];" "var_dump($a);" "$b = $a;" "var_dump($a,$b);" "$b['a'] = 1;" "var_dump($a,$b);" "$a = array(0);" "$ref = &$a[0];" "var_dump($a);" "$b = $a;" "var_dump($a,$b);" "$b[0] = 1;" "var_dump($a,$b);" ); // reference self assignment MVCR("t($arr['hello'], $arr);" "}" "test();" "$arr = array('hello' => 1);" "$x = &$arr['hello'];" "$arr['hello'] = $x;" "var_dump($arr);" "function test2(&$a, $b) {" " $a = $b;" "}" "$v = 10;" "test2($v, $v);" "var_dump($v);"); // reference, parameter & assignment MVCR(" 1);" " $t = &$perms;" " $t = $t['x'];" " unset($t);" " return $perms;" "}" "var_dump(foo());"); MVCR("foo['a']['b']);" " $x[0]->foo['a']['b'] = 5;" " var_dump($x);" "}" "foo(false);" "function baz(&$x) {}" "foreach ($x->foo[1]->prop as &$y) {}" "var_dump($x);" "baz($q->foo[1]->prop);" "var_dump($q);" "$y = &$z->foo[1]->prop;" "var_dump($z);" "function &fiz(&$x) {" " return $x->foo[1]->prop;" "}" "fiz($w);" "var_dump($w);"); MVCR("f('f', 'this');\n" "$a->f('g', 'this');\n" "$a->g('f', 30);\n" "$a->g('g', 30);\n"); MVCR("x = 0;" " }" "}" "function test(&$a, $b) {" " var_dump($a, $b);" "}" "function f($x) {" " unset($GLOBALS['a']);" " return 1;" "}" "$a = array(new X);" "test($a[0], f(1));"); MVCR("t();"); // l-value MVCR(" 'aval')); var_dump($a);"); MVCR(" 'ok')); $a = 1; var_dump($a);"); MVCR(" 'ok'), EXTR_SKIP); var_dump($a);"); MVCR(" 'ok'), EXTR_PREFIX_SAME, 'p');" " var_dump($p_a);"); MVCR(" 'ok'), EXTR_PREFIX_ALL, 'p');" " var_dump($p_a);"); MVCR(" 'ok'), EXTR_IF_EXISTS); var_dump($a);"); MVCR(" 'ok', 'b' => 'no'), EXTR_PREFIX_IF_EXISTS, 'p'); var_dump($p_a); var_dump($b); var_dump($p_b);"); MVCR(" &$a), EXTR_REFS); $b = 'no'; var_dump($a);"); MVCR(" &$a); extract($arr, EXTR_REFS); $b = 'no'; var_dump($a);"); MVCR(" 2, '1d' => 3);\n" " extract($arr);\n" " $vars = get_defined_vars(); asort($vars); var_dump($vars);\n" "}\n" "f();\n"); MVCR("$b = 'test'; var_dump($this->$b); var_dump($this->a);" " $c = &$this->$b; $c = array(1); var_dump($this->a);" " }" "} $obj = new B(); $obj->test();"); MVCR("a);"); MVCR("$f = 100; var_dump($a); " "var_dump((array)$a); " "$f = 100; " "f($a->$f); " "foreach ($a as $k => &$v) { var_dump($k); $v = 1; } " "var_dump($a); "); return true; } bool TestCodeRun::TestDynamicFunctions() { MVCR(" 100) { $f = 'var_dump'; } else { $f = 'sscanf'; }" "$auth = \"24\\tLewis Carroll\";" "$n = $f($auth, \"%d\\t%s %s\", $id, $first, $last);" "echo \"$id,$first,$last\\n\";"); // Test dynamically calling a builtin that is MixedVariableArguments MVCR(" 3, 'a' => 2, 'c' => 1)," " array('x' => 6, 'y' => 4, 'z' => 5)," " array('p' => 8, 'q' => 9, 'r' => 7));" " if ($flag) { $f = 'var_dump'; } else { $f = 'array_multisort'; }" " $f($arr[0], $arr[1], $arr[2]);" " var_dump($arr);" "}" "bar($argc > 100);"); return true; } bool TestCodeRun::TestRenameFunction() { OptionSetter w0(this, OptionSetter::CompileTime, "-vDynamicInvokeFunctions.*=test1 " "-vDynamicInvokeFunctions.*=test2"); OptionSetter w1(this, OptionSetter::RunTime, "-vEval.JitEnableRenameFunction=true"); MVCRO("$f($b); var_dump($b); var_dump($c);"); MVCR("$name();} } " "$obj = new A(); $obj->test();"); MVCR("$m($ar[0], $st[0]); A::$m($ar[1], $st[1]);"); { OptionSetter w(this, OptionSetter::CompileTime, "-v DynamicMethodPrefix.*=_"); MVCR("$name();} }" "$obj = new A(); $obj->test();"); } MVCR("refTestHelper($x);" " var_dump($x);" "}" "$q = new z;" "$f = 'minArgTest';" "$q->minArgTest('one',2,3.333,4,5,6,7,8,9,10);" "$q->minArgTest('one',2,3.333,4,5,6,7,8,9,10,11,12);" "$q->$f('one',2,3.333,4,5,6,7,8,9,10);" "$q->$f('one',2,3.333,4,5,6,7,8,9,10,11,12);" "refTest($q);" "$f = 'varArgsTest';" "$q->varArgsTest('one',2,3.333,4,5,6,7,8,9,10);" "$q->varArgsTest('one',2,3.333,4,5,6,7,8,9,10,11,12);" "$q->$f('one',2,3.333,4,5,6,7,8,9,10);" "$q->$f('one',2,3.333,4,5,6,7,8,9,10,11,12);" "$f = 'varArgsTest2';" "$q->varArgsTest2('one',2,3.333,4,5,6,7,8,9,10);" "$q->varArgsTest2('one',2,3.333,4,5,6,7,8,9,10,11,12);" "$q->$f('one',2,3.333,4,5,6,7,8,9,10);" "$q->$f('one',2,3.333,4,5,6,7,8,9,10,11,12);"); MVCR("z();"); MVCR("functions['test'] = $function;" " print($this->functions['test']());" " }" "}" "$a = new foo ();"); MVCR("q();"); MVCR("$method($aa[3]);" "var_dump($aa);"); MVCR("overridden();" " } else {" " static::overridden();" " }" " }" "}" "class Child extends Parent_ {" " protected final function overridden() {" " var_dump(isset($this), __METHOD__);" " }" " protected function calledHere() {" " var_dump(__METHOD__);" " }" " public function entry($fun = 'calledHere') {" " self::callParent($fun);" " }" " function callParent($fun) {" " parent::$fun();" " if (isset($this)) {" " $this::$fun();" " }" " }" "}" "$c = new Child;" "$c->entry();" "$c->entry('overridden');" "Child::entry();" "Child::callParent('calledHere');" "Child::callParent('overridden');"); return true; } bool TestCodeRun::TestVolatile() { MVCR(" 1 && !defined('CON')) {" " define(/*|Dynamic|*/'CON', 1);" " }" " if (defined('CON')) {" " var_dump(CON);" " } else {" " echo \"CON does not exists\\n\";" " }" "}" "for ($i = 0; $i < 4; $i++) {" " if ($i > 1 && !function_exists('foo')) {" " function foo() {" " echo \"foo called\\n\";" " }" " }" " if (function_exists('foo')) {" " foo();" " } else {" " echo \"foo does not exists\\n\";" " }" "}" "for ($i = 0; $i < 4; $i++) {" " if ($i > 1 && !class_exists('bar')) {" " class bar {" " function bar() { echo \"bar called\\n\"; }" " }" " }" " if (class_exists('bar')) {" " $a = new bar;" " } else {" " echo \"bar does not exists\\n\";" " }" "}"); MVCR(" 1 && !function_exists('foo')) {" " function foo() {" " echo \"foo called\\n\";" " }" " }" " $foo = 'foo';" " if (function_exists($foo)) {" " foo();" " } else {" " echo \"foo does not exists\\n\";" " }" " }" " for ($i = 0; $i < 4; $i++) {" " if ($i > 1 && !class_exists('goo')) {" " class goo {" " function goo() {" " echo \"goo called\\n\";" " }" " }" " }" " $goo = 'goo';" " if (class_exists($goo)) {" " $a = new goo();" " } else {" " echo \"goo does not exists\\n\";" " }" " }" "}" "if (function_exists('bar')) bar();" "$a = 'bar';" "if (function_exists($a)) bar();" "$a = 'later';" "if (function_exists($a)) {" " echo \"later exists\\n\";" "} else {" " echo \"later does not exists\\n\";" "}" "$a = 'later2';" "if (class_exists($a)) {" " echo \"later2 exists\\n\";" "} else {" " echo \"later2 does not exists\\n\";" "}" "$a = 'later3';" "if (function_exists($a)) {" " echo \"later3 exists\\n\";" "} else {" " echo \"later3 does not exists\\n\";" "}" "$a = 'later4';" "if (class_exists($a)) {" " echo \"later4 exists\\n\";" "} else {" " echo \"later4 does not exists\\n\";" "}" "function later3() {" " echo \"later3 called\\n\";" "}" "class later4 {" "}" "if (function_exists('function_exists')) {" " echo \"yes\\n\";" "}" "if (class_exists('exception')) {" " echo \"yes\\n\";" "}"); MVCR("f();" "} else {" " var_dump('correct');" "}"); MVCR("getMessage() . \"\\n\";\n" " } while($e = $e->getPrevious());\n" "}\n" "try {\n" " $obj = new A();\n" "} catch(Exception $e) {\n" " do {\n" " echo $e->getMessage() . \"\\n\";\n" " } while($e = $e->getPrevious());\n" "}\n" "// hphpc won't call the autoloader unless there exists a \n" "// definition for the class somewhere\n" "if (true) {\n" " class A {}\n" "}\n", "autoload_first\n" "autoload_second\n" "second\n" "second_inner\n" "first\n" "first_inner\n" "autoload_first\n" "autoload_second\n" "second\n" "second_inner\n" "first\n" "first_inner\n"); MVCRO("\n" " string(1) \"f\"\n" "}\n" "array(0) {\n" "}\n" "bool(false)\n" "array(1) {\n" " [0]=>\n" " string(1) \"f\"\n" "}\n" "bool(false)\n"); MVCRO(" array()," " 'constant' => array()," " 'failure' => 'failure')," " ''));" "function failure($kind, $name) {" " if ($kind == 'constant' && $name == 'bar') define('bar', 'baz');" " var_dump($kind, $name);" "}" "var_dump(function_exists('foo'));" "var_dump(function_exists('bar', false));" "var_dump(defined('foo'));" "var_dump(defined('bar', false));" "var_dump(constant('foo'));" "var_dump(constant('bar'));" "if (0) {" " function foo() {}" " function foo() {}" " define('foo', 0);" " define('bar', 0);" "}", "bool(true)\n" "string(8) \"function\"\n" "string(3) \"foo\"\n" "bool(false)\n" "bool(false)\n" "string(8) \"constant\"\n" "string(3) \"foo\"\n" "bool(false)\n" "bool(false)\n" "string(8) \"constant\"\n" "string(3) \"foo\"\n" "NULL\n" "string(8) \"constant\"\n" "string(3) \"bar\"\n" "string(3) \"baz\"\n"); return true; } bool TestCodeRun::TestHereDoc() { MVCR(" Double MVCR(" 't');} class B { public $a;} " "$a = 1; $a = new A(); $a->a['t'] = true; var_dump($a->a['t']);"); // Variant % operator MVCR(" -MAX_LATITUDE) define('MAX_LATITUDE', 90); "); // toInt64() wrapper MVCR("a = $a->b = 'test'; var_dump($a);"); MVCR("prop++; var_dump($a->prop);"); // obj->prop doesn't need lval() wrapper MVCR("prop++; var_dump($a->prop);"); // ((p_obj)variant)->prop MVCR("prop++; var_dump($a->prop);"); // unsigned int should never be seen MVCR("test($a, $b);"); // method->method MVCR("getA()->test();" ); // constructor fallback MVCR("method MVCR("b = new A(); $a->b->test();"); // testing code generation order MVCR(" 1); var_dump($_SERVER);"); MVCR(" 1); var_dump($_SERVER);"); // class constant as default MVCR("foo();} " "function foo() { print 'foo';}}"); MVCR("f(date('m/d/y H:i:s', 123456789));" "$v = date(\"m\",123456789)+1;"); // no side effect optimization met if() short MVCR(" 0) ? $n : $n + 1);"); MVCR("test(1, 2) : false;" "}" "var_dump(test(1));"); MVCR("foo = f($b++, $b++, $b++)) . f(1,2,3);" " return $x;" "}"); MVCR("$foo) || empty($x->$foo) ||" " isset($x->{'bar'})) {" " unset($x->$foo);" " unset($x->{'bar'});" " echo true;" " }" "}"); MVCR("newInstance()->loadAll(); }"); MVCR("error = '';" " }" " return $r;" "}" "var_dump(foo(true));" "var_dump(foo(false));"); MVCR("error->line = 1;" " }" " return $r;" "}" "var_dump(foo(true));" "var_dump(foo(false));"); MVCR("baz(bar(1), bar(''));" " }" "}"); MVCR("bar();" "}"); MVCR("foo(1);"); MVCR("foo);" " $x = new X;" " var_dump($x);" "}" "foo();"); MVCR("serial = self::$nextSerial++;" " }" "}"); { OptionSetter w1(this, OptionSetter::CompileTime, "-vLocalCopyProp=0 -vEliminateDeadCode=0"); MVCR("';" " $body .= '';" " $item_num = 0;" " if (null !== $values) {" " foreach($values as $val) {" " $row_id = 'tr_sentrylist_' . $item_num . '_' . $full_name;" " $body .= '';" " $body .= '';" " $body .= '';" " $body .= '';" " $item_num += 1;" " }" " }" " $body .= '
';" " $body .= foo($item_num, 0," " $val, $parent_fields);" " $body .= '';" " $body .= foo($item_num, $full_name, 0, 0);" " $body .= '
';" "}"); MVCR("bar();" " };" " }" " function bar() {}" "}"); MVCR("bar();" "}" "test();"); MVCRNW("foo();" " $x->foo();" " }" " function foo() { var_dump(__METHOD__); }" "}" "function test() {" " X::bar(null);" "}" "test();"); MVCR("__array[$offset])) {" " return $this->initializeOffset($offset);" " } else {" " return null;" " }" " return $this->__array[$offset];" " }" "}"); MVCR("bar();" " }" " return $x;" " }" "}"); MVCR("foo(false, true));"); MVCR(" false, 5 => false);\n" " $c = new C();\n" " var_dump($c->loadAllWithIDs($testA));\n" "}\n" "\n" "main();\n"); MVCR("bar();" " if ($this instanceof B) {" " $this->b = 1;" " }" " $this->a = 1;" " }" "}" "class B extends A {" " public $b;" " function bar() {}" "}" "function main() {" " $b = new B;" " $b->foo();" " var_dump($b);" "}" "main();"); return true; } bool TestCodeRun::TestReflection() { MVCR("name, $x->class);\n"); MVCR("a();" "$y = new Y;" "$y->a();" "var_dump(get_class_methods($x));" "var_dump(get_class_methods($y));"); MVCR("getParameters();\n" "var_dump($params[0]->isDefaultValueAvailable());\n"); MVCR("getMethod($mname);" " echo \"$cname:$mname:\"; var_dump($m->isConstructor());" "}" "test('X', 'X');" "test('Y', 'Y');" "test('Y', 'y');" "test('Z', 'Z');" "test('Z', 'z');"); MVCR("getMethods()));", "int(1)\n"); MVCRO("getMethods() as $m) {" " var_dump($m->name);" " }" "}" "test();", "string(3) \"bar\"\n"); MVCRO("getDocComment());\n" "\n" "class C {\n" " /**\n" " * Doc comment on a method generator\n" " */\n" " public function bar() {\n" " yield null;\n" " }\n" "}\n" "$rm = new ReflectionMethod('C','bar');\n" "var_dump($rm->getDocComment());\n" , "string(46) \"/**\n" " * Doc comment on a function generator\n" " */\"\n" "string(48) \"/**\n" " * Doc comment on a method generator\n" " */\"\n" ); } MVCR("getMethods());" " }" " var_dump('ok');" " } catch (Exception $e) {" " var_dump($e->getMessage());" " }" "}" "test();"); MVCRO(" array(' . count($params) . \") {\\n\";\n" " foreach ($params as $p) {\n" " echo \" name => {$p->getName()}\\n\";\n" " }\n" " echo \"}\\n\";\n" "}\n" "function show($rf) {\n" " var_dump($rf->getName());\n" " var_dump($rf->isUserDefined());\n" " var_dump($rf->getStartLine());\n" " var_dump($rf->getEndLine());\n" " var_dump($rf->getDocComment());\n" " var_dump($rf->getFileName() === __FILE__);\n" " show_params($rf->getParameters());\n" " var_dump($rf->getNumberOfParameters());\n" " var_dump($rf->getNumberOfRequiredParameters());\n" "}\n" "\n" "$rf = new ReflectionFunction($f);\n" "$rg = new ReflectionFunction($g);\n" "$radd = new ReflectionFunction($add);\n" "\n" "echo \"invoking f\\n\";\n" "$rf->invoke();\n" "\n" "echo \"\\ninvoking g\\n\";\n" "$rg->invoke('hello');\n" "$rg->invokeArgs(array('goodbye'));\n" "\n" "echo \"\\ninvoking add\\n\";\n" "$radd->invoke(1, 2);\n" "$radd->invokeArgs(array(5000000000, 5000000000));\n" "\n" "echo \"\\nshowing f\\n\";\n" "show($rf);\n" "\n" "echo \"\\nshowing g\\n\";\n" "show($rg);\n" "\n" "echo \"\\nshowing add\\n\";\n" "show($radd);\n" , "invoking f\n" "in $f\n" "\n" "invoking g\n" "in $g; passed hello\n" "in $g; passed goodbye\n" "\n" "invoking add\n" "x + y = 3\n" "x + y = 10000000000\n" "\n" "showing f\n" "string(9) \"{closure}\"\n" "bool(true)\n" "int(4)\n" "int(4)\n" "bool(false)\n" "bool(true)\n" "parameters => array(0) {\n" "}\n" "int(0)\n" "int(0)\n" "\n" "showing g\n" "string(9) \"{closure}\"\n" "bool(true)\n" "int(5)\n" "int(5)\n" "bool(false)\n" "bool(true)\n" "parameters => array(1) {\n" " name => a\n" "}\n" "int(1)\n" "int(0)\n" "\n" "showing add\n" "string(9) \"{closure}\"\n" "bool(true)\n" "int(8)\n" "int(11)\n" "string(54) \"/** This doc comment is so helpful and descriptive. */\"\n" "bool(true)\n" "parameters => array(2) {\n" " name => x\n" " name => y\n" "}\n" "int(2)\n" "int(2)\n" ); MVCR("getName()); " " var_dump($func->isInternal()); " " var_dump($func->isUserDefined()); " " var_dump($func->isClosure()); " " $vars = $func->getStaticVariables(); " " var_dump(count($vars));" " var_dump(isset($vars['a']));" " var_dump($func->returnsReference()); " " var_dump($func->getNumberOfParameters()); " " var_dump($func->getNumberOfRequiredParameters()); " " foreach ($func->getParameters() as $name => $param) {" " var_dump($name); " " dump_param($param); " " }" "} " "" "function verify_class($cls) {" " if ($cls) {" " var_dump($cls->getName()); " " } else {" " var_dump(null);" " }" "}" "" "function verify_classes($classes) {" " ksort($classes);" " foreach ($classes as $cls) {" " verify_class($cls); " " }" "}" "" "function dump_param($param) {" " var_dump($param->getName()); " " var_dump($param->isPassedByReference()); " " verify_class($param->getDeclaringClass()); " " verify_class($param->getClass()); " " var_dump($param->isArray()); " " var_dump($param->allowsNull()); " " var_dump($param->isOptional()); " " var_dump($param->isDefaultValueAvailable()); " " if ($param->isOptional()) { " //" var_dump($param->getDefaultValue()); " " } " " var_dump($param->getPosition()); " "} " "" "function dump_prop($prop, $obj) {" " var_dump($prop->getName()); " " var_dump($prop->isPublic()); " " var_dump($prop->isPrivate()); " " var_dump($prop->isProtected()); " " var_dump($prop->isStatic()); " //" var_dump($prop->isDefault()); " " var_dump($prop->getModifiers() & 0xffff); " " if ($prop->isPublic()) { " " var_dump($prop->getValue($obj)); " " if (!$prop->isStatic()) {" " var_dump($prop->setValue($obj, 78)); " " }" " var_dump($prop->getValue($obj)); " " } " " verify_class($prop->getDeclaringClass()); " "} " "" "function dump_class($cls, $obj) {" " var_dump($cls->isInstance($obj)); " " var_dump($cls->getName()); " " var_dump($cls->isInternal()); " " var_dump($cls->isUserDefined()); " " var_dump($cls->isInstantiable()); " " var_dump($cls->hasConstant('CLS_CONST')); " " var_dump($cls->hasMethod('method1')); " " var_dump($cls->hasProperty('prop1')); " " dump_func($cls->getMethod('method1')); " " dump_prop($cls->getProperty('prop1'), $obj); " " verify_classes($cls->getInterfaces()); " " var_dump($cls->isInterface()); " " var_dump($cls->isAbstract()); " " var_dump($cls->isFinal()); " " var_dump($cls->getModifiers() & 0xffff); " " verify_class($cls->getParentClass()); " " var_dump($cls->isSubclassOf('i1')); " " var_dump($cls->getStaticPropertyValue('prop2')); " //" var_dump($cls->setStaticPropertyValue('prop2', 45)); " " cls1::$prop2 = 45; " " var_dump($cls->getStaticPropertyValue('prop2')); " " var_dump(cls1::$prop2); " " var_dump($cls->isIterateable()); " " var_dump($cls->implementsInterface('i2')); " " foreach ($cls->getProperties() as $name => $prop) {" " var_dump($name); " " dump_prop($prop, $obj); " " }" " foreach ($cls->getMethods() as $name => $func) {" " var_dump($name); " " dump_func($func); " " var_dump($func->isFinal()); " " var_dump($func->isAbstract()); " " var_dump($func->isPublic()); " " var_dump($func->isPrivate()); " " var_dump($func->isProtected()); " " var_dump($func->isStatic()); " " var_dump($func->isConstructor()); " " var_dump($func->isDestructor()); " " var_dump($func->getModifiers() & 0xFFFF); " " verify_class($func->getDeclaringClass()); " " if ($name == 'method1') $func->invoke($obj, 'invoked'); " " }" "}" "" // verification "$func = new ReflectionFunction('func1'); " "dump_func($func); " "" "$func = new ReflectionFunction('func2'); " "$func->invoke('invoked');" "" "$cls = new ReflectionClass('cls1'); " "$obj = $cls->newInstance(); " "dump_class($cls, $obj);" "" "$cls = new ReflectionClass('cls2'); " "$obj = $cls->newInstance(); " "dump_class($cls, $obj);" ""); MVCR("getProperty('arr');" " return $p->getValue();" " }" "}" "abstract class aa extends c {" " public function get_arr() {" " $actions = parent::get_arr();" " return $actions;" " }" "}" "class a extends aa {" " public static $arr = array('v');" "}" "$x = new a;" "var_dump($x->g());"); MVCR("getName());" "$r = new ReflectionClass('bbbb');" "var_dump($r->getName());" "$a = new aaaa;" "$a->f();"); MVCR("getConstant(\"bar\"));"); MVCR("getFileName() !== '');" "var_dump($i->getFileName() !== '');"); MVCR("hasMethod('mE'));" "var_dump($ref->hasMethod('me'));" "$m = $ref->getMethod('me');" "var_dump($m->getName());"); MVCR("name);" " }" "}" "$condition = 123;" "if ($condition) {" " class A extends Base {}" "} else {" " class A extends Base {}" "}" "class B extends A {" " function bar() {" " }" "}" "$obj = new B();" "$obj->foo();"); MVCR("implementsInterface('A'));" "$inter = new ReflectionClass('B');" "var_dump($inter->hasMethod('foo'));"); MVCR("getName()); } }\n" "$r = new ReflectionClass('A');\n" "$a = $r->getProperties(); f($a);\n" "$a = $r->getProperties(ReflectionProperty::IS_PUBLIC); f($a);\n" "$a = $r->getProperties(ReflectionProperty::IS_PRIVATE); f($a);\n" "$a = $r->getProperties(ReflectionProperty::IS_PROTECTED); f($a);\n" "$a = $r->getProperties(ReflectionProperty::IS_STATIC); f($a);\n"); { HipHopSyntax w(this); MVCROF( "isClosure()); " "var_dump($rf->isGenerator()); " " " "function is_a_generator() { " " yield 1; " " yield 2; " "}; " "$rf = new ReflectionFunction('is_a_generator'); " "var_dump($rf->isClosure()); " "var_dump($rf->isGenerator()); " " " "$cl = function() { " " return 1; " "}; " "$rf = new ReflectionFunction($cl); " "var_dump($rf->isClosure()); " "var_dump($rf->isGenerator()); " " " "$cl = function() { " " yield 1; " " yield 2; " "}; " "$rf = new ReflectionFunction($cl); " "var_dump($rf->isClosure()); " "var_dump($rf->isGenerator()); " , "test/vm/reflection_isclosure.php.exp" ); } return true; } bool TestCodeRun::TestErrorHandler() { MVCR("getMessage();" " var_dump($msg);" " }" " public static function setup() {" " set_exception_handler(array(__CLASS__, 'log'));" " }" "}" "$obj = new C;" "$obj->setup();" "throw new Exception('test');"); return true; } bool TestCodeRun::TestAssertOptions() { MVCR("a = 1;" "$x->b = 'hello';" "$x->c = $x;" "var_dump(http_build_query($x));"); MVCR(";\\$y=woo!;\\n\";\n" "$arr = token_get_all($str);\n" "foreach ($arr as $t) {\n" " if ($t[0] == 396) {\n" " var_dump($t[1]);\n" " }\n" "}\n" , "string(12) \"T_XHP_TAG_LT\"\n" "string(1) \"<\"\n" "string(1) \"<\"\n" "string(1) \"<\"\n" ); return true; } bool TestCodeRun::TestInvalidArgument() { MVCRO(" 'UTF-8'," " 'line-length' => 76," " 'line-break-chars' => '\n'" ");" "$preferences['scheme'] = 'Q';" "$preferences['input-charset'] = str_pad('invalid-charset', 64);" "var_dump(iconv_mime_encode('Subject', 'Pr\xc3\274fung Pr\xc3\274fung'," " $preferences));" "$preferences['input-charset'] = 'ISO-8859-1';" "$preferences['output-charset'] = str_pad('invalid-charset', 64);" "var_dump(iconv_mime_encode('Subject', 'Pr\xc3\274fung Pr\xc3\274fung'," " $preferences));" "var_dump(iconv_set_encoding('internal_encoding'," " str_pad('invalid-charset', 64)));" "var_dump(iconv('UTF-8', str_pad('invalid-charset', 64), ''));" "var_dump(iconv(str_pad('invalid-charset', 64), 'UTF-8', ''));" "var_dump(time_nanosleep(-1, 0));" "var_dump(time_nanosleep(0, -1));" "var_dump(time_sleep_until(0));" "var_dump(gzcompress('abc', -2));" "var_dump(gzdeflate('abc', -2));" "var_dump(http_build_query(1));" "var_dump(parse_url('http://www.example.com', 100));" "var_dump(dns_check_record('127.0.0.1', 'INVALID_TYPE'));" "var_dump(assert_options(-1));" "var_dump(simplexml_load_string('', 'INVALID_CLASS'));" "var_dump(simplexml_load_string('', 'stdClass'));" "var_dump(stream_get_contents('', -1));" "$fp = fopen('test/test_ext_file.txt', 'r');" "var_dump(fgets($fp, -1));" /* Not handled correctly. Invalid arg /types/ should result in the function not being called, and null returned (even though the functions are documented as returning false on failure). "var_dump(fputcsv($fp, array(), 'abc'));" "var_dump(fputcsv($fp, array(), 'a', 'def'));" "var_dump(fgetcsv($fp, array(), 'abc'));" "var_dump(fgetcsv($fp, array(), 'a', 'def'));" */ "fclose($fp);" "$tmpfname = tempnam('', str_repeat('a', 128));" "var_dump(strlen(basename($tmpfname)));" "unlink($tmpfname);" "$tmpfname = tempnam('', '/var/www' . str_repeat('a', 128));" "var_dump(strlen(basename($tmpfname)));" "unlink($tmpfname);" "$ar1 = array(10, 100, 100, 0);" "$ar2 = array(1, 3, 2);" "var_dump(array_multisort($ar1, $ar2));" "$phrase = 'eat fruits, vegetables, and fiber every day.';" "$healthy = array('fruits', 'vegetables');" "$yummy = array('pizza', 'beer', 'ice cream');" "var_dump(str_replace($healthy, $yummy, $phrase));" "var_dump(str_replace('ll', $yummy, 'good golly miss molly!'," " $count));" "var_dump(setlocale(LC_ALL, array('de_DE@euro', 'de_DE', 'deu_deu')," " array(1, 2)));" "var_dump(setlocale(LC_ALL, str_pad('a', 255)));" "var_dump(pack(\"\\xf4\", 0x1234, 0x5678, 65, 66));" "var_dump(pack(\"x5\", 0x1234, 0x5678, 65, 66));" "var_dump(pack(\"h\", -0x1234));" "var_dump(pack(\"h\", 12345678900));" "var_dump(unpack(\"\\xf4\", \"0x1234\"));" "var_dump(sscanf('foo', '[%s', $id, $first, $last));" "var_dump(sscanf('foo', '%z', $id, $first, $last));" "var_dump(sscanf(\"SN/abc\", \"SN/%d%d\", $out));" "var_dump($out);" "var_dump(sscanf(\"SN/abc\", \"\", $out));" "var_dump($out);" "var_dump(printf('%$', 3));" "var_dump(vsprintf('%$', 3));" "var_dump(sprintf('%$', 3));" "var_dump(vsprintf('%$', 3));" "var_dump(str_word_count('abc', 2, '...'));" "var_dump(str_word_count('abc', 2, 'b..a'));" "var_dump(str_word_count('abc', 2, 'a..b..c'));" "var_dump(base_convert('05678', 8, 37));" "var_dump(convert_cyr_string('abc', 'y', 'z'));" "var_dump(money_format('%abc', 1.33));" "var_dump(money_format('%i%i', 1.33));" "var_dump(str_pad('abc', 10, '', 100));" "var_dump(str_pad('abc', 10, ' ', 100));" "var_dump(wordwrap('', 75, '', true));" "var_dump(wordwrap(null, 75, '', true));" "var_dump(wordwrap('abc', 75, '', true));" "var_dump(wordwrap('abc', 0, '', true));"); MVCR(" 1);" "}" "test();" "var_dump($_POST);"); MVCR(" &$v) {\n" " if ($k == 'a') { $v = -1; }\n" " }\n" " global $a;\n" " var_dump($a);\n" " $b = $GLOBALS;\n" " $b['a'] = 0;\n" " var_dump($GLOBALS['a']);\n" "}\n" "f();\n"); return true; } bool TestCodeRun::TestGlobalStatement() { MVCR("bar();"); MVCR("q;" " echo $foo;" " }" " function y() {" " static $foo = 20;" " $foo++;" " echo $foo;" " }" " static function sf() {" " static $foo = 0;" " $foo++;" " echo $foo;" " }" "}" "class d extends c {" " public $q = 30;" "}" "$x = new c();" "$x->x();" "$x->y();" "$x->y();" "$x->y();" "$x->y();" "$x = new d();" "$x->x();" "$x->y();" "$x->y();" "$x->y();" "c::sf();" "c::sf();" "c::sf();" "d::sf();" "d::sf();" "d::sf();"); MVCR("foo();" " }" "}" "class B extends A {}" "class C extends A {}" "$a = new A;" "$b = new B;" "$c = new C;" "$a->run();" "$b->run();" "$c->run();"); return true; } bool TestCodeRun::TestIfStatement() { MVCR("= 2) continue 2;" " echo \"I : $i J : $j\".\"\\n\";" " }" " echo \"End\\n\";" "}" "for ($i = 0;$i<10;$i++) {" " if ($i % 2 == 0) continue 1;" " echo $i . \"\\n\";" "}" "for ($i = 0;$i<10;$i++) {" " if ($i % 2 == 0) continue;" " echo $i . \"\\n\";" "}"); MVCR(" 1) return;" " if ($a == 1) return 1;" "}" "function foo3($a) {" " if ($a > 1) return;" " if ($a == 1) return;" "}" "function bar() {" " $v1 = foo1(0);" " var_dump($v1);" " $v2 = foo2(0);" " var_dump($v2);" " $v3 = foo3(0);" " var_dump($v3);" "}" "bar();"); MVCR(" 1));" \ #op"(array(\"\\0\" => \"\\0\"));" \ #op"(array(\"\\0\" => \"\\\\\"));" \ #op"(array(\"\\0\" => \"\\'\"));" \ #op"(array(\"\\\\\" => 1));" \ #op"(array(\"\\\\\" => \"\\0\"));" \ #op"(array(\"\\\\\" => \"\\\\\"));" \ #op"(array(\"\\\\\" => \"\\'\"));" \ #op"(array(\"\\'\" => 1));" \ #op"(array(\"\\'\" => \"\\0\"));" \ #op"(array(\"\\'\" => \"\\\\\"));" \ #op"(array(\"\\'\" => \"\\'\"));" \ #op"(array(\"\\a\" => \"\\a\"));" \ #op"(!array(\"\\0\" => \"\\0\"));" \ #op"((array(\"\\0\" => \"\\0\")));" \ #op"((int)array(\"\\0\" => \"\\0\"));" \ #op"((integer)array(\"\\0\" => \"\\0\"));" \ #op"((bool)array(\"\\0\" => \"\\0\"));" \ #op"((boolean)array(\"\\0\" => \"\\0\"));" \ #op"((float)array(\"\\0\" => \"\\0\"));" \ #op"((double)array(\"\\0\" => \"\\0\"));" \ #op"((real)array(\"\\0\" => \"\\0\"));" \ #op"((string)array(\"\\0\" => \"\\0\"));" \ "$a = \"0x10\";" \ #op"($a);" \ #op"(\"\\0\");" \ "$a = array(\"\\0\" => 1);" \ #op"($a);" \ "$a = array(\"\\0\" => \"\\0\");" \ #op"($a);" \ "$a = array(\"\\0\" => \"\\\\\");" \ #op"($a);" \ "$a = array(\"\\0\" => \"\\'\");" \ #op"($a);" \ "$a = array(\"\\\\\" => 1);" \ #op"($a);" \ "$a = array(\"\\\\\" => \"\\0\");" \ #op"($a);" \ "$a = array(\"\\\\\" => \"\\\\\");" \ #op"($a);" \ "$a = array(\"\\\\\" => \"\\'\");" \ #op"($a);" \ "$a = array(\"\\'\" => 1);" \ #op"($a);" \ "$a = array(\"\\'\" => \"\\0\");" \ #op"($a);" \ "$a = array(\"\\'\" => \"\\\\\");" \ #op"($a);" \ "$a = array(\"\\'\" => \"\\'\");" \ #op"($a);" \ "$a = array(\"\\a\" => \"\\a\");" \ #op"($a);" #define UNARY_OP(op) \ MVCR(UNARY_OP_DATA(op)) \ MVCR(UNARY_OP_ARRAY_DATA(op)) bool TestCodeRun::TestUnaryOperators() { UNARY_OP(var_dump); MVCR("\");"); return true; } bool TestCodeRun::TestPrint() { UNARY_OP(echo); UNARY_OP(print); UNARY_OP(print_r); UNARY_OP(serialize); return true; } bool TestCodeRun::TestVarExport() { MVCR(UNARY_OP_DATA(var_export)); MVCRO(UNARY_OP_ARRAY_DATA(var_export), "array (\n" " '' . \"\\0\" . '' => 1,\n" ")array (\n" " '' . \"\\0\" . '' => '' . \"\\0\" . '',\n" ")array (\n" " '' . \"\\0\" . '' => '\\\\',\n" ")array (\n" " '' . \"\\0\" . '' => '\\\\\\\'',\n" ")array (\n" " '\\\\' => 1,\n" ")array (\n" " '\\\\' => '' . \"\\0\" . '',\n" ")array (\n" " '\\\\' => '\\\\',\n" ")array (\n" " '\\\\' => '\\\\\\\'',\n" ")array (\n" " '\\\\\\\'' => 1,\n" ")array (\n" " '\\\\\\\'' => '' . \"\\0\" . '',\n" ")array (\n" " '\\\\\\\'' => '\\\\',\n" ")array (\n" " '\\\\\\\'' => '\\\\\\\'',\n" ")array (\n" " '\\\\a' => '\\\\a',\n" ")falsearray (\n" " '' . \"\\0\" . '' => '' . \"\\0\" . '',\n" ")11truetrue111'Array''0x10''' . \"\\0\" . ''array (\n" " '' . \"\\0\" . '' => 1,\n" ")array (\n" " '' . \"\\0\" . '' => '' . \"\\0\" . '',\n" ")array (\n" " '' . \"\\0\" . '' => '\\\\',\n" ")array (\n" " '' . \"\\0\" . '' => '\\\\\\\'',\n" ")array (\n" " '\\\\' => 1,\n" ")array (\n" " '\\\\' => '' . \"\\0\" . '',\n" ")array (\n" " '\\\\' => '\\\\',\n" ")array (\n" " '\\\\' => '\\\\\\\'',\n" ")array (\n" " '\\\\\\\'' => 1,\n" ")array (\n" " '\\\\\\\'' => '' . \"\\0\" . '',\n" ")array (\n" " '\\\\\\\'' => '\\\\',\n" ")array (\n" " '\\\\\\\'' => '\\\\\\\'',\n" ")array (\n" " '\\\\a' => '\\\\a',\n" ")"); return true; } bool TestCodeRun::TestLocale() { MVCRO("a;}} " "$a = new A; $a->a = 'a'; $b = new A; $b->a = 'b'; " "$arr = array($a, $b); sort($arr, SORT_REGULAR, true); " "print ((string)$arr[0]);", "a"); MVCRO("a = 'a'; $b = new A; $b->a = 'b'; " "$arr = array($b, $a);" "print $arr[0]->a;" "sort($arr, SORT_REGULAR, true); " "print $arr[0]->a;", "ba"); MVCRO("bar();" "$f2->bar();" "var_dump(get_class(\"qwerty\"));" "var_dump(get_class($f1));" "var_dump(get_class($f2));" ); MVCR("test();" "$bar->test();" "$bar->test_bar();" "$goo->test();" "$goo->test_bar();" "$goo->test_goo();" "var_dump(get_parent_class($bar));" "var_dump(get_parent_class($foo));" "var_dump(get_parent_class($goo));" "var_dump(get_parent_class(\"bar\"));" "var_dump(get_parent_class(\"foo\"));" "var_dump(get_parent_class(\"goo\"));" "var_dump(get_parent_class(\"i\"));" "var_dump(get_parent_class(\"\"));" "var_dump(get_parent_class(\"[[[[\"));" "var_dump(get_parent_class(\" \"));" "var_dump(get_parent_class(new stdclass));" "var_dump(get_parent_class(array()));" "var_dump(get_parent_class(1));" ); return true; } bool TestCodeRun::TestRedeclaredFunctions() { MVCR("getCode());\n" " }\n" "}\n" "foo();\n" ); MVCR("childProp; }" " function testChildMeth() { return $this->childMeth(); }" " static function baseStatMeth() {" " return 'Base static method';" " }" " function childMeth() { return 'I am base'; }" " }" "} else {" " class base {" " }" "}" "class child1 extends base {" " public $child1Val = 'child1';" " public $childProp = 'IamChild1';" " static $child1Static = 'child1Stat';" " function childMeth() {" " return 'I am child1';" " }" " static function child1StatMeth() {" " return 'Child 1 static method';" " }" " function parentChildMeth() {" " return parent::childMeth();" " }" "}" "class child2 extends child1 {" " public $child2Val = 'child2';" " public $childProp = 'IamChild2';" " static $child2Static = 'child2Stat';" " static function child2StatMeth() {" " return 'Child 2 static method';" " }" " function childMeth() {" " return 'I am child2';" " }" " function parentChildMeth() {" " return parent::childMeth();" " }" " function testChildMeth2() { return $this->childMeth(); }" "}" "if (true) {" " class child3 extends child2 {" " public $child3Val = 'child3';" " public $childProp = 'IamChild3';" " static $child3Static = 'child3Stat';" " function childMeth() {" " return 'I am child3';" " }" " static function child3StatMeth() {" " return 'Child 3 static method';" " }" " function parentChildMeth() {" " return parent::childMeth();" " }" "" " }" "} else {" " class child3 {}" "}" "function test($val, $exp, $feature) {" " if ($val !== $exp) {" " echo $feature . \" failed. Got:\\n\";" " var_dump($val);" " echo \"But expected:\\n\";" " var_dump($exp);" " } else {" " echo $feature . \" passed\\n\";" " }" "}" "function run() {" " $base = new base;" " test($base->baseVal, 'base', 'Base object member');" " test(base::$baseStatic, 'baseStat', 'Base static member');" " test(base::baseStatMeth(), 'Base static method', 'Base static method');" " test($base->baseStatMeth(), 'Base static method', 'Base static method obj syntax');" " $child1 = new child1;" " test($child1->baseVal, 'base', 'dRedec inherited property');" " test($child1->child1Val, 'child1', 'dRedec property');" " test($child1->testChildMeth(), 'I am child1', 'dRedec parent->virtual method');" " test($child1->childProp(), 'IamChild1', 'dRedec parent->child prop method');" " test(child1::child1StatMeth(), 'Child 1 static method', 'dRedec static method');" " test(child1::baseStatMeth(), 'Base static method', 'dRedec parent static method');" " test($child1->child1StatMeth(), 'Child 1 static method', 'dRedec static method obj syntax');" " test($child1->baseStatMeth(), 'Base static method', 'dRedec parent static method obj syntax');" " test(child1::$baseStatic, 'baseStat', 'dRedec parent static prop');" " test(child1::$child1Static, 'child1Stat', 'dRedec static prop');" " test($child1->parentChildMeth(), 'I am base', 'dRedec parent method');" " $child2 = new child2;" " test($child2->baseVal, 'base', 'ddRedec grandparent property');" " test($child2->child1Val, 'child1', 'ddRedec parent property');" " test($child2->child2Val, 'child2', 'ddRedec property');" " test($child2->testChildMeth(), 'I am child2', 'ddRedec grandparent->virtual method');" " test($child2->testChildMeth2(), 'I am child2', 'ddRedec parent->virtual method');" " test($child2->childProp(), 'IamChild2', 'ddRedec grandparent->child prop method');" " test(child2::baseStatMeth(), 'Base static method', 'ddRedec grandparent static method');" " test(child2::child1StatMeth(), 'Child 1 static method', 'ddRedec parent static method');" " test(child2::child2StatMeth(), 'Child 2 static method', 'ddRedec static method');" " test($child2->baseStatMeth(), 'Base static method', 'ddRedec grandparent static method obj syntax');" " test($child2->child1StatMeth(), 'Child 1 static method', 'ddRedec parent static method obj syntax');" " test($child2->child2StatMeth(), 'Child 2 static method', 'ddRedec static method obj syntax');" " test(child2::$baseStatic, 'baseStat', 'ddRedec grandparent static prop');" " test(child2::$child1Static, 'child1Stat', 'ddRedec parent static prop');" " test(child2::$child2Static, 'child2Stat', 'ddRedec static prop');" " test($child2->parentChildMeth(), 'I am child1', 'ddRedec parent method');" " $child3 = new child3;" " test($child3->baseVal, 'base', 'RddRedec greatgrandparent property');" " test($child3->child1Val, 'child1', 'RddRedec grandparent property');" " test($child3->child2Val, 'child2', 'RddRedec parent property');" " test($child3->child3Val, 'child3', 'RddRedec property');" " test($child3->testChildMeth(), 'I am child3', 'RddRedec greatgrandparent->virtual method');" " test($child3->testChildMeth2(), 'I am child3', 'RddRedec grandparent->virtual method');" " test($child3->childProp(), 'IamChild3', 'RddRedec greatgrandparent->child prop method');" " test(child3::baseStatMeth(), 'Base static method', 'RddRedec greatgrandparent static method');" " test(child3::child1StatMeth(), 'Child 1 static method', 'RddRedec grandparent static method');" " test(child3::child2StatMeth(), 'Child 2 static method', 'RddRedec parent static method');" " test(child3::child3StatMeth(), 'Child 3 static method', 'RddRedec static method');" " test($child3->baseStatMeth(), 'Base static method', 'RddRedec greatgrandparent static method obj syntax');" " test($child3->child1StatMeth(), 'Child 1 static method', 'RddRedec grandparent static method obj syntax');" " test($child3->child2StatMeth(), 'Child 2 static method', 'RddRedec parent static method obj syntax');" " test($child3->child3StatMeth(), 'Child 3 static method', 'RddRedec static method obj syntax');" " test(child3::$baseStatic, 'baseStat', 'RddRedec greatgrandparent static prop');" " test(child3::$child1Static, 'child1Stat', 'RddRedec grandparent static prop');" " test(child3::$child2Static, 'child2Stat', 'RddRedec parent static prop');" " test(child3::$child3Static, 'child3Stat', 'RddRedec static prop');" " test($child3->parentChildMeth(), 'I am child2', 'RddRedec parent method');" "}" "run();" ); MVCR("foo();" "$t->bar();"); MVCR("foo();" "$t->bar();"); MVCR("a, '\n';" "}} test();"); MVCR("bar();" " $x = new V;" " $x->bar();" "}" "test();"); MVCR("foo + $this->bar; }" "}" "class D2 extends D1 {" " public $foo;" " private $bar;" " function bar() { return $this->foo + $this->bar; }" "}" "PEAR::f();"); MVCR("bar = 1;" "$x->foo = 2;" "var_dump($x);"); MVCR("out(A::fun()); }" " public function out($arg) { var_dump($arg); }" "}" "$c = new C();" "$c->foo();"); MVCR("x();" " }" " function y() {" " echo 'y';" " }" "}" "class c extends b {" " function x() {" " $this->y();" " }" "}" "if (false) {" " class b{}" " class c{}" "}" "$x = new c();" "$x->z();"); MVCR("meh()->work();" "}" "test();"); MVCR("t = 5;" " $x->a = 3;" " $y = clone $x;" " var_dump($y->a,$y->t);" "}" "test();"); MVCR("a = 2; }" " }" "} else {" " class A {" " protected $a = 1;" " }" " class B extends A {" " public $a;" " function f() { $this->a = 2; }" " }" "}" "$obj = new B;" "$obj->f();" "var_dump($obj);"); MVCR(" $v) {" " var_dump($v);" " }" " }" "}" "$x = new d;" "$x->t2();"); MVCR(" 2, 2 => 3); " "foreach ($myarray as $this => $wat) {" " echo \"You should not see this\"; " "}", ""); MVCRONW(" 2, 2 => 3); " "foreach ($myarray as $a => $this) {" " echo \"You should not see this\"; " "}", ""); return true; } bool TestCodeRun::TestClone() { MVCR("foo = 'foo';" "$a1->fooref = &$p;" "$a1->dyn = 'dyn';" "$a1->dynref = &$q;" "var_dump($a1);" "$a2 = clone $a1;" "var_dump($a1);" "var_dump($a2);" "$a2->foo = 'a2foo';" "$a2->fooref = 'a2fooref';" "$a2->dyn = 'a2dyn';" "$a2->dynref = 'a2dynref';" "$a2->dynref2 = 'dynref2';" "var_dump($a1);" "var_dump($a2);" "var_dump($p);" "var_dump($q);"); MVCR("cm);" " }" "}" "class c2 extends c {}" "$y = new c;" "$y->x();" "$z = clone $y;" "$z->x();" "$y = new c2;" "$y->x();" "$z = clone $y;" "$z->x();"); return true; } bool TestCodeRun::TestEvalOrder() { MVCRO("foo(var_dump('123'));\n" "var_dump('end');\n" "function h() { var_dump('errored');}", "string(7) \"errored\"\n"); MVCR(" $x) { " " var_dump($x); " "}"); MVCR("var = $array;\n" " }\n" " }\n" " public function rewind() {\n" " echo \"rewinding\n\";\n" " reset($this->var);\n" " }\n" " public function current() {\n" " $var = current($this->var);\n" " echo \"current: $var\n\";\n" " return $var;\n" " }\n" " public function key() {\n" " $var = key($this->var);\n" " echo \"key: $var\n\";\n" " return $var;\n" " }\n" " public function next() {\n" " $var = next($this->var);\n" " echo \"next: $var\n\";\n" " return $var;\n" " }\n" " public function valid() {\n" " $var = $this->current() !== false;\n" " echo \"valid: \",$var?'true':'false',\"\n\";\n" " return $var;\n" " }\n" "}\n" "\n" "function f() { var_dump('f'); return 0; }\n" "function g() { var_dump('g'); return 0; }\n" "\n" "$a = array(1, 2);\n" "$values = array('a' => 1, 'b' => 2, 'c' => 3);\n" "$it = new MyIterator($values);\n" "foreach ($it as $a[f()] => $a[g()]) {\n" " print \"$a[0]\n\";\n" "}\n"); MVCR("a[foo()]->y); "); MVCR("foo = 9;" " $this->bar = '3';" " return $this;" " }" "}" "$a = new A();" "var_dump($a->q('1')->foo + $a->q('2')->bar);" "var_dump($a->q('1')->foo - $a->q('2')->bar);" "var_dump($a->q('1')->foo / $a->q('2')->bar);" "var_dump($a->q('1')->foo * $a->q('2')->bar);" "var_dump($a->q('1')->foo % $a->q('2')->bar);" "var_dump($a->q('1')->foo << $a->q('2')->bar);" "var_dump($a->q('1')->foo >> $a->q('2')->bar);" "var_dump($a->q('1')->foo && $a->q('2')->bar);" "var_dump($a->q('1')->foo || $a->q('2')->bar);" "var_dump($a->q('1')->foo and $a->q('2')->bar);" "var_dump($a->q('1')->foo or $a->q('2')->bar);" "var_dump($a->q('1')->foo xor $a->q('2')->bar);" "var_dump($a->q('1')->foo . $a->q('2')->bar);" "var_dump($a->q('1')->foo & $a->q('2')->bar);" "var_dump($a->q('1')->foo | $a->q('2')->bar);" "var_dump($a->q('1')->foo ^ $a->q('2')->bar);" "var_dump($a->q('1')->foo == $a->q('2')->bar);" "var_dump($a->q('1')->foo === $a->q('2')->bar);" "var_dump($a->q('1')->foo != $a->q('2')->bar);" "var_dump($a->q('1')->foo !== $a->q('2')->bar);" "var_dump($a->q('1')->foo > $a->q('2')->bar);" "var_dump($a->q('1')->foo >= $a->q('2')->bar);" "var_dump($a->q('1')->foo < $a->q('2')->bar);" "var_dump($a->q('1')->foo <= $a->q('2')->bar);" ); MVCR("f(p(1), p(2), p(3), 4);" "echo \"rsfc\n\";" "rt($a, id(10));" "var_dump($a);" "dump($v++, $v++);" "$v = 10;" "dump($v, $v = 0);" "echo \"nest\n\";" "x(p(1), x(p(2), p(3), p(4), p(5)), p(6), x(p(7), p(8), p(9), p(10)));" "echo \"arr\n\";" "$z = array(p(1), p(2), x(p(3), p(4), p(5), p(6)), p(7));" "$q = 1;" "$z = array(1, 2, $q);" ); MVCR("f(pid('arg1'),pid('arg2'));" " }" "}" "$d = id1(new cls())" " ->f('arg1')" " ->f('arg2')" " ->f('arg3');" "$d = id1(new cls())" " ->f('arg1', 'argex1')" " ->f('arg2', 'argex2')" " ->f('arg3', 'argex3');" "$d = id(new cls(), pid('idarg'))" " ->f(pid('arg1'), pid('argex1'))" " ->f(pid('arg2'), pid('argex2'))" " ->f(pid('arg3'), pid('argex3'));" "$d->ttest();"); MVCR("r($x);" "var_dump($x);"); MVCR("x(3, p(1), p(2))->x(6, p(4), p(5));"); MVCR("val = $v;" " }" " public function blah() {" " return $this;" " }" "}" "class A {" " public $v;" " function set($v) {" " $this->v = $v;" " return $this;" " }" "}" "function id($x) { return $x; }" "$x = new Q(0);" "$a = id(new A)->set($x);" "$x = id(new Q(1))->blah();" "var_dump($a);"); MVCR("f, $a->g); var_dump($a);\n" "}\n" "test();\n"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C\\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "function f() {" " echo \"f()\\n\";" " return 1;" "}" "function foo() {" " $obj = new C;" " $obj->a = f();" " $obj->b = new C;" " $obj->b->a = f();" "}" "foo();"); MVCR("data[$name];" " }" " public function offsetSet($name, $value) {" " $a = serialize($value);" " echo \"offsetSet: $name=$a\\n\";" " $this->data[$name]=$value;" " }" " public function offsetExists($name) {" " echo \"offsetExists: $name\\n\"; return true;" " }" " public function offsetUnset($name) {" " echo \"offsetUnset: $name\\n\";" " }" "}" "function f() {" " echo \"f()\\n\";" " return 1;" "}" "function f2() {" " echo \"f2()\\n\";" " return 'foo';" "}" "function foo($a) {" " $a['foo'] = new C;" " $a['foo']['bar'] = new C;" " $a['foo']['bar']['goo'] = f();" "}" "foo(new C);"); MVCR(" &$v);" " return $a;" "}" "function goo($v) {" " return $v . 1;" "}" "var_dump(foo('1.0'));" "var_dump(foo(foo('1.0')));" "var_dump(foo(goo('1.0')));"); MVCR("prop = 5;" " return 0;" "}" "$a = new stdclass;" "$a->prop = 2;" "var_dump($a->prop . k($a));" "$a = new stdclass;" "$a->prop = 2;" "var_dump(($a->prop . '') . k($a));" "$i = 0;" "var_dump($i . ++$i);" "$i = 0;" "var_dump(($i . '') . ++$i);" "function foo() {" " return 'foo';" "}" "f($a, 'test');" "var_dump(($a . 'x') . foo($a = ''));" "$a = array(2);" "var_dump($a[$a = 0]);" "$a = new stdclass;" "$a->foo = 42;" "var_dump($a->{$a = 'foo'});" "var_dump($a);" "$b = new stdclass;" "$a = null;" "$a->{f($a,$b)} = 5;" "var_dump($a, $b);" "function dump($a, $b) {" " var_dump($a, $b);" "}" "f($a, 'foo');" "dump($a, $a = 'bar');" "$a = 'foo';" "dump($a, $a = 'bar');" "f($a, 'foo');" "dump($a.'', $a = 'bar');" "f($a, 'foo');" "dump($a.$a, $a = 'bar');"); MVCR("{$n} = $v;" " echo 'set:'; var_dump($n, $v);" " }" " function OffsetExists($n) { return $n == 'foo'; }" " function OffsetUnset($n) {}" " function __get($n) { return $this->OffsetGet($n); }" " function __set($n,$v) { return $this->OffsetSet($n, $v); }" "}" "$a = new X;" "function ref(&$a, &$b, &$c) {" "}" "function test() {" " global $a;" " $a[f(0)]->{f(1)}[f(2)] = $a[f(3)][f(4)][f(5)]->foo;" " var_dump($a[f(6)]['fuz'] . f(7));" " ref($a[f(10)][f(11)][f(12)],$a[f(20)][f(21)][f(22)]," " $a[f(30)][f(31)][f(32)]);" " $a->{f(0)}[f(1)]->{f(2)} = $a->{f(3)}->{f(4)}->bar;" "}" "test();"); MVCR("foo($x = null);" " $y($y = null);" "}" "test(new X, 'y');"); MVCR(" $x[$a = 'foo']);" " return $a;" "}" "var_dump(test(array('foo' => 5)));"); MVCR("\n" " string(1) \"T\"\n" "}\n" "bool(true)\n" ); return true; } bool TestCodeRun::TestGetObjectVars() { MVCR("foo($child_obj);" "$unrelated_obj->foo($base_obj);" ); MVCR("foo($child_obj);" ); MVCR("foo($base_obj);" ); MVCR("foo($base_obj);" ); MVCR(" 'apple', 'b' => 'banana'));\n" " }\n" " public function unserialize($serialized) {\n" " $props = unserialize($serialized);\n" " $this->a = $props['a'];\n" " $this->b = $props['b'];\n" " }\n" "} $obj = unserialize(serialize(new A())); var_dump($obj->b);"); MVCR("name = 'foo'.$n;" " $this->num = 3*$n;" " }" "}" "class Big {" " public $groupAll = array();" " public $group1 = array();" " public $group2 = array();" " public $wacky;" " public $nothing;" " public $unrelated = array();" " function add() {" " $s = new Small();" " $this->groupAll[] = $s;" " if ($s->num % 2 == 0) {" " $this->group1[]=array($s->name, $s);" " } else {" " $this->group2[]=array($s->name, $s);" " }" " }" " function finish() {" " $x = 10;" " $this->wacky = array(&$x, &$x);" " $s = new Small();" " $this->unrelated[] = $s;" " $this->unrelated[] = $s;" " $this->unrelated[] = $s;" " }" "}" "function t() {" " $b = new Big;" " for ($i = 0; $i < 10; ++$i) {" " $b->add();" " }" " $b->finish();" " var_dump($b);" " $s = serialize($b);" " var_dump($s);" " $us = unserialize($s);" " var_dump($us);" "}" "t();" ); MVCR("foo = 100;" "var_dump((array)$x);" "var_dump(serialize($x));" "var_dump($x);"); // Zend PHP 5.2 has a bug here, fixed in 5.3. MVCR("\n" " string(3) \"foo\"\n" "}\n" "bool(false)\n" "bool(false)\n"); MVCR("prot,$x->priv);"); MVCR("priv = $a;" " $this->prot = $b;" " $this->pub = $c;" " }" " function foo() { var_dump($this->priv, $this->prot, $this->pub); }" "}" "$x = new X(1,2,3);" "$s = serialize($x);" "$x = unserialize($s);" "var_dump($x);" "$x->foo();"); MVCR("foo = &$q;" "for ($i = 0; $i < 10; $i++) $a->{'x'.$i} = clone $a;" "$a->bar = &$q;" "$s = serialize($a);" "var_dump($s);" "$A = unserialize($s);" "var_dump($A);" "$r = &$A->bar;" "var_dump(array_keys($r));"); MVCR("str = 'hello';" " $this->arr = array(1,2,3);" " $this->obj = $this;" " }" "}" "function test() {" " $x = new X;" " $s = serialize($x);" " $x = unserialize($s);" " var_dump($x);" "}" "test();"); return true; } bool TestCodeRun::TestJson() { MVCR("aaaa();"); // recursive object MVCR("foo = $foo;\n" "var_dump(json_encode($foo));\n"); #if 0 MVCR("1, \"2\"=>2);" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(1);" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(\"1\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(1, \"2\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(1);" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(1, \"2\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(1);" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(1, \"2\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(1);" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\");" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(1, \"2\");" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(1);" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(1, \"2\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(1);" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(1, \"2\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(1);" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(1, \"2\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode(&$a));"); #endif return true; } bool TestCodeRun::TestThrift() { MVCRO("t = new DummyTransport();" " }" " function getTransport() {" " return $this->t;" " }" "}" "class DummyTransport {" " public $buff = '';" " public $pos = 0;" " function flush() { }" " function write($buff) {" " $this->buff .= $buff;" " }" " function read($n) {" " $r = substr($this->buff, $this->pos, $n);" " $this->pos += $n;" " return $r;" " }" "}" "class TestStruct {" " static $_TSPEC;" "" " public $aBool = null;" " public $anInt = null;" " public $aString = null;" " public $aDouble = null;" " public $anInt64 = null;" " public $aList = null;" " public $aMap = null;" " public $aSet = null;" " public $anByte = null;" " public $anI16 = null;" "" " public function __construct($vals=null) {" " if (!isset(self::$_TSPEC)) {" " self::$_TSPEC = array(" " -1 => array(" " 'var' => 'aBool'," " 'type' => TType::BOOL," " )," " 1 => array(" " 'var' => 'anInt'," " 'type' => TType::I32," " )," " 2 => array(" " 'var' => 'aString'," " 'type' => TType::STRING," " )," " 3 => array(" " 'var' => 'aDouble'," " 'type' => TType::DOUBLE," " )," " 4 => array(" " 'var' => 'anInt64'," " 'type' => TType::I64," " )," " 5 => array(" " 'var' => 'aList'," " 'type' => TType::LST," " 'etype' => TType::DOUBLE," " 'elem' => array(" " 'type' => TType::DOUBLE," " )," " )," " 6 => array(" " 'var' => 'aMap'," " 'type' => TType::MAP," " 'ktype' => TType::I32," " 'vtype' => TType::DOUBLE," " 'key' => array(" " 'type' => TType::I32," " )," " 'val' => array(" " 'type' => TType::DOUBLE," " )," " )," " 7 => array(" " 'var' => 'aSet'," " 'type' => TType::SET," " 'etype' => TType::I32," " 'elem' => array(" " 'type' => TType::I32," " )," " )," " 8 => array(" " 'var' => 'anByte'," " 'type' => TType::BYTE," " )," " 9 => array(" " 'var' => 'anI16'," " 'type' => TType::I16," " )," " );" " }" " }" "}" "" "function test() {" " $p = new DummyProtocol();" " $v1 = new TestStruct();" " $v1->aBool = true;" " $v1->anInt = 1234;" " $v1->aString = 'abcdef';" " $v1->aDouble = 1.2345;" " $v1->anInt64 = 8589934592;" " $v1->aList = array(13.3, 23.4, 3576.2);" " $v1->aMap = array(10=>1.2, 43=>5.33);" " $v1->aSet = array(10=>true, 11=>true);" " $v1->anByte = 123;" " $v1->anI16 = 1234;" " var_dump($v1);" " thrift_protocol_write_binary($p, 'foomethod', 1, $v1, 20, true);" " var_dump(md5($p->getTransport()->buff));" " var_dump(thrift_protocol_read_binary($p, 'TestStruct', true));" "}" "test();" , "object(TestStruct)#3 (10) {\n" " [\"aBool\"]=>\n" " bool(true)\n" " [\"anInt\"]=>\n" " int(1234)\n" " [\"aString\"]=>\n" " string(6) \"abcdef\"\n" " [\"aDouble\"]=>\n" " float(1.2345)\n" " [\"anInt64\"]=>\n" " int(8589934592)\n" " [\"aList\"]=>\n" " array(3) {\n" " [0]=>\n" " float(13.3)\n" " [1]=>\n" " float(23.4)\n" " [2]=>\n" " float(3576.2)\n" " }\n" " [\"aMap\"]=>\n" " array(2) {\n" " [10]=>\n" " float(1.2)\n" " [43]=>\n" " float(5.33)\n" " }\n" " [\"aSet\"]=>\n" " array(2) {\n" " [10]=>\n" " bool(true)\n" " [11]=>\n" " bool(true)\n" " }\n" " [\"anByte\"]=>\n" " int(123)\n" " [\"anI16\"]=>\n" " int(1234)\n" "}\n" "string(32) \"6b4fbe9563551f3dee970a74b883f923\"\n" "object(TestStruct)#4 (10) {\n" " [\"aBool\"]=>\n" " bool(true)\n" " [\"anInt\"]=>\n" " int(1234)\n" " [\"aString\"]=>\n" " string(6) \"abcdef\"\n" " [\"aDouble\"]=>\n" " float(1.2345)\n" " [\"anInt64\"]=>\n" " int(8589934592)\n" " [\"aList\"]=>\n" " array(3) {\n" " [0]=>\n" " float(13.3)\n" " [1]=>\n" " float(23.4)\n" " [2]=>\n" " float(3576.2)\n" " }\n" " [\"aMap\"]=>\n" " array(2) {\n" " [10]=>\n" " float(1.2)\n" " [43]=>\n" " float(5.33)\n" " }\n" " [\"aSet\"]=>\n" " array(2) {\n" " [10]=>\n" " bool(true)\n" " [11]=>\n" " bool(true)\n" " }\n" " [\"anByte\"]=>\n" " int(123)\n" " [\"anI16\"]=>\n" " int(1234)\n" "}\n"); MVCRO( "t = new DummyTransport();" " }" " function getTransport() {" " return $this->t;" " }" "}" "class DummyTransport {" " public $buff = '';" " public $pos = 0;" " function flush() { }" " function write($buff) {" " $this->buff .= $buff;" " }" " function read($n) {" " $r = substr($this->buff, $this->pos, $n);" " $this->pos += $n;" " return $r;" " }" "}" "class TestStruct {" " static $_TSPEC;" "" " public $aBool = null;" " public $anInt = null;" " public $aDouble = null;" " public $anInt64 = null;" " public $anByte = null;" " public $anI16 = null;" "" " public function __construct($vals=null) {" " if (!isset(self::$_TSPEC)) {" " self::$_TSPEC = array(" " -1 => array(" " 'var' => 'aBool'," " 'type' => TType::BOOL," " )," " 1 => array(" " 'var' => 'anInt'," " 'type' => TType::I32," " )," " 2 => array(" " 'var' => 'aDouble'," " 'type' => TType::DOUBLE," " )," " 3 => array(" " 'var' => 'anInt64'," " 'type' => TType::I64," " )," " 4 => array(" " 'var' => 'anByte'," " 'type' => TType::BYTE," " )," " 5 => array(" " 'var' => 'anI16'," " 'type' => TType::I16," " )," " );" " }" " }" "}" "" "function test() {" " $p = new DummyProtocol();" " $v1 = new TestStruct();" " $v1->aBool = false;" " $v1->anInt = -1234;" " $v1->aDouble = -1.2345;" " $v1->anInt64 = -1;" " $v1->anByte = -12;" " $v1->anI16 = -123;" " thrift_protocol_write_binary($p, 'foomethod', 1, $v1, 20, true);" " var_dump(thrift_protocol_read_binary($p, 'TestStruct', true));" "}" "test();", "object(TestStruct)#4 (6) {\n" " [\"aBool\"]=>\n" " bool(false)\n" " [\"anInt\"]=>\n" " int(-1234)\n" " [\"aDouble\"]=>\n" " float(-1.2345)\n" " [\"anInt64\"]=>\n" " int(-1)\n" " [\"anByte\"]=>\n" " int(-12)\n" " [\"anI16\"]=>\n" " int(-123)\n" "}\n"); MVCRO( "t = new DummyTransport();" " }" " function getTransport() {" " return $this->t;" " }" "} " "class DummyTransport {" " public $buff = '';" " public $pos = 0;" " function flush() { }" " function write($buff) {" " $this->buff .= $buff;" " } " " function read($n) {" " $r = substr($this->buff, $this->pos, $n);" " $this->pos += $n;" " return $r;" " } " "} " "class TestStruct {" " static $_TSPEC;" " " " public $aBool = null;" " public $anInt = null;" " public $aString = null;" " public $aDouble = null;" " public $anInt64 = null;" " public $aList = null;" " public $aMap = null;" " public $aSet = null;" " public $anByte = null;" " public $anI16 = null;" " " " public function __construct($vals=null) {" " if (!isset(self::$_TSPEC)) {" " self::$_TSPEC = array(" " -1 => array(" " 'var' => 'aBool'," " 'type' => TType::BOOL," " )," " 1 => array(" " 'var' => 'anInt'," " 'type' => TType::I32," " )," " 2 => array(" " 'var' => 'aString'," " 'type' => TType::STRING," " )," " 3 => array(" " 'var' => 'aDouble'," " 'type' => TType::DOUBLE," " )," " 4 => array(" " 'var' => 'anInt64'," " 'type' => TType::I64," " )," " 5 => array(" " 'var' => 'aList'," " 'type' => TType::LST," " 'etype' => TType::DOUBLE," " 'elem' => array(" " 'type' => TType::DOUBLE," " )," " )," " 6 => array(" " 'var' => 'aMap'," " 'type' => TType::MAP," " 'ktype' => TType::I32," " 'vtype' => TType::DOUBLE," " 'key' => array(" " 'type' => TType::I32," " )," " 'val' => array(" " 'type' => TType::DOUBLE," " )," " )," " 7 => array(" " 'var' => 'aSet'," " 'type' => TType::SET," " 'etype' => TType::I32," " 'elem' => array(" " 'type' => TType::I32," " )," " )," " 8 => array(" " 'var' => 'anByte'," " 'type' => TType::BYTE," " )," " 9 => array(" " 'var' => 'anI16'," " 'type' => TType::I16," " )," " );" " }" " }" "}" "" "function test() {" " $p = new DummyProtocol();" " $v1 = new TestStruct();" " $v1->aBool = true;" " $v1->anInt = 1234;" " $v1->aString = 'abcdef';" " $v1->aDouble = 1.2345;" " $v1->anInt64 = 8589934592;" " $v1->aList = array(13.3, 23.4, 3576.2);" " $v1->aMap = array(10=>1.2, 43=>5.33);" " $v1->aSet = array(10=>true, 11=>true);" " $v1->anByte = 123;" " $v1->anI16 = 1234;" " thrift_protocol_write_compact($p, 'foomethod', 1, $v1, 20);" " var_dump(md5($p->getTransport()->buff));" "}" "test();", "string(32) \"cd0654ca200fe910204988f44f996a11\"\n"); MVCRO( "t = new DummyTransport();" " }" " function getTransport() {" " return $this->t;" " }" "} " "class DummyTransport {" " public $buff = '';" " public $pos = 0;" " function flush() { }" " function write($buff) {" " $this->buff .= $buff;" " } " " function read($n) {" " $r = substr($this->buff, $this->pos, $n);" " $this->pos += $n;" " return $r;" " } " " function putBack($data) {" " $this->buff = ($data . $this->buff);" " } " "} " "class TestStruct {" " static $_TSPEC;" " " " public $aBool = null;" " public $anInt = null;" " public $aString = null;" " public $aDouble = null;" " public $anInt64 = null;" " public $aList = null;" " public $aMap = null;" " public $aSet = null;" " public $anByte = null;" " public $anI16 = null;" " " " public function __construct($vals=null) {" " if (!isset(self::$_TSPEC)) {" " self::$_TSPEC = array(" " -1 => array(" " 'var' => 'aBool'," " 'type' => TType::BOOL," " )," " 1 => array(" " 'var' => 'anInt'," " 'type' => TType::I32," " )," " 2 => array(" " 'var' => 'aString'," " 'type' => TType::STRING," " )," " 3 => array(" " 'var' => 'aDouble'," " 'type' => TType::DOUBLE," " )," " 4 => array(" " 'var' => 'anInt64'," " 'type' => TType::I64," " )," " 5 => array(" " 'var' => 'aList'," " 'type' => TType::LST," " 'etype' => TType::DOUBLE," " 'elem' => array(" " 'type' => TType::DOUBLE," " )," " )," " 6 => array(" " 'var' => 'aMap'," " 'type' => TType::MAP," " 'ktype' => TType::I32," " 'vtype' => TType::DOUBLE," " 'key' => array(" " 'type' => TType::I32," " )," " 'val' => array(" " 'type' => TType::DOUBLE," " )," " )," " 7 => array(" " 'var' => 'aSet'," " 'type' => TType::SET," " 'etype' => TType::I32," " 'elem' => array(" " 'type' => TType::I32," " )," " )," " 8 => array(" " 'var' => 'anByte'," " 'type' => TType::BYTE," " )," " 9 => array(" " 'var' => 'anI16'," " 'type' => TType::I16," " )," " );" " }" " }" "}" "" "function test() {" " $p = new DummyProtocol();" " $v1 = new TestStruct();" " $v1->aBool = true;" " $v1->anInt = 1234;" " $v1->aString = 'abcdef';" " $v1->aDouble = 1.2345;" " $v1->anInt64 = 8589934592;" " $v1->aList = array(13.3, 23.4, 3576.2);" " $v1->aMap = array(10=>1.2, 43=>5.33);" " $v1->aSet = array(10=>true, 11=>true);" " $v1->anByte = 123;" " $v1->anI16 = 1234;" " thrift_protocol_write_compact($p, 'foomethod', 1, $v1, 20);" // HACK: rewrite the version and call type from "version X, call" to // "version 2, response" to appease deserializer " $p->getTransport()->buff[1] = pack('C', 0x42);" " var_dump(thrift_protocol_read_compact($p, 'TestStruct'));" "}" "test();", "object(TestStruct)#4 (10) {\n" " [\"aBool\"]=>\n" " bool(true)\n" " [\"anInt\"]=>\n" " int(1234)\n" " [\"aString\"]=>\n" " string(6) \"abcdef\"\n" " [\"aDouble\"]=>\n" " float(1.2345)\n" " [\"anInt64\"]=>\n" " int(8589934592)\n" " [\"aList\"]=>\n" " array(3) {\n" " [0]=>\n" " float(13.3)\n" " [1]=>\n" " float(23.4)\n" " [2]=>\n" " float(3576.2)\n" " }\n" " [\"aMap\"]=>\n" " array(2) {\n" " [10]=>\n" " float(1.2)\n" " [43]=>\n" " float(5.33)\n" " }\n" " [\"aSet\"]=>\n" " array(2) {\n" " [10]=>\n" " bool(true)\n" " [11]=>\n" " bool(true)\n" " }\n" " [\"anByte\"]=>\n" " int(123)\n" " [\"anI16\"]=>\n" " int(1234)\n" "}\n"); return true; } bool TestCodeRun::TestExit() { MVCR(" 1000;')));"); MVCR(" 1000;')));"); return true; } bool TestCodeRun::TestConstructorDestructor() { MVCR("';" "$payload['pane_html'] .= '
';"); MVCR("'." " n_indent()." " $arg2 ." " n_unindent()." " '
';" "}" "$GLOBALS['n_indent_level'] = 0;" "var_dump(render(\"foo\", \"bar\"));"); MVCR(" 0) {" " $sql = 'foo';" " } else {" " $sql = 'bar';" " }" " $sql .= ' baz';" " return $sql;" "}" "echo test(1),test(-1),\"\\n\";"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C\\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "function bar() {" " print \" hello \" . foo() . \"\\n\";" " $a = new A;" " $a[0] = 0;" " $a[1] = 1;" " echo \" hello $a[0]\";" " echo \" hello $a[1]\\n\";" " print \" hello $a[0]\";" " print \" hello $a[1]\\n\";" " $b = new C;" " $b->a = 'aaaa';" " $b->b = 'bbbb';" " echo \" hello $b->a\";" " echo \" hello $b->b\\n\";" " print \" hello $b->a\";" " print \" hello $b->b\\n\";" " echo \" hello $b->a $b->b $b->a $b->b\";" "}" "bar();"); MVCR("Test\", ENT_QUOTES);" "echo htmlspecialchars_decode(\"\\0abc\");" "echo htmlspecialchars_decode(\"abc\\0def\");" "echo htmlentities(\"Test\", ENT_QUOTES);" "echo dirname(\"Test\");" "echo basename(\"Test\");" "echo version_compare(\"5.1.2\", \"5.1.3\");" "echo dechex(10);" "echo hexdec(\"See\");" "echo decbin(12);" "echo decbin('000110011');" "echo decoct(264);" "echo octdec('77');" "echo octdec(decoct(45));" "echo str_repeat(\"-=\", 10);" "echo intval(42);" "echo intval(4.2);" "echo intval('42');" "echo intval('+42');" "echo intval('-42');" "echo intval(042);" "echo intval('042');" "echo intval(1e10);" "echo intval('1e10');" "echo intval(0x1A);" "echo intval(42000000);" "echo intval(42, 8);" "echo intval('42', 8);" "echo substr(\"abcdef\", -1);" "echo substr(\"abcdef\", -2);" "echo substr(\"abcdef\", -3, 1);" "echo substr(\"abcdef\", 0, -1);" "echo substr(\"abcdef\", 2, -1);" "echo substr(\"abcdef\", 4, -4);" "echo substr(\"abcdef\", -3, -1);" "echo substr(\"abcdef\", 1);" "echo substr(\"abcdef\", 1, 3);" "echo substr(\"abcdef\", 0, 4);" "echo substr(\"abcdef\", 0, 8);" "echo substr(\"abcdef\", -1, 1);" "echo trim(\"\\t\\t\\0These are a few words :) ... \");" "echo trim(\"\\t\\t\\0These are a few words :) ... \", \" \\t.\");" "echo trim(\"\\x09Example string\\x0A\", \"\\x00..\\x1F\");" "echo ltrim(\"\\t\\t\\0These are a few words :) ... \");" "echo ltrim(\"\\t\\t\\0These are a few words :) ... \", \" \\t.\");" "echo ltrim(\"\\x09Example string\\x0A\", \"\\x00..\\x1F\");" "echo rtrim(\"\\t\\t\\0These are a few words :) ... \");" "echo rtrim(\"\\t\\t\\0These are a few words :) ... \", \" \\t.\");" "echo rtrim(\"\\x09Example string\\x0A\", \"\\x00..\\x1F\");" "echo chop(\"\\t\\t\\0These are a few words :) ... \");" "echo chop(\"\\t\\t\\0These are a few words :) ... \", \" \\t.\");" "echo chop(\"\\x09Example string\\x0A\", \"\\x00..\\x1F\");" "echo acos(0.5);" "echo acosh(0.5);" "echo asin(0.5);" "echo asinh(0.5);" "echo atan(0.5);" "echo atan2(0.5, 0.5);" "echo atanh(0.5);" "echo cos(0.5);" "echo cosh(0.5);" "echo sin(0.5);" "echo sinh(0.5);" "echo tan(0.5);" "echo tanh(0.5);" "echo exp(5.7);" "echo exp(12);" "echo log10(12);" "echo log(12);" "echo sqrt(2);" "echo ceil(7.9);" "echo floor(7.9);" "echo fmod(5.7, 1.3);" "echo ip2long(\"127.0.0.1\");" /* 5.2 accepts these, 5.3 does not. php.net says it should "echo ip2long(\"10.0.0\");" "echo ip2long(\"10.0.256\");" */ "echo long2ip(pow(2,32) + 1024);" "echo rad2deg(M_PI_4);" "echo deg2rad(45);"); MVCR("x();"); MVCR(" 'foo');" "}" "" "interface A {" " const CONSTANT = 'CONSTANT';" "}" "" "class B implements A { }" "" "class C {" " static $A_CONSTANT = A::CONSTANT;" " static $B_CONSTANT = B::CONSTANT;" "}" "" "var_dump(A::CONSTANT);" "var_dump(B::CONSTANT);" "var_dump(C::$A_CONSTANT);" "var_dump(C::$B_CONSTANT);"); MVCR(" array(" " ATB::PARAM_A => true," " ATB::PARAM_C => array(" " array('tcks', 'none')," " array('tcks', 'ids')," " )," " ATB::PARAM_B =>" " 'aaaa'," " )," " 'user_id' => array(" " ATB::PARAM_A => true," " ATB::PARAM_C => array(" " array('tcks', 'none')," " array('tcks', 'id')," " )," " ATB::PARAM_B =>" " 'bbbb'," " )," " );" " }" "}" "var_dump(ABCD::foo());"); MVCR("\n" " string(1) \"b\"\n" "}\n"); MVCRO("\n" " string(3) \"new\"\n" "}\n"); MVCRO("\n" " string(3) \"xxx\"\n" "}\n"); MVCR("getParameters() as $p) {" " var_dump($p->getDefaultValue());" " }" "}" "function fiz($c) {" " var_dump($c::FOO);" "}" "fiz('I');" "fiz('C');" "test();"); MVCR("foo();" "$rc = new ReflectionClass('Test');" "$method = $rc->getMethod('foo');" "foreach ($method->getParameters() as $param) {" " var_dump($param->getDefaultValue());" "}"); MVCR("_getJSFunction('_encode10');" " var_dump($encode10);" " $encode36 = $this->_getJSFunction('_encode36');" " var_dump($encode36);" " }" " private function _getJSFunction($aName) {" " if (defined('self::JSFUNCTION'.$aName))" " return constant('self::JSFUNCTION'.$aName);" " else" " return '';" " }" " const JSFUNCTION_encode10 =" " 'function($charCode) {" " return $charCode;" "}';" "" "}" "$obj = new JavaScriptPacker;" "$obj->foo(); "); MVCR("f();" "$obj = new Bar;" "$obj->f();"); MVCR("getConstViaThis());\n" "var_dump($class2->getConstViaFrame());\n" , "int(2)\n" "int(2)\n" ); return true; } bool TestCodeRun::TestAssignment() { MVCR("val = 1); }" " function goo() { f($val = 'val'); f($this->$val = 2); }" " function zoo() {" " var_dump($val); var_dump($this->val);" " }" "}" "function foo() {" " f($val2 = 1);" "}" "$obj = new ClassA();" "var_dump($obj);" "$obj->foo();" "var_dump($obj);" "$obj->bar();" "var_dump($obj);" "$obj->goo();" "var_dump($obj);" "$obj->zoo();"); MVCR("$val = 2); }" " function foo2() { f($this->val = 3); }" " function bar() {" " var_dump($val); var_dump($this->val);" " }" "}" "$obj = new ClassA();" "var_dump($obj);" "$obj->foo();" "var_dump($obj);" "$obj->bar();" "$obj->foo2();" "var_dump($obj);" "$obj->bar();"); MVCR("kid->check();\n" " $this->kid->clear_unset();\n" " }\n" "}\n" "\n" "class node {\n" " public $dom;\n" "\n" " public function __construct($dom) {\n" " $this->dom = $dom;\n" " $dom->kid = $this;\n" " }\n" " public function __destruct() {\n" " echo \"node destructing\n\";\n" " }\n" " public function clear_unset() {\n" " unset($this->dom);\n" " }\n" " public function clear_set() {\n" " $this->dom = null;\n" " }\n" " public function check() {\n" " var_dump(isset($this->dom));\n" " }\n" "}\n" "\n" "class node_arr {\n" " public $doms = array();\n" "\n" " public function __construct($dom) {\n" " $this->doms[0] = $dom;\n" " $dom->kid = $this;\n" " }\n" " public function __destruct() {\n" " echo \"node destructing\n\";\n" " }\n" " public function clear_unset() {\n" " unset($this->doms[0]);\n" " }\n" " public function clear_set() {\n" " $this->doms[0] = null;\n" " }\n" " public function check() {\n" " var_dump(isset($this->doms[0]));\n" " }\n" "}\n" "\n" "echo \"\nProperty, SetM\n\";\n" "$node = new node(new dom);\n" "$node->clear_set();\n" "unset($node);\n" "\n" "echo \"\nProperty, UnsetM\n\";\n" "$node = new node(new dom);\n" "$node->clear_unset();\n" "unset($node);\n" "\n" "echo \"\nArray, SetM\n\";\n" "$node = new node_arr(new dom);\n" "$node->clear_set();\n" "unset($node);\n" "\n" "echo \"\nArray, UnsetM\n\";\n" "$node = new node_arr(new dom);\n" "$node->clear_unset();\n" "unset($node);\n"); return true; } bool TestCodeRun::TestSimpleXML() { MVCR("addChild($node->getName(), (string)$node);\n" " foreach ($node->attributes() as $name => $value) {\n" " $newchild->addAttribute($name, $value);\n" " }\n" " foreach ($node->children() as $child) {\n" " addChildNode($newchild, $child);\n" " }\n" "}\n" "\n" "$xmlreq = '1st" "2nd';\n" "$quote = simplexml_load_string($xmlreq);\n" "$req = new SimpleXMLElement('');\n" "foreach ($quote->attributes() as $name => $value) {\n" " $req->addAttribute($name, $value);\n" "}\n" "foreach ($quote->children() as $child) {\n" " addChildNode($req, $child);\n" "}\n" "\n" "$vertex = new SimpleXMLElement('');\n" "addChildNode($vertex, $req);\n" "var_dump($vertex->asXML());\n" ); MVCR("345.234');" "var_dump((double)$x->bar);"); MVCR("');" "var_dump((bool)$x->bar);"); MVCR("0');" "var_dump((bool)$x->bar);"); MVCR("'); " "$x->addAttribute('attr', 'one'); " "$x['attr'] = 'two'; " "var_dump((string)$x['attr']); " "var_dump($x->asXML());"); MVCR("whoops');\n" "var_dump((array)$node->bar);"); MVCR("" "whoops');\n" "var_dump((array)$node->bar);"); MVCR("whoops');\n" "var_dump((string)$node[0]);"); MVCR("whoops');" "var_dump((string)$node);"); MVCR("whoops');" "var_dump((string)$node);"); MVCR("whoops');" "var_dump((string)$node);"); MVCR("');\n" "$sxe->addChild('path', 'some/path/to/my.file');\n" "$sxe->addChild('options');\n" "$sxe->options->addChild('paddingbottom', 1);\n" "var_dump((string)$sxe->path);\n" "var_dump((string)$sxe->options->paddingbottom);\n" ); MVCR("');\n" "$x->addChild('bar', 'whoops');\n" "var_dump((string)$x);\n"); MVCR( " $v) {\n" " if ($sxml['list']) {\n" " if (isset($v['key'])) {\n" " $arr[(string)$v['key']] = convert_simplexml_to_array($v);\n" " } else {\n" " $arr[] = convert_simplexml_to_array($v);\n" " }\n" " } else {\n" " $arr[$k] = convert_simplexml_to_array($v);\n" " }\n" " }\n" " }\n" " if (sizeof($arr) > 0) {\n" " return $arr;\n" " } else {\n" " return (string)$sxml;\n" " }\n" "}\n" "\n" "$xml = <<\n" " \n" " \n" " value1-1\n" " value1-2\n" " \n" " value1\n" " \n" " \n" " value2\n" " \n" "\n" "EOM;\n" "\n" "$sxml = simplexml_load_string($xml);\n" "var_dump(convert_simplexml_to_array($sxml));\n" ); MVCR("test';\n" "$sxml = simplexml_load_string($xml);\n" "foreach ($sxml as $k => $v) {\n" " var_dump($k, (string)$v);\n" "}\n"); MVCR("678';\n" "$sxml = simplexml_load_string($xml);\n" "foreach ($sxml as $k => $v) {\n" " var_dump($k, (int)$v);\n" "}\n"); MVCR("678';\n" "$sxml = simplexml_load_string($xml);\n" "foreach ($sxml as $k => $v) {\n" " var_dump($k, (string)$v);\n" "}\n"); MVCR("" "';\n" "$dom = new SimpleXMLElement($xml);\n" "$invalidations = $dom->invalidations;\n" "var_dump((string)$invalidations->invalidation[\"id\"]);\n" "foreach ($invalidations as $node) {\n" " var_dump((string)$node->invalidation[\"id\"]);\n" "}\n"); MVCR("\n" "\n" " \n" " memcache\n" " \n" " \n" "\n" " \n" " memcache\n" " \n" " \n" "\n" "EOM;\n" "var_dump($file);\n" "\n" "$xml = simplexml_load_string($file);\n" "foreach ($xml->children() as $parent_name => $xml_ele) {\n" " var_dump($parent_name);\n" "\n" " foreach ($xml_ele->children() as $key => $value) {\n" " var_dump((string)$key, (string)$value);\n" " }\n" "}\n" ); MVCR("6';\n" "$sxml = simplexml_load_string($xml);\n" "function convert_simplexml_to_array($sxml) {\n" " if ($sxml) {\n" " foreach ($sxml as $k => $v) {\n" " var_dump($k, (string)$v);\n" " convert_simplexml_to_array($v);\n" " }\n" " }\n" "}\n" "convert_simplexml_to_array($sxml);"); MVCR("'); $doc->node->option = false; var_dump($doc->asXML());"); MVCR("'); $doc->node->option = 0; var_dump($doc->asXML());"); MVCR("'); unset($doc->node->option); var_dump($doc->asXML());"); MVCR("'); foreach ($doc->list[0]->entry as $r) { var_dump((array)$r->attributes());}"); MVCR("');" "$sxe->addChild('options');" "$sxe->options->addChild('paddingtop', 0);" "echo 'Success\n';"); MVCR("c1c2c3'); $foo_ns_bar = $doc->children('http://example.com');" "var_dump($doc->getName());" "foreach ($foo_ns_bar as $v) var_dump((string)$v);" "var_dump($foo_ns_bar->getName());" "var_dump(count($foo_ns_bar->b1));" "var_dump((string)$foo_ns_bar->b1);" "var_dump((string)$foo_ns_bar->b1[0]);" "foreach ($foo_ns_bar->b1 as $v) var_dump((string)$v);" "var_dump(count($foo_ns_bar->b2));" "var_dump((string)$foo_ns_bar->b2[0]);" "var_dump((string)$foo_ns_bar->b2[1]);" "foreach ($foo_ns_bar->b2 as $v) var_dump((string)$v);" ); MVCR(" 10) {" " var_dump('Recursed to deep, backing out');" " return;" " }" " print $indent.$el->getName().\"\\n\";" " foreach ($el->attributes() as $k => $v) {" " print $indent.$k.' => '.$v.\"\\n\";" " }" " foreach ($el->children() as $child) {" " printElement($child, $indent.' ');" " }" "}" "$a = simplexml_load_string('hihi');" "printElement($a);" ); MVCR("testtestv');" "var_dump((array)$a->attributes());" "var_dump((string)$a->subnode[0]);" "var_dump((string)$a->subnode[0]['attr1']);" "var_dump((string)$a->subnode[1]['subsubnode']);" "var_dump((string)$a->subnode[1]->subsubnode);" "var_dump((string)$a->test);" "var_dump((array)$a->subnode[0]->attributes());" "var_dump((array)$a->subnode[1]->attributes());" "var_dump($a->asxml());" "var_dump((string)$a->addchild('newnode', 'newvalue'));" "$a->addattribute('newattr', 'newattrvalue');" "var_dump($a->asxml());" "var_dump((array)$a->attributes());" "var_dump((string)$a->newnode);" "var_dump($a->getname());" "var_dump((array)$a->children()->subnode[0]->subsubnode);" "$nodes = $a->xpath('//node/subnode');" "var_dump((string)$nodes[1]->subsubnode);" "$nodes = $nodes[1]->xpath('subsubnode');" "var_dump((string)$nodes[0]);" ); MVCR("test');" "var_dump((array)($a->subnode->subsubnode));" "var_dump((string)($a->subnode->subsubnode));" ); MVCR("test');" "var_dump((array)($a->subnode->subsubnode));" "var_dump((string)($a->subnode->subsubnode));" ); MVCR("test');" "var_dump((string)($a->subnode->subsubnode['0']));" "var_dump((string)($a->subnode->subsubnode[0]));" ); MVCR("test');" "var_dump((string)($a->subnode['attr1']));" ); MVCR("test');" "var_dump((string)($a->subnode->subsubnode['attr1']));" ); MVCR("test');" "var_dump((string)($a->subnode->subsubnode->sssnode));" ); MVCR("';" "$xml = new SimpleXMLElement($post_xml);" "foreach ($xml->scannedItem as $item) {" " echo $item['itemName'] . \"\\n\";" "}"); MVCR("test');" "var_dump((string)($a->subnode->subsubnode[0]));" ); MVCR("678';\n" "$sxml = simplexml_load_string($xml);\n" "var_dump(count($sxml->t));\n" "var_dump((string)$sxml->t[0]);\n" "var_dump((string)$sxml->t[1]);\n" "var_dump((string)$sxml->t[2]);\n" "var_dump(count($sxml->t->bogus));\n" "var_dump(count($sxml->t->attributes()));\n" "foreach ($sxml->bogus as $v) {}"); MVCR("now is the time for all good men to come to " "the aid of their country';\n" "$s = simplexml_load_string($xml);\n" "var_dump(get_class($s));\n" "$s = simplexml_load_string($xml, 'MyElement');\n" "var_dump(get_class($s));\n" "var_dump($s->bar->baz->asUcWordString());\n" ); return true; } bool TestCodeRun::TestXML() { MVCR( "parser = xml_parser_create();\n" " xml_set_object($this->parser, $this);\n" " xml_set_element_handler($this->parser, 'tag_open', 'tag_close');\n" " xml_set_character_data_handler($this->parser, 'cdata');\n" " }\n" " function parse($data) { xml_parse($this->parser, $data);}\n" " function tag_open($parser, $tag, $attributes) {\n" " var_dump($tag, $attributes);\n" " }\n" " function cdata($parser, $cdata) { var_dump($cdata);}\n" " function tag_close($parser, $tag){ var_dump($tag);}\n" "}\n" "\n" "$xml_parser = new xml();\n" "$xml_parser->parse('PHP');\n" ); MVCR("\", true);\n" "\n" " $p = xml_parser_create();\n" " xml_set_element_handler($p, 'parse_callback', 'parse_callback');\n" " xml_set_element_handler($p, 'parse_callback', '');\n" " xml_parse($p, \"\", true);\n" "}\n" "main();\n"); return true; } bool TestCodeRun::TestDOMDocument() { MVCR("';\n" "$dom = new domDocument;\n" "$dom->loadxml($xml);\n" "$xpath = new DOMXPath($dom);\n" "$node_list = $xpath->query('//dependencies/dependency[@dependency_id = 0 and @dependent_id = 1]');\n" "$dependencies = $xpath->query('//dependencies')->item(0);\n" "$dependencies->removeChild($node_list->item(0));\n" ); MVCR("';\n" "$dom = new domDocument;\n" "$dom->loadxml($xml);\n" "$xpath = new DOMXPath($dom);\n" "$node_list = $xpath->query('//dependencies/dependency[@dependent_id = 8]');\n" "foreach ($node_list as $node) {\n" " var_dump($node->getAttribute($attribute));\n" "}\n" ); MVCR("\n" "\n" "]>\n" "\n" "Title\n" "\n" "&sp;\n" "\n" "\n" "\n" "\n" "a1b1" "c1\n" "a2c2\n" "a3b3c3\n" "\n" "\n" "\n" "\n" " \";\n" "\n" "function print_node($node)\n" "{\n" " print \"Node Name: \" . $node->nodeName;\n" " print \"\nNode Type: \" . $node->nodeType;\n" " if ($node->nodeType != 3) {\n" " $child_count = $node->childNodes->length;\n" " } else {\n" " $child_count = 0;\n" " }\n" " print \"\nNum Children: \" . $child_count;\n" " if($child_count <= 1){\n" " print \"\nNode Content: \" . $node->nodeValue;\n" " }\n" " print \"\n\n\";\n" "}\n" "\n" "function print_node_list($nodelist)\n" "{\n" " foreach($nodelist as $node)\n" " {\n" " print_node($node);\n" " }\n" "}\n" "\n" "echo \"Test 1: accessing single nodes from php\n\";\n" "$dom = new domDocument;\n" "$dom->loadxml($xmlstr);\n" "if(!$dom) {\n" " echo \"Error while parsing the document\n\";\n" " exit;\n" "}\n" "\n" "// children() of of document would result in a memleak\n" "//$children = $dom->children();\n" "//print_node_list($children);\n" "\n" "echo \"--------- root\n\";\n" "$rootnode = $dom->documentElement;\n" "print_node($rootnode);\n" "\n" "echo \"--------- children of root\n\";\n" "$children = $rootnode->childNodes;\n" "print_node_list($children);\n" "\n" "// The last node should be identical with the last " "entry in the children array\n" "echo \"--------- last\n\";\n" "$last = $rootnode->lastChild;\n" "print_node($last);\n" "\n" "// The parent of this last node is the root again\n" "echo \"--------- parent\n\";\n" "$parent = $last->parentNode;\n" "print_node($parent);\n" "\n" "// The children of this parent are the same children as one above\n" "echo \"--------- children of parent\n\";\n" "$children = $parent->childNodes;\n" "print_node_list($children);\n" "\n" "echo \"--------- creating a new attribute\n\";\n" "//This is worthless\n" "//$attr = $dom->createAttribute(\"src\", \"picture.gif\");\n" "//print_r($attr);\n" "\n" "//$rootnode->set_attributeNode($attr);\n" "$attr = $rootnode->setAttribute(\"src\", \"picture.gif\");\n" "$attr = $rootnode->getAttribute(\"src\");\n" "print_r($attr);\n" "print \"\n\";\n" "\n" "echo \"--------- Get Attribute Node\n\";\n" "$attr = $rootnode->getAttributeNode(\"src\");\n" "print_node($attr);\n" "\n" "echo \"--------- Remove Attribute Node\n\";\n" "$attr = $rootnode->removeAttribute(\"src\");\n" "print \"Removed \" . $attr . \" attributes.\n\";\n" "\n" "echo \"--------- attributes of rootnode\n\";\n" "$attrs = $rootnode->attributes;\n" "print_node_list($attrs);\n" "\n" "echo \"--------- children of an attribute\n\";\n" "$children = $attrs->item(0)->childNodes;\n" "print_node_list($children);\n" "\n" "echo \"--------- Add child to root\n\";\n" "$myelement = new domElement(\"Silly\", \"Symphony\");\n" "$newchild = $rootnode->appendChild($myelement);\n" "print_node($newchild);\n" "print $dom->saveXML();\n" "print \"\n\";\n" "\n" "echo \"--------- Find element by tagname\n\";\n" "echo \" Using dom\n\";\n" "$children = $dom->getElementsByTagname(\"Silly\");\n" "print_node_list($children);\n" "\n" "echo \" Using elem\n\";\n" "$children = $rootnode->getElementsByTagName(\"Silly\");\n" "print_node_list($children);\n" "\n" "echo \"--------- Unlink Node\n\";\n" "print_node($children->item(0));\n" "$rootnode->removeChild($children->item(0));\n" "print_node_list($rootnode->childNodes);\n" "print $dom->savexml();\n" ); // dom002.phpt MVCR("\n" "\n" " \n" " \n" " \n" " \n" "\n" "HERE;\n" "\n" "function dump($elems) {\n" " foreach ($elems as $elem) {\n" " var_dump($elem->nodeName);\n" " dump($elem->childNodes);\n" "}\n" "}\n" "\n" "$dom = new DOMDocument();\n" "$dom->loadXML($xml);\n" "$doc = $dom->documentElement;\n" "dump($dom->getElementsByTagName('bar'));\n" "dump($doc->getElementsByTagName('bar'));\n" "dump($dom->getElementsByTagNameNS('http://www.example.com/ns/fubar'," " 'bar'));\n" "dump($doc->getElementsByTagNameNS('http://www.example.com/ns/fubar'," " 'bar'));\n" ); // dom005.phpt MVCR("\n" "Hello world\n" "\n" "\n" "This is a not well-formed
\n" "html files with undeclared entities \n" "\n" "\n" "EOM;\n" "$dom->loadHTML($html);\n" "print \"--- save as XML\n\";\n" "\n" "print adjustDoctype($dom->saveXML());\n" "print \"--- save as HTML\n\";\n" "\n" "print adjustDoctype($dom->saveHTML());\n" "\n" "function adjustDoctype($xml) {\n" " return str_replace(" "array(\">\n<\",\"DOCTYPE HTML\",'

','

')," "array(\"><\",\"DOCTYPE html\",'',''),$xml);\n" "}\n" ); // dom006.phpt MVCR("createElement('title');\n" " $titleElement->appendChild($this->createTextNode($title));\n" " $authorElement = $this->createElement('author');\n" " $authorElement->appendChild($this->createTextNode($author));\n" " $bookElement = $this->createElement('book');\n" " $bookElement->appendChild($titleElement);\n" " $bookElement->appendChild($authorElement);\n" " $this->documentElement->appendChild($bookElement);\n" " }\n" "}\n" "\n" "$dom = new books;\n" "\n" "$xml = <<\n" "\n" " \n" " The Grapes of Wrath\n" " John Steinbeck\n" " \n" " The Pearl John Steinbeck\n" " \n" "EOM;\n" "\n" "$dom->loadXML($xml);\n" "$dom->addBook('PHP de Luxe', 'Richard Samar, Christian Stocker');\n" "print $dom->saveXML();" ); // dom007.phpt MVCR("\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "]>\n" "\n" " \n" " Basic Languages\n" " Introduction to Languages\n" " \n" " \n" " French I\n" " Introduction to French\n" " \n" " \n" " \n" "\n" "EOXML;\n" "\n" "$dom = new DOMDocument();\n" "$dom->loadXML($xml);\n" "\n" "$dtd = $dom->doctype;\n" "\n" "/* Notation Tests */\n" "$nots = $dtd->notations;\n" "\n" "$length = $nots->length; var_dump($length);\n" "echo \"Length: \".$length.\"\n\";\n" "\n" "foreach ($nots AS $key=>$node) {\n" " echo \"Key $key: \".$node->nodeName.\" (\".\n" "$node->systemId.\") (\".$node->publicId.\")\n\";\n" "}\n" "print \"\n\";\n" "for($x=0; $x < $length; $x++) {\n" " echo \"Index $x: \".$nots->item($x)->nodeName.\" (\".\n" " $nots->item($x)->systemId.\") " "(\".$nots->item($x)->publicId.\")\n\";\n" "}\n" "\n" "echo \"\n\";\n" "$node = $nots->getNamedItem('xxx');\n" "var_dump($node);\n" "\n" "echo \"\n\";\n" "/* Entity Decl Tests */\n" "$ents = $dtd->entities;\n" "$length = $ents->length;\n" "echo \"Length: \".$length.\"\n\";\n" "foreach ($ents AS $key=>$node) {\n" " echo \"Key: $key Name: \".$node->nodeName.\"\n\";\n" "}\n" "echo \"\n\";\n" "for($x=0; $x < $length; $x++) {\n" " echo \"Index $x: \".$ents->item($x)->nodeName.\"\n\";\n" "}\n" "\n" "echo \"\n\";\n" "$node = $ents->item(3);\n" "var_dump($node);\n" "$node = $ents->getNamedItem('xxx');\n" "var_dump($node);\n" ); MVCR("createDocumentFragment();" " $body->appendXML($html);" " } else {" " $doc->loadHTML($html);" " $body = $doc->documentElement;" " }" " return helper($body);" " }" "" " function helper($element) {" " if ($element instanceof DOMText) {" " return htmlspecialchars($element->nodeValue);" " } else {" " $body = '';" " foreach ($element->childNodes as $child) {" " $body .= helper($child);" " }" "" " if ($element instanceof DOMElement) {" " $attrs = array();" " foreach ($element->attributes as $attr) {" " $attrs[] = htmlspecialchars($attr->name) . '=\"' . " " htmlspecialchars($attr->value) . '\"';" " }" " if ($attrs) {" " $attrs = ' ' . implode(' ', $attrs);" " } else {" " $attrs = '';" " }" " return '<' . $element->tagName . $attrs . '>' . $body . " " 'tagName . '>';" " } else {" " return $body;" " }" " }" " }" "" " $fragment = 'Hello, world.';" " $document = '
" "

'.$fragment.'

';" "" " echo rerender($fragment, true).\"\n\n\";" " echo rerender($document, false).\"\n\n\";" ); MVCR("$1 - ';" "$dom = new DOMDocument();" "$dom->loadXML($xml);" "new foo($dom->documentElement);" "class foo {" " function foo($a) {" " var_dump($a);" " }" "}"); MVCR("loadXML('');\n" "$remove = array();\n" "foreach ($dom->getElementsByTagName('b') as $data) {\n" " foreach ($data->childNodes as $element) {\n" " if ($element instanceof DOMElement) {\n" " $remove[] = $element;\n" " }\n" " }\n" "}\n" "foreach ($remove as $r) {\n" " $r->parentNode->removeChild($r);\n" "}\n" "echo $dom->saveXML();\n" ); MVCRO("HelloWorld';\n" " $doc = new DOMDocument();\n" " $element = $doc->createDocumentFragment();\n" " $element->appendXML($html);\n" " foreach ($element->childNodes->getIterator() as $child) {\n" " $element = null;\n" " $doc = null;\n" " var_dump($child->nodeValue);\n" " }\n" "}\n" "foo();\n", "string(5) \"Hello\"\n" "string(5) \"World\"\n" ); /* github issue #556 */ MVCR( "registerNodeClass('DOMNode', 'MyNode'));" "var_dump($dom->registerNodeClass('DOMElement', 'MyElement'));" ); return true; } bool TestCodeRun::TestFile() { //MVCR(".\\n\";" "" "fseek($input, 0);" "$output = fopen('php://memory', 'w+');" "stream_copy_to_stream($input, $output, null);" "fseek($output, 0);" "$bytes = fread($output, 1024);" "print \"From file, using Maxlen null: <\".serialize($bytes).\">.\\n\";" "" "" "fseek($input, 0);" "$output = fopen('php://memory', 'w+');" "stream_copy_to_stream($input, $output, -1);" "fseek($output, 0);" "$bytes = fread($output, 1024);" "print \"From file, using Maxlen -1: <\".serialize($bytes).\">.\\n\";"); MVCR("ctorRan = true;" " }" " public function stream_open($fn, $mode, $opt, &$opened_path) {" " var_dump($this->ctorRan);" " return true;" " }" "}" "stream_wrapper_register('wrap', 'MyWrapper');" "fclose(fopen('wrap://test', 'r'));" ); // Private wrapper MVCR("s++ == 0)" " return \"a\\n\";" " return '';" " }" " function stream_eof() {" " return $this->s >= 2;" " }" "}" "stream_wrapper_register('test', 'TestStream');" "$f = fopen('test://', 'r');" "while (!feof($f)) {" " $line = stream_get_line($f, 99, \"\\n\");" " var_dump($line);" "}" ); // ext/standard/tests/streams/bug60455_03.phpt MVCR("lines[] = \"a\\n\";" " $this->lines[] = ($path == 'test://nonempty2nd' ? \"b\\n\" : \"\\n\");" " if ($path == 'test://eofafter2nd')" " $this->eofth = 2;" " return true;" " }" " function stream_read($count) {" " if (key_exists($this->s++, $this->lines))" " return $this->lines[$this->s - 1];" " return '';" " }" " function stream_eof() {" " return $this->s >= $this->eofth;" " }" "}" "stream_wrapper_register('test', 'TestStream');" "$f = fopen('test://nonempty2nd', 'r');" "while (!feof($f)) {" " $line = stream_get_line($f, 99, \"\\n\");" " var_dump($line);" "}" "$f = fopen('test://', 'r');" "while (!feof($f)) {" " $line = stream_get_line($f, 99, \"\\n\");" " var_dump($line);" "}" "$f = fopen('test://eofafter2nd', 'r');" "while (!feof($f)) {" " $line = stream_get_line($f, 99, \"\\n\");" " var_dump($line);" "}" ); // Fifo Stream MVCR("data .= $buf; }" " function stream_read($count) {" " $chunk = substr($this->data, 0, $count);" " $this->data = substr($this->data, $count);" " return $chunk;" " }" " function stream_eof() { return strlen($this->data) == 0; }" " function stream_flush() { $this->data = ''; }" " function stream_close() { echo \"Close\\n\"; }" "}" "var_dump(stream_wrapper_register('fifo', 'FifoStream'));" "$fp = fopen('fifo://testing', 'w+');" "var_dump(fwrite($fp, \"Data one...\\n\"));" "fflush($fp);" "var_dump(fwrite($fp, \"Data two...\\n\"));" "var_dump(fwrite($fp, \"Data three...\\n\"));" "while(!feof($fp)) {" " var_dump(fgets($fp));" "}" "fclose($fp);" ); // Memory Stream MVCR("data = substr($filename, 6);" " return true;" " }" " function stream_read($count) {" " $ret = substr($this->data, $this->ofs, $count);" " $this->ofs += $count;" " if ($this->ofs > strlen($this->data))" " $this->ofs = strlen($this->data);" " return $ret;" " }" " function stream_seek($ofs, $whence) {" " if ($whence == SEEK_CUR) $this->ofs += $ofs;" " if ($whence == SEEK_SET) $this->ofs = $ofs;" " if ($whence == SEEK_END) $this->ofs = strlen($this->data) + $ofs;" " if ($this->ofs < 0) $this->ofs = 0;" " if ($this->ofs > strlen($this->data))" " $this->ofs = strlen($this->data);" " return true;" " }" " function stream_tell() { return $this->ofs; }" "}" "stream_wrapper_register('mem', 'MemoryStream');" "$fp = fopen('mem://abcdefghijklmnopqrstuvwxyz', 'r');" "var_dump(fgetc($fp), fgetc($fp));" "fseek($fp, 11, SEEK_CUR);" "var_dump(fgetc($fp), fgetc($fp));" "fseek($fp, 0, SEEK_END);" "var_dump(ftell($fp));" ); return true; } bool TestCodeRun::TestDirectory() { MVCR("path . \"\\n\";" "while (false !== ($entry = $d->read())) {" " echo $entry.\"\\n\";" "}" "$d->rewind();" "while (false !== ($entry = $d->read())) {" " echo $entry.\"\\n\";" "}" "$d->close();"); return true; } bool TestCodeRun::TestBadFunctionCalls() { // make sure no error MVCR("foo();\n" " } catch (BadMethodCallException $e) {\n" " echo \"BadMethodCallException thrown\\n\";\n" " }\n" "}\n", "BadMethodCallException thrown\n" "BadMethodCallException thrown\n" "BadMethodCallException thrown\n" "BadMethodCallException thrown\n" "BadMethodCallException thrown\n"); // Make sure call_user_func() doesn't throw an exception MVCRO("a(); }" "test();"); // __construct takes priority MVCR("a(); } " "test();"); MVCR("__construct();" " }" " public function __construct() {" " echo \"In A::__construct\\n\";" " }" "}" "class B extends A {" " public function B() {" " echo \"In B\\n\";" " $this->A();" " }" "}" "$obj = new B();" "" "class A2 {" " public function __construct() {" " echo \"In A2::__construct\\n\";" " $this->B2();" " }" " public function B2() {" " echo \"In B2\\n\";" " }" "}" "class B2 extends A2 {" " public function __construct() {" " echo \"In B2::__construct\\n\";" " parent::__construct();" " }" "}" "$obj = new B2();" "class C {" " public function C() {}" "}" "class D extends C {" " public function __construct() {" " echo \"In D::__construct\\n\";" " C::__construct();" " }" "}" "$obj = new D;" "$obj->c();" "class E {" " public function E() {" " echo \"In E\\n\";" " }" " public function foo() {" " $this->E();" " E::__construct();" " }" "}" "$obj = new E;" "$obj->foo();"); MVCR("a = $i * $i;" " $this->b = $j * $j;" " $this->c = $k * $k;" " }" " public $a;" " protected $b;" " private $c;" " public $aa = 'aa';" " protected $bb = false;" " private $cc = 1.22;" " }" "}" "class B extends A {" " public function __construct($i, $j, $k) {" " $this->a = $i + $i;" " $this->b = $j + $j;" " $this->c = $k + $k;" " }" " public $a;" " protected $b;" " private $c;" " public $aa = 'aaa';" " protected $bb = 4;" " private $cc = 1.222;" "}" "function foo() {" " $obj = new B(1, 2, 3);" " var_dump($obj);" "}" "foo();"); return true; } bool TestCodeRun::TestIntIsset() { MVCR("exp_info = $exp_info ?: array();\n" " }\n" "}\n" "$x = new X(array(0, 1, 2));\n" "var_dump($x->exp_info);\n" "$x1 = new X(null);\n" "var_dump($x->exp_info);\n"); MVCR("name = \"MyDestructableClass\";" " }" "" " function __destruct() {" " print \"Destroying \" . $this->name . \"\\n\";" " }" "}" "function foo($a) {" " if ($a) return new MyDestructableClass();" " return false;" "}" "function bar($a) {" " if ($a) {" " $obj = foo(1);" " $obj = 1;" " var_dump(2);" " }" " var_dump(1);" "}" "bar(1);"); MVCR("name = \"MyDestructableClass\";" " }" "" " function __destruct() {" " print \"Destroying \" . $this->name . \"\\n\";" " }" "}" "function foo(&$a) {" " $a = new MyDestructableClass();" "}" "function bar($a) {" " if ($a) {" " $b = array(1, 2, 3);" " var_dump($b);" " foo($dummy = array(1, 2, 3));" " $c = array(1, 2, 3);" " var_dump($c);" " }" "}" "bar(1);"); MVCR(" $p) {" " $a = 10;" " } else {" " $a = &$b;" " }" " }" "}" "function bar() {" " $a = foo(2);" " var_dump($GLOBALS['b']);" "}" "bar();"); MVCR("x = 0; }\n" " public function __toString() {\n" " return sprintf(\"Evil%d\", $this->x++);\n" " }\n" "}\n" "function f_1($x) {\n" " switch ($x) {\n" " case \"123\": print '\"123\"' . \"\n\"; break;\n" " case \"4abc\": print '\"4abc\"' . \"\n\"; break;\n" " default: print \"default\n\"; break;\n" " case \"0\": print '\"0\"' . \"\n\"; break;\n" " case \"\": print '\"\"' . \"\n\"; break; \n" " case \"Evil4\": print '\"Evil4\"' . \"\n\"; break;\n" " }\n" "}\n" "function f_2($x) {\n" " var_dump($x); print \" goes to:\";\n" " switch ($x) {\n" " case \"foo\": print \"foo\n\"; break;\n" " case \"1\": print \"1\n\"; break;\n" " case \"2.0\": print \"2.0\n\"; break;\n" " case \"2ab\": print \"2ab\n\"; break;\n" " case \"3.212\": print \"3.212\n\"; break;\n" " case \"0\": print \"0\n\"; break;\n" " case \"\": print \"{empty str}\n\"; break;\n" " default: print \"default\n\"; break;\n" " }\n" "}\n" "function g_2($x) {\n" " var_dump($x); print \" goes to:\";\n" " switch ($x) {\n" " case \"\": print \"{empty str}\n\"; break;\n" " case \"0\": print \"0\n\"; break;\n" " default: print \"default\n\"; break;\n" " }\n" "}\n" "function h_2($x) {\n" " var_dump($x); print \" goes to:\";\n" " switch ($x) {\n" " case \"3.0\": print \"3.0\n\"; break;\n" " case \"3.0abc\": print \"3.0abc\n\"; break;\n" " case \"3\": print \"3\n\"; break;\n" " default: print \"\n\";\n" " }\n" "}\n" "function f_3($x) {\n" " switch ($x) {\n" " default: print \"default\n\";\n" " case \"bar\": print \"bar\n\";\n" " case \"foo\": print \"foo\n\";\n" " case \"baz\": print \"baz\n\";\n" " }\n" "}\n" "f_1(\"\");\n" "f_1(null);\n" "f_1(false);\n" "f_1(\"0\");\n" "f_1(\"0eab\");\n" "f_1(\"0.0\");\n" "f_1(0.0);\n" "f_1(0);\n" "f_1(true);\n" "f_1(false);\n" "f_1(\"4abc\");\n" "f_1(4);\n" "f_1(\"4.0\");\n" "f_1(new Evil());\n" "f_2(1);\n" "f_2(2);\n" "f_2(2.0);\n" "f_2(true);\n" "f_2(false);\n" "f_2(null);\n" "f_2((object) null);\n" "f_2(array());\n" "f_2(3.21200);\n" "g_2(0);\n" "g_2(null);\n" "g_2(false);\n" "g_2(true);\n" "h_2(\"3\");\n" "h_2(\"3abc\");\n" "h_2(\"3a\");\n" "h_2(3);\n" "h_2(3.0);\n" "f_3(\"foo\");\n" "f_3(\"bar\");\n" "f_3(\"baz\");\n" "f_3(\"def\");\n"); MVCR("foo();\n" "$x->bar(new stdClass);\n" "$x->bar($x);\n" "foreach ($x->baz($x) as $v) {\n" " var_dump($v);\n" "}\n", "defdefargargobject(X)#1 (0) {\n" "}\n"); } MVCR(" \"a\")));" "var_dump(strtr(\"hello\", array(\"ll\" => \"a\")));"); MVCR("array('bar'=>1));\n" "function fix(&$v, $k) { $v *= 2; }\n" "array_walk_recursive($a, 'fix');\n" "var_dump($a['foo']);\n"); MVCR("foo =& $a;" " var_dump(is_object($b));" " $b = false;" " $b[0] =& $a;" " uksort($a, function ($i, $j) use(&$b) {" " if ($b[0][$i] == $b[0][$j]) return 0;" " return $b[0][$i] < $b[0][$j] ? -1 : 1;" " });" "}" "function test($x) {" " $a = array(220,250,240,$x);" " xsort($a);" " var_dump($a);" "}" "test(230);"); MVCR("getMessage());" " }" "}" "test();"); return true; } bool TestCodeRun::TestExtFile() { MVCR(" 50; $i--) {" " imagefilledarc($image, 50, $i, 100, 50, 0, 45," " $darknavy, IMG_ARC_PIE);" " imagefilledarc($image, 50, $i, 100, 50, 45, 75," " $darkgray, IMG_ARC_PIE);" " imagefilledarc($image, 50, $i, 100, 50, 75, 360," " $darkred, IMG_ARC_PIE);" "}" "" "imagefilledarc($image, 50, 50, 100, 50, 0, 45, $navy, IMG_ARC_PIE);" "imagefilledarc($image, 50, 50, 100, 50, 45, 75 , $gray, IMG_ARC_PIE);" "imagefilledarc($image, 50, 50, 100, 50, 75, 360 , $red, IMG_ARC_PIE);" "" "" "// flush image" "header('Content-type: image/png');" "imagepng($image);" "imagedestroy($image);"); MVCR("isFile()) {" " echo $info->getRealPath();" "}" "$info = new SplFileInfo('test/test_code_run.cpp');" "var_dump($info->getbaseName());" "var_dump($info->getbaseName('.cpp'));" "echo 'Last changed at ' . date('g:i a', $info->getCTime());" "var_dump($info->getGroup());" "var_dump($info->getInode());" "var_dump($info->getMTime());" "var_dump($info->getOwner());" "var_dump($info->getPerms());" "var_dump($info->getSize());" "var_dump($info->getType());" "var_dump($info->isDir());" "var_dump($info->isFile());" "var_dump($info->isLink());" "var_dump($info->isReadable());" "var_dump($info->isWritable());"); MVCR("getRealPath());" "var_dump($info->getPath());" "var_dump($info->getPathName());" "$info = new SplFileInfo('test/');" "var_dump($info->getRealPath());" "var_dump($info->getPath());" "var_dump($info->getPathName());" "$info = new SplFileInfo('test//../test');" "var_dump($info->getRealPath());" "var_dump($info->getPath());" "var_dump($info->getPathName());" "$p=realpath('test/..');" "$info = new SplFileInfo($p.'/test_link');" "var_dump($info->getLinkTarget());" "var_dump($info->getRealPath());" "var_dump($info->getPath());" "var_dump($info->getPathName());"); MVCR("getLinkTarget();" "}" "catch (Exception $e) {" " echo 'Caught exception: ', $e->getMessage(), \"\\n\";" " return;" "}" "echo \"failed to throw\\n\";" " return true;" "}"); return true; } bool TestCodeRun::TestExtIterator() { MVCR("isDot()) {" " var_dump($fileinfo->getFilename());" " }" "}" "$iterator = new DirectoryIterator(\"test\");" "foreach ($iterator as $fileinfo) {" " if ($fileinfo->isFile()) {" " echo \"BEGIN: \" . $fileinfo->getFilename() . \"\\n\";" " echo $fileinfo->getCTime() . \"\\n\";" " echo $fileinfo->getBasename() . \"\\n\";" " echo $fileinfo->getBasename('.cpp') . \"\\n\";" " echo $fileinfo->getGroup() . \"\\n\";" " echo $fileinfo->getInode() . \"\\n\";" " echo $fileinfo->getMTime() . \"\\n\";" " echo $fileinfo->getOwner() . \"\\n\";" " echo $fileinfo->getPerms() . \"\\n\";" " echo $fileinfo->getSize() . \"\\n\";" " echo $fileinfo->getType() . \"\\n\";" " echo $fileinfo->isDir() . \"\\n\";" " echo $fileinfo->isDot() . \"\\n\";" " echo $fileinfo->isExecutable() . \"\\n\";" " echo $fileinfo->isLink() . \"\\n\";" " echo $fileinfo->isReadable() . \"\\n\";" " echo $fileinfo->isWritable() . \"\\n\";" " echo \"END\" . \"\\n\";" " }" "}" "$iterator = new RecursiveDirectoryIterator(\"test\");" "foreach ($iterator as $fileinfo) {" " if ($fileinfo->isFile()) {" " echo $fileinfo->getFilename() . \"\\n\";" " echo $fileinfo->getCTime() . \"\\n\";" " echo $fileinfo->getBasename() . \"\\n\";" " echo $fileinfo->getBasename('.cpp') . \"\\n\";" " echo $fileinfo->getFilename() . \"\\n\";" " echo $fileinfo->getGroup() . \"\\n\";" " echo $fileinfo->getInode() . \"\\n\";" " echo $fileinfo->getMTime() . \"\\n\";" " echo $fileinfo->getOwner() . \"\\n\";" " echo $fileinfo->getPerms() . \"\\n\";" " echo $fileinfo->getSize() . \"\\n\";" " echo $fileinfo->getType() . \"\\n\";" " echo $fileinfo->isDir() . \"\\n\";" " echo $fileinfo->isExecutable() . \"\\n\";" " echo $fileinfo->isLink() . \"\\n\";" " echo $fileinfo->isReadable() . \"\\n\";" " echo $fileinfo->isWritable() . \"\\n\";" " }" "}"); MVCR("valid()) {" " if(!$dir->isDot()) {" " print $dir->current().\"\\n\";" " }" " $dir->next();" "}"); MVCR("$cur) {" " $filesize=$cur->getSize();" " $bytestotal+=$filesize;" " $nbfiles++;" " echo \"$filename => $filesize\\n\";" "}" "$bytestotal=number_format($bytestotal);" "echo \"Total: $nbfiles files, $bytestotal bytes\\n\";"); MVCR("$cur) {" " if (substr($filename,-1)=='.') continue;" " $filesize=$cur->getSize();" " $bytestotal+=$filesize;" " $nbfiles++;" " echo \"$filename => $filesize\\n\";" "}" "$bytestotal=number_format($bytestotal);" "echo \"Total: $nbfiles files, $bytestotal bytes\\n\";"); MVCR(" $info) {" " if ($info->isDir() && substr($file,-1)!='.') {" " echo $file.\"\\n\";" " }" "}"); MVCR(" $fileSPLObject ) {" " if (substr($fullFileName,-1)=='.') continue;" " print $fullFileName . \" \" .$fileSPLObject->getFilename(). \"\\n\";" "}" "$fileSPLObjects = new RecursiveIteratorIterator(" " new RecursiveDirectoryIterator($directory)," " RecursiveIteratorIterator::CHILD_FIRST);" "foreach( $fileSPLObjects as $fullFileName => $fileSPLObject ) {" " if (substr($fullFileName,-1)=='.') continue;" " print $fullFileName . \" \" .$fileSPLObject->getFilename(). \"\\n\";" "}" "$fileSPLObjects = new RecursiveIteratorIterator(" " new RecursiveDirectoryIterator($directory)," " RecursiveIteratorIterator::LEAVES_ONLY);" "foreach( $fileSPLObjects as $fullFileName => $fileSPLObject ) {" " if (substr($fullFileName,-1)=='.') continue;" " print $fullFileName . \" \" .$fileSPLObject->getFilename(). \"\\n\";" "}" "// invalid mode -100" "$fileSPLObjects = new RecursiveIteratorIterator(" " new RecursiveDirectoryIterator($directory), -100);" "foreach( $fileSPLObjects as $fullFileName => $fileSPLObject ) {" " if (substr($fullFileName,-1)=='.') continue;" " print $fullFileName . \" \" .$fileSPLObject->getFilename(). \"\\n\";" "}"); MVCR("rewind();$rdi->valid();$rdi->next()) {" " if ($rdi->isDot()) continue;" " if ($rdi->isDir() || $rdi->isFile()) {" " for ($i = 0; $i<=$depth;++$i) echo \" \";" " echo $rdi->current().\"\\n\";" " if ($rdi->hasChildren()) getFiles($rdi->getChildren(),1+$depth);" " }" " }" "}" "getFiles(new RecursiveDirectoryIterator('test'));"); MVCR("next();" "} catch (UnexpectedValueException $e) {" "}" "var_dump('ok');"); MVCR("getInnerIterator()->current() % 2 == 0;\n" " }\n" "}\n" "$i = new EvensOnly(new ArrayIterator(range(0, 10)));\n" "foreach ($i as $v) {\n" " var_dump($v);\n" "}\n"); MVCR(" 'http://test-uri'));" "$str = ''." " ''." " ''." " '16'." " '21'." " ' ';" "$server->addFunction('Add');" "$server->handle($str);"); MVCR(" 'bar'))->pub);"); return true; } bool TestCodeRun::TestExtCollator() { MVCR("compare( $str1, $str2 ) : collator_compare( $coll, $str1, $str2 );\n" "}\n" "function ut_coll_sort_with_sort_keys( $coll, &$arr )\n" "{\n" " return $GLOBALS['oo-mode'] ? \n" " $coll->sortWithSortKeys( $arr ) : collator_sort_with_sort_keys( $coll, $arr );\n" "}\n" "function ut_coll_sort( $coll, &$arr, $sort_flag = Collator::SORT_REGULAR )\n" "{\n" " return $GLOBALS['oo-mode'] ? \n" " $coll->sort( $arr, $sort_flag ) : collator_sort( $coll, $arr, $sort_flag );\n" "}\n" "function ut_coll_asort( $coll, &$arr, $sort_flag = Collator::SORT_REGULAR )\n" "{\n" " return $GLOBALS['oo-mode'] ? \n" " $coll->asort( $arr, $sort_flag ) : collator_asort( $coll, $arr, $sort_flag );\n" "}\n" "function ut_coll_get_locale( $coll, $type )\n" "{\n" " return $GLOBALS['oo-mode'] ? \n" " $coll->getLocale( $type ) : collator_get_locale( $coll, $type );\n" "}\n" "function ut_coll_set_strength( $coll, $strength )\n" "{\n" " return $GLOBALS['oo-mode'] ? \n" " $coll->setStrength( $strength ) : collator_set_strength( $coll, $strength );\n" "}\n" "function ut_coll_set_attribute( $coll, $attr, $val )\n" "{\n" " return $GLOBALS['oo-mode'] ? \n" " $coll->setAttribute( $attr, $val ) : collator_set_attribute( $coll, $attr, $val );\n" "}\n" "function ut_coll_set_default( $coll )\n" "{\n" " return $GLOBALS['oo-mode'] ? Collator::setDefault( $coll ) : collator_set_default( $coll );\n" "}\n" "$test_num = 1;\n" "function sort_arrays( $locale, $arrays, $sort_flag = Collator::SORT_REGULAR )\n" "{\n" " $res_str = '';\n" " $coll = ut_coll_create( $locale );\n" " foreach( $arrays as $array )\n" " {\n" " // Sort array values\n" " $res_val = ut_coll_sort( $coll, $array, $sort_flag );\n" " // Concatenate the sorted array and function result\n" " // with output string.\n" " $res_dump = \"\\n\" . dump( $array ) .\n" " \"\\n Result: \" . dump( $res_val );\n" " // Preppend test signature to output string\n" " $md5 = md5( $res_dump );\n" " global $test_num;\n" " \n" " $res_str .= \"\\n\\n\".\n" " \"Test $test_num.$md5:\" .\n" " $res_dump;\n" " ++$test_num;\n" " }\n" " return $res_str;\n" "}\n" "function ut_main1()\n" "{\n" " global $test_num;\n" " $test_num = 1;\n" " $res_str = '';\n" " // Sort an array in SORT_REGULAR mode using en_US locale.\n" " $test_params = array(\n" " array( 'abc', 'abd', 'aaa' ),\n" " array( 'm' , '1' , '_' ),\n" " array( 'a' , 'aaa', 'aa' ),\n" " array( 'ba' , 'b' , 'ab' ),\n" " array( 'e' , 'c' , 'a' ),\n" " array( '100', '25' , '36' ), // test 6\n" " array( 5 , '30' , 2 ),\n" " array( 'd' , '' , ' a' ),\n" " array( 'd ' , 'f ' , ' a' ),\n" " array( 'a' , null , '3' ),\n" " array( 'y' , 'k' , 'i' )\n" " );\n" " $res_str .= sort_arrays( 'en_US', $test_params );\n" " $test_params = array(\n" " array( '100', '25' , '36' ),\n" " array( 5 , '30' , 2 ), // test 13\n" " array( 'd' , '' , ' a' ),\n" " array( 'y' , 'k' , 'i' )\n" " );\n" " // Sort in en_US locale with SORT_STRING flag\n" " $res_str .= sort_arrays( 'en_US', $test_params, Collator::SORT_STRING );\n" " // Sort a non-ASCII array using ru_RU locale.\n" " $test_params = array(\n" " array( '\xd0\xb0\xd0\xb1\xd0\xb3', " " '\xd0\xb0\xd0\xb1\xd0\xb2', " " '\xd0\xb0\xd0\xb0\xd0\xb0', " " '\xd0\xb0\xd0\xb1\xd0\xb2' ),\n" " array( '\xd0\xb0\xd0\xb0', '\xd0\xb0\xd0\xb0\xd0\xb0'," " '\xd0\xb0' )\n" " );\n" " $res_str .= sort_arrays( 'ru_RU', $test_params );\n" " // Sort an array using Lithuanian locale.\n" " $test_params = array(\n" " array( 'y' , 'k' , 'i' )\n" " );\n" " $res_str .= sort_arrays( 'lt_LT', $test_params );\n" " return $res_str;\n" "}\n" "ut_run('ut_main1');\n" "function ut_main2() {\n" " $obj = ut_coll_create('en_US');\n" " $arr0 = array( 100, 25, 36, '30.2', '30.12' ); // test 6\n" " $arr1 = array( '100', '25', '36' ); // test 6\n" " $arr2 = array( 11, 5, '2', 64, 17, '30', 10, 2, '54' );\n" " // strcmp 17 and 30, ret = 1\n" " // Comparing values 17 and 30, ret = 1\n" " $arr3 = array( 11, 5, 2, 64, 17, 30, 10, 2, 54 );\n" " $arrA = $arr0;\n" " $arrB = $arr0;\n" " $arrC = $arr0;\n" " ut_coll_sort($obj, $arrA, Collator::SORT_REGULAR);\n" " ut_coll_sort($obj, $arrB, Collator::SORT_STRING);\n" " ut_coll_sort($obj, $arrC, Collator::SORT_NUMERIC);\n" " var_dump($arrA, $arrB, $arrC);\n" " $arrA = $arr1;\n" " $arrB = $arr1;\n" " $arrC = $arr1;\n" " ut_coll_sort($obj, $arrA, Collator::SORT_REGULAR);\n" " ut_coll_sort($obj, $arrB, Collator::SORT_STRING);\n" " ut_coll_sort($obj, $arrC, Collator::SORT_NUMERIC);\n" " var_dump($arrA, $arrB, $arrC);\n" " $arrA = $arr2;\n" " $arrB = $arr2;\n" " $arrC = $arr2;\n" " ut_coll_sort($obj, $arrA, Collator::SORT_REGULAR);\n" " ut_coll_sort($obj, $arrB, Collator::SORT_STRING);\n" " ut_coll_sort($obj, $arrC, Collator::SORT_NUMERIC);\n" " var_dump($arrA, $arrB, $arrC);\n" " $arrA = $arr3;\n" " $arrB = $arr3;\n" " $arrC = $arr3;\n" " ut_coll_sort($obj, $arrA, Collator::SORT_REGULAR);\n" " ut_coll_sort($obj, $arrB, Collator::SORT_STRING);\n" " ut_coll_sort($obj, $arrC, Collator::SORT_NUMERIC);\n" " var_dump($arrA, $arrB, $arrC);\n" "}\n" "ut_run('ut_main2');\n" "function ut_main3()\n" "{\n" " $res_str = '';\n" " $locales = array(\n" " 'EN-US-ODESSA',\n" " 'UK_UA_ODESSA',\n" " 'uk-ua_CALIFORNIA@currency=;currency=GRN',\n" " '',\n" " 'root',\n" " 'uk@currency=EURO'\n" " );\n" " foreach( $locales as $locale )\n" " {\n" " // Create Collator with the current locale.\n" " $coll = ut_coll_create( $locale );\n" " if( !is_object($coll) )\n" " {\n" " $res_str .= \"Error creating collator with '$locale' locale: \" .\n" " intl_get_error_message() . \"\\n\";\n" " continue;\n" " }\n" " // Get the requested, valid and actual locales.\n" " $vloc = ut_coll_get_locale( $coll, Locale::VALID_LOCALE );\n" " // Show them.\n" " $res_str .= \"Locale: '$locale'\\n\" .\n" " \" ULOC_VALID_LOCALE = '$vloc'\\n\";\n" " }\n" " return $res_str;\n" "}\n" "ut_run('ut_main3');\n" "function test_COW( $locale, $test_array )\n" "{\n" " $res_str = '';\n" " $coll = ut_coll_create( $locale );\n" " // Create two copies of the given array.\n" " $copy1 = $test_array;\n" " $copy2 = $test_array;\n" " // Sort given array and the first copy of it.\n" " ut_coll_sort( $coll, $test_array );\n" " ut_coll_sort( $coll, $copy1 );\n" " // Return contents of all the arrays.\n" " // The second copy should remain unsorted.\n" " $res_str .= dump( $test_array ) . \"\\n\";\n" " $res_str .= dump( $copy1 ) . \"\\n\";\n" " $res_str .= dump( $copy2 ) . \"\\n\";\n" " return $res_str;\n" "}\n" "function ut_main4()\n" "{\n" " $res_str = '';\n" " $a1 = array( 'b', 'a', 'c' );\n" " $a2 = array( '\xd0\xb1', '\xd0\xb0', '\xd0\xb2' );\n" " $res_str .= test_COW( 'en_US', $a1 );\n" " $res_str .= test_COW( 'ru_RU', $a2 );\n" " return $res_str;\n" "}\n" "ut_run('ut_main4');\n" "function cmp_array( &$coll, $a )\n" "{\n" " $res = '';\n" " $prev = null;\n" " foreach( $a as $i )\n" " {\n" " if( is_null( $prev ) )\n" " $res .= \"$i\";\n" " else\n" " {\n" " $eqrc = ut_coll_compare( $coll, $prev, $i );\n" " $eq = $eqrc < 0 ? \"<\" : ( $eqrc > 0 ? \">\" : \"=\" );\n" " $res .= \" $eq $i\";\n" " }\n" " $prev = $i;\n" " }\n" " $res .= \"\\n\";\n" " return $res;\n" "}\n" "function check_alternate_handling( &$coll )\n" "{\n" " $res = '';\n" " ut_coll_set_strength( $coll, Collator::TERTIARY );\n" " ut_coll_set_attribute( $coll, Collator::ALTERNATE_HANDLING, Collator::NON_IGNORABLE );\n" " $res .= cmp_array( $coll, array( 'di Silva', 'Di Silva', 'diSilva', 'U.S.A.', 'USA' ) );\n" " ut_coll_set_attribute( $coll, Collator::ALTERNATE_HANDLING, Collator::SHIFTED );\n" " $res .= cmp_array( $coll, array( 'di Silva', 'diSilva', 'Di Silva', 'U.S.A.', 'USA' ) );\n" " ut_coll_set_strength( $coll, Collator::QUATERNARY );\n" " $res .= cmp_array( $coll, array( 'di Silva', 'diSilva', 'Di Silva', 'U.S.A.', 'USA' ) );\n" " $res .= \"\\n\";\n" " return $res;\n" "}\n" "function ut_main5()\n" "{\n" " $coll = ut_coll_create( 'en_US' );\n" " return\n" " check_alternate_handling( $coll );\n" "}\n" "ut_run('ut_main5');\n" "function sort_arrays_with_sort_keys( $locale, $arrays )\n" "{\n" " $res_str = '';\n" " $coll = ut_coll_create( $locale );\n" " foreach( $arrays as $array )\n" " {\n" " // Sort array values\n" " $res_val = ut_coll_sort_with_sort_keys( $coll, $array );\n" " // Concatenate the sorted array and function result\n" " // with output string.\n" " $res_dump = \"\\n\" . dump( $array ) .\n" " \"\\n Result: \" . dump( $res_val );\n" " \n" " \n" " // Preppend test signature to output string\n" " $md5 = md5( $res_dump );\n" " global $test_num;\n" " $res_str .= \"\\n\\n\".\n" " \"Test $test_num.$md5:\" .\n" " $res_dump;\n" " ++$test_num;\n" " }\n" " return $res_str;\n" "}\n" "function ut_main6()\n" "{\n" " global $test_num;\n" " $test_num = 1;\n" " $res_str = '';\n" " // Sort an array in SORT_REGULAR mode using en_US locale.\n" " $test_params = array(\n" " array( 'abc', 'abd', 'aaa' ),\n" " array( 'm' , '1' , '_' ),\n" " array( 'a' , 'aaa', 'aa' ),\n" " array( 'ba' , 'b' , 'ab' ),\n" " array( 'e' , 'c' , 'a' ),\n" " array( 'd' , '' , ' a' ),\n" " array( 'd ' , 'f ' , ' a' ),\n" " array( 'a' , null , '3' ),\n" " array( 'y' , 'i' , 'k' )\n" " );\n" " $res_str .= sort_arrays_with_sort_keys( 'en_US', $test_params );\n" " // Sort a non-ASCII array using ru_RU locale.\n" " $test_params = array(\n" " array( '\xd0\xb0\xd0\xb1\xd0\xb3', " " '\xd0\xb0\xd0\xb1\xd0\xb2', " " '\xd0\xb0\xd0\xb0\xd0\xb0', " " '\xd0\xb0\xd0\xb1\xd0\xb2' ),\n" " array( '\xd0\xb0\xd0\xb0', '\xd0\xb0\xd0\xb0\xd0\xb0'," " '\xd0\xb0' )\n" " );\n" " $res_str .= sort_arrays_with_sort_keys( 'ru_RU', $test_params );\n" " // Array with data for sorting.\n" " $test_params = array(\n" " array( 'y' , 'i' , 'k' )\n" " );\n" " // Sort an array using Lithuanian locale.\n" " $res_str .= sort_arrays_with_sort_keys( 'lt_LT', $test_params );\n" " return $res_str . \"\\n\";\n" "}\n" "ut_run('ut_main6');\n" ); return true; } bool TestCodeRun::TestExtSocket() { MVCR(" 2\n" " [1] => 2\n" ")\n" "Array\n" "(\n" " [0] => 2\n" " [1] => 2\n" ")\n" "Array\n" "(\n" " [0] => 3\n" " [1] => 3\n" ")\n" ); MVCRO("v = 100; } }\n" "$a = array(array(1, 2, 3), new A());\n" "apc_store('0', $a);\n" "$b = apc_fetch(0);\n" "var_dump($b[1]->v);\n" "$b[1]->f();\n" // SharedMap::get() needs caching "var_dump($b[1]->v);\n" "$b[2] = 1;\n" // SharedMap::escalate() needs caching "var_dump($b[1]->v);\n", "int(10)\n" "int(100)\n" "int(100)\n" ); MVCRO("\n" " int(100)\n" " [\"b\":\"A\":private]=>\n" " int(10)\n" "}\n" ); MVCRO("a = 5; $a->b = &$a->a;\n" "apc_store('key', $a);\n" "var_dump(apc_fetch('key'));\n", "object(A)#2 (2) {\n" " [\"a\"]=>\n" " &int(5)\n" " [\"b\"]=>\n" " &int(5)\n" "}\n" ); MVCRO("\n" " int(10)\n" "}\n" ); // objects in an apc array can be changed without escalating the array MVCRO("i = 100;\n" "apc_store('key2', $b);\n" "$t = apc_fetch('key2');\n" "var_dump($t[0]->i);\n", "int(100)\n"); // Serializable object in APC MVCRO("a); }\n" " function unserialize($s) { $this->a = unserialize($s); }\n" "}\n" "$o = new A;\n" "apc_store('key', $o);\n" "$r = apc_fetch('key');\n" "var_dump($r);\n", "object(A)#2 (1) {\n" " [\"a\"]=>\n" " int(123)\n" "}\n"); for (int i = 0; i < 2; i++) { string cfg = "-vServer.APC.AllowObject=" + boost::lexical_cast(i); OptionSetter w(this, OptionSetter::RunTime, cfg.c_str()); // apc_fetch twice to trigger immutable object MVCRO("a = $i * $i;" " $this->b = $j * $j;" " $this->c = $k * $k;" " }" " public $a;" " protected $b;" " private $c;" " public $aa = 'aa';" " protected $bb = false;" " private $cc = 1.22;" "}" "class B extends A {" " public function __construct($i, $j, $k) {" " $this->a = $i + $i;" " $this->b = $j + $j;" " $this->c = $k + $k;" " }" " public $a;" " protected $b;" " private $c;" " public $aa = 'aaa';" " protected $bb = 4;" " private $cc = 1.222;" "}" "class C extends B {" " public function __construct($i, $j, $k) {" " $this->a = $i + $i + $i;" " $this->b = $j + $j + $j;" " $this->c = $k + $k + $k;" " }" " public $a;" " protected $b;" " private $c;" " public $aa = 'aaaa';" " protected $bb = 40;" " private $cc = 1.333;" "}" "class D extends C {" " public function __construct($i, $j, $k) {" " $this->a = $i + $i + $i;" " $this->b = $j + $j + $j;" " $this->c = $k + $k + $k;" " }" " public $a;" " public $b;" " private $c;" " public $aa = 'aaaaa';" " public $bb = 400;" " private $cc = 1.3333;" "}" "function foo() {" " $obj = new A(111, 222, 333);" " apc_store('foobar', $obj);" " $obj = apc_fetch('foobar');" " $obj = apc_fetch('foobar');" " var_dump($obj);" " $obj = new B(111, 222, 333);" " apc_store('foobar', $obj);" " $obj = apc_fetch('foobar');" " $obj = apc_fetch('foobar');" " var_dump($obj);" " $obj = new C(111, 222, 333);" " apc_store('foobar', $obj);" " $obj = apc_fetch('foobar');" " $obj = apc_fetch('foobar');" " var_dump($obj);" " $obj = new D(111, 222, 333);" " apc_store('foobar', $obj);" " $obj = apc_fetch('foobar');" " $obj = apc_fetch('foobar');" " var_dump($obj);" "}" "foo();", "object(A)#3 (6) {\n" " [\"a\"]=>\n" " int(12321)\n" " [\"b\":protected]=>\n" " int(49284)\n" " [\"c\":\"A\":private]=>\n" " int(110889)\n" " [\"aa\"]=>\n" " string(2) \"aa\"\n" " [\"bb\":protected]=>\n" " bool(false)\n" " [\"cc\":\"A\":private]=>\n" " float(1.22)\n" "}\n" "object(B)#6 (8) {\n" " [\"a\"]=>\n" " int(222)\n" " [\"b\":protected]=>\n" " int(444)\n" " [\"c\":\"B\":private]=>\n" " int(666)\n" " [\"aa\"]=>\n" " string(3) \"aaa\"\n" " [\"bb\":protected]=>\n" " int(4)\n" " [\"cc\":\"B\":private]=>\n" " float(1.222)\n" " [\"c\":\"A\":private]=>\n" " NULL\n" " [\"cc\":\"A\":private]=>\n" " float(1.22)\n" "}\n" "object(C)#9 (10) {\n" " [\"a\"]=>\n" " int(333)\n" " [\"b\":protected]=>\n" " int(666)\n" " [\"c\":\"C\":private]=>\n" " int(999)\n" " [\"aa\"]=>\n" " string(4) \"aaaa\"\n" " [\"bb\":protected]=>\n" " int(40)\n" " [\"cc\":\"C\":private]=>\n" " float(1.333)\n" " [\"c\":\"B\":private]=>\n" " NULL\n" " [\"cc\":\"B\":private]=>\n" " float(1.222)\n" " [\"c\":\"A\":private]=>\n" " NULL\n" " [\"cc\":\"A\":private]=>\n" " float(1.22)\n" "}\n" "object(D)#12 (12) {\n" " [\"a\"]=>\n" " int(333)\n" " [\"b\"]=>\n" " int(666)\n" " [\"c\":\"D\":private]=>\n" " int(999)\n" " [\"aa\"]=>\n" " string(5) \"aaaaa\"\n" " [\"bb\"]=>\n" " int(400)\n" " [\"cc\":\"D\":private]=>\n" " float(1.3333)\n" " [\"c\":\"C\":private]=>\n" " NULL\n" " [\"cc\":\"C\":private]=>\n" " float(1.333)\n" " [\"c\":\"B\":private]=>\n" " NULL\n" " [\"cc\":\"B\":private]=>\n" " float(1.222)\n" " [\"c\":\"A\":private]=>\n" " NULL\n" " [\"cc\":\"A\":private]=>\n" " float(1.22)\n" "}\n"); } MVCRO("map = $f;\n" " }\n" "}\n" "class E {\n" " protected $map;\n" " public function __construct($f) {\n" " $this->map = $f;\n" " }\n" " public function getMap() {\n" " return $this->map;\n" " }\n" "}\n" "$f = new stdclass();\n" "$arr = array(new E($f), new D($f));\n" "apc_store('ggg', $arr);\n" "$arr2 = apc_fetch('ggg');\n" "var_dump($arr[0]->getMap());\n" "var_dump($arr[1]->map);\n" "var_dump($arr2[0]->getMap());\n" "var_dump($arr2[1]->map);\n" , "object(stdClass)#1 (0) {\n" "}\n" "object(stdClass)#1 (0) {\n" "}\n" "object(stdClass)#5 (0) {\n" "}\n" "object(stdClass)#5 (0) {\n" "}\n" ); MVCRO("p = &$v;\n" "$o2->p = &$v;\n" "$arr1 = array($o1, $o2);\n" "apc_store('foo', $arr1);\n" "$arr2 = apc_fetch('foo');\n" "var_dump($arr1);\n" "var_dump($arr2);\n" , "array(2) {\n" " [0]=>\n" " object(stdClass)#1 (1) {\n" " [\"p\"]=>\n" " &int(42)\n" " }\n" " [1]=>\n" " object(stdClass)#2 (1) {\n" " [\"p\"]=>\n" " &int(42)\n" " }\n" "}\n" "array(2) {\n" " [0]=>\n" " object(stdClass)#3 (1) {\n" " [\"p\"]=>\n" " &int(42)\n" " }\n" " [1]=>\n" " object(stdClass)#4 (1) {\n" " [\"p\"]=>\n" " &int(42)\n" " }\n" "}\n" ); { HipHopSyntax w(this); MVCRO("cache_gen = $x->gen('a', 'b'); " "foreach ($x->cache_gen as $v) { var_dump($v); } " "apc_store('key', $x); " "$y = apc_fetch('key'); " "print_r($y->cache_gen);", "string(1) \"a\"\n" "string(1) \"b\"\n" "DummyContinuation Object\n" "(\n" ")\n" ); MVCRO("\n" " string(4) \"afoo\"\n" " [1]=>\n" " array(1) {\n" " [0]=>\n" " string(3) \"foo\"\n" " }\n" "}\n"); MVCRO("\n" " object(X)#2 (0) {\n" " }\n" " [1]=>\n" " object(X)#2 (0) {\n" " }\n" " [2]=>\n" " object(X)#2 (0) {\n" " }\n" "}\n" "array(3) {\n" " [0]=>\n" " object(X)#3 (0) {\n" " }\n" " [1]=>\n" " object(X)#3 (0) {\n" " }\n" " [2]=>\n" " object(X)#3 (0) {\n" " }\n" "}\n"); return true; } bool TestCodeRun::TestInlining() { OptionSetter w(this, OptionSetter::CompileTime, "-vAutoInline=5"); MVCR("f();" "}" "var_dump(test());"); MVCR("';" "}" "function test() {" " echo foo();" "}" "test();"); MVCR("x = $x; } }" "class X extends B {" " function __construct() { parent::__construct(array()); }" " function foo() { echo \"foo\n\"; }" "}" "function bar($x=0) { if ($x) return 1; return ''; }" "function test($foo) {" " id(new X(bar()))->foo();" " id(new $foo(bar()))->foo();" "}" "test('X');"); MVCR("t();" "}"); MVCR("bar = 1;" "}"); MVCR(" $tr_row) {" " if ($tr_row == 45) $temp_tr = $tr_id;" " if ($tr_id == 0) {" " continue;" " } else {" " return $tr_row;" " }" " }" " if ($temp_tr) {" " return $temp_tr;" " }" " return null;" "}" "var_dump(test(array('a' => 1, 'b' => 45)));"); MVCR("map = $map;" " $this->parents = $parents;" " }" "}"); MVCR("o = $this;" " $this->a = array(1,2,3);" " $this->o2 = $this;" " }" "}" "function test() {" " $x = new X;" " $x->foo();" " $s = serialize($x);" " var_dump($s);" " $y = unserialize($s);" " var_dump($y);" "}" "test();"); return true; } bool TestCodeRun::TestHoisting() { MVCR("f4(3);\n"); MVCR("f4missing(3);\n" "echo \"finish\n\";\n"); MVCR("foo();}\n" "}\n" "class G extends B {\n" " function foo() { var_dump(__CLASS__);}\n" " function f4missing() { $b = func(); $b::f4missing();}\n" "}\n" "$g = new G; $g->f4missing();\n"); return true; } bool TestCodeRun::TestLateStaticBinding() { MVCR( "foo();\n" " static::g();\n" " $y->foo();\n" " self::g();\n" " Y::foo() && static::g();\n" " }\n" " static function g() { var_dump(__CLASS__); }\n" "}\n" "class Y extends X {\n" " static function g() { var_dump(__CLASS__); }\n" " static function foo() { return true; }\n" "}\n" "function test() {\n" " $x = new X;\n" " $y = new Y;\n" " $x->f();\n" " $y->f();\n" "}\n" "test();\n" ); MVCR( "foo(); // $this changes 'static'\n" " parent::foo(); // 'parent' doesn't change 'static'\n" " }\n" "}\n" "\n" "$a = new A();\n" "$b = new B();\n" "\n" "B::foo(); // B\n" "$b->foo(); // B\n" "\n" "$b->foo2(); // BB\n" "$b->foo3(); // BB\n" "\n" "A::foo(); // A\n" "$a->foo(); // A\n" "\n" "$a->foo2(); // BA\n" ); MVCR("baz();\n" "Y::baz();\n"); MVCR("f(); }\n" " }\n" "} else {\n" " class A { }\n" "}\n" "class B extends A { static $a = 'B'; }\n" "$b = new B;\n" "$b->g();\n"); // instanceof static and new static MVCR("bar();\n" "self::test();\n" "}\n" "}\n" "class Foo {\n" "public function bar() {}\n" "}\n" "$obj = new Foo();\n" "TestA::nativeTest($obj);\n"); MVCR("foo('y');" "$x->foo(new Y);"); MVCR("fiz(self::foo());\n" " }\n" " function fiz($x) {}\n" "}\n" "class B extends A {}\n" "$array = array('foo');\n" "array_map('B::foo', $array);\n" "call_user_func('B::foo');\n" "call_user_func(array('B', 'foo'));\n" "A::bar();\n"); if (false) { MVCR("getMethod('foo')->invoke($o);" " $x->getMethod('foo')->invoke(null);" " $x->getMethod('bar')->invoke($o);" "}" "test(new ReflectionClass('X'), new X);" "test(new ReflectionClass('Y'), new X);" // "test(new ReflectionClass('X'), new Y);" // "test(new ReflectionClass('Y'), new Y);" "test(new ReflectionClass('X'), new X);" // "test(new ReflectionClass('X'), new Z);" "test(new ReflectionClass('Z'), new Z);" "call_user_func(array(new Y, 'X::foo'));" "call_user_func(array(new Z, 'X::foo'));"); MVCR("foo();"); return true; } bool TestCodeRun::TestCallStatic() { MVCRO("test1a();\n", "d2::__call\n" // "c2::__callStatic\n" <--- PHP 5.3 returns this ); MVCRO("test1a();\n" "var_dump('end');\n", "d2::__call\n" "string(3) \"end\"\n" // "string(7) \"errored\"\n" <--- PHP 5.3 returns this ); MVCRO("test1a();\n" "var_dump('end');\n", "c2::__call\n" "string(3) \"end\"\n" // "string(7) \"errored\"\n" <--- PHP 5.3 returns this ); MVCR("test();\n"); MVCRO("test();\n" "var_dump('end');\n", "string(7) \"errored\"\n" ); MVCR("test();\n" "$obj = new b2;\n" "$obj->test();\n"); MVCR("test();\n" "$obj = new b1;\n" "$obj->test();\n"); MVCR("test();\n" "$obj = new b2;\n" "$obj->test();\n"); MVCR("test();\n" "$obj = new b1;\n" "$obj->test();\n"); MVCR("test();\n" "$obj = new b2;\n" "$obj->test();\n"); MVCR("runTest('in object context');\n" "MethodTest::runTest('in static context');\n"); MVCR("f(42);\n"); MVCR("getMessage());" " }" " var_dump('after try2');" " } catch (Exception $e) {" " l2: var_dump($e->getMessage());" " } catch (MyException $m) {" " l3: var_dump($m->getMessage());" " }" " var_dump('after try1');" "}" "for ($i = 0; $i < 16; $i++) foo($i);"); MVCR(" 2; }; echo $a(4).\"\n\";" " echo call_user_func_array($a, array(4));"); MVCR("'bar'));"); MVCR("goo($p);" " }, $values);" " var_dump($values);" " }" " public function bar() { return $this; }" " public function goo($p) { return $p; }" "}" "$obj = new A;" "var_dump($obj->bar());" "$obj->foo();", "object(A)#1 (0) {\n" "}\n" "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" " [2]=>\n" " int(3)\n" "}\n"); return true; } bool TestCodeRun::TestNamespace() { MVCR("fiz();" " var_dump(true);" " var_dump(false);" " var_dump(null);" " var_dump(INF);" " var_dump(FIZ);" " var_dump(FUZ);" " var_dump(\\FUZ);" "}"); MVCR("fruit() as $fruit) { var_dump($fruit);} ", "string(5) \"apple\"\n" "string(6) \"banana\"\n" ); MVCRO(" $v1) {\n" " foreach ($a2 as $k2 => &$v2) {\n" " $v2 += $v1; yield $v2;\n" " }\n" " }\n" "}\n" "$a1 = array(1, 2);\n" "$a2 = array(1, 2);\n" "foreach (f($a1, $a2) as $v) { var_dump($v); }\n" "var_dump($a2[0], $a2[1]);\n", "int(2)\n" "int(3)\n" "int(4)\n" "int(5)\n" "int(4)\n" "int(5)\n"); // yield within anonymous function MVCRO("f();\n" "foreach ($f() as $v) { var_dump($v); }\n", "int(1)\n" "int(2)\n"); // Continuatin::send() MVCRO("next();\n" "var_dump($c->current());\n" "$c->send(2);\n" "var_dump($c->current());\n" "$c->send(array(3, 4));\n" "var_dump($c->current());\n", "int(1)\n" "int(2)\n" "int(4)\n"); MVCRO("bar(function() {yield 1; yield 2; yield 3;});" " }" " public function bar(Closure $c) {" " $a = $c();" " foreach ($a as $b) {" " echo $b.\"\\n\";" " }" " }" "}" "$a = new A();" "$a->foo();", "1\n" "2\n" "3\n"); MVCRO("doIt();\n" " } catch (Exception $e) {\n" " $res = $e->getMessage();\n" " }\n" " yield $res;\n" "}\n" "$x = new X;\n" "foreach (f($x) as $i) { var_dump($i); }\n", "string(6) \"foobar\"\n"); MVCRO("yielder() as $foo) { var_dump($foo); }\n" "\n" "// derive from redec gen\n" "class Foo {\n" " public function fooMsg() { return 'foo'; }\n" " public function fooGen() { yield $this->fooMsg(); }\n" "}\n" "if (get()) {\n" " class Bar extends Foo {\n" " public function fooMsg() { return 'bar'; }\n" " public function barMsg() { return 'bar'; }\n" " public function barGen() { yield $this->barMsg(); }\n" " }\n" "} else {\n" " class Bar extends Foo {}\n" "}\n" "$f = new Foo;\n" "foreach ($f->fooGen() as $foo) { var_dump($foo); }\n" "$b = new Bar;\n" "foreach ($b->fooGen() as $foo) { var_dump($foo); }\n" "foreach ($b->barGen() as $foo) { var_dump($foo); }\n" "\n" "// conditional derive from redec gen\n" "function get0() { return false; }\n" "function f($x) {\n" " if ($x) {\n" " if (get0()) {\n" " class X1 {\n" " public function msg() { return 'first, first'; }\n" " public function gen() { yield $this->msg(); }\n" " } \n" " } else {\n" " class X1 {\n" " public function msg() { return 'first, second'; }\n" " public function gen() { yield $this->msg(); }\n" " } \n" " } \n" " } else {\n" " if (get()) {\n" " class Y extends X1 {\n" " public function msg() { return 'second, first'; }\n" " public function gen() { yield $this->msg(); }\n" " } \n" " } else {\n" " class Y extends X1 {\n" " public function msg() { return 'second, second'; }\n" " public function gen() { yield $this->msg(); }\n" " } \n" " } \n" " }\n" " $x = $x ? new X1 : new Y;\n" " foreach ($x->gen() as $foo) { var_dump($foo); }\n" "}\n" "f(true);\n" "f(false);\n", "string(5) \"first\"\n" "string(3) \"foo\"\n" "string(3) \"bar\"\n" "string(3) \"bar\"\n" "string(13) \"first, second\"\n" "string(13) \"second, first\"\n"); MVCRO("foo('this') as $v) { var_dump($v); }\n", "int(5)\n"); // Test passing null to hphp_get_iterator() MVCRO("gen());" "t($b->foo());" "$a = new A;" "t($a->gen());" "t($a->foo());" , "string(1) \"B\"\n" "string(1) \"B\"\n" "string(1) \"A\"\n" "string(1) \"A\"\n" "string(1) \"B\"\n" "string(1) \"B\"\n" "string(1) \"A\"\n" "string(1) \"A\"\n" "string(1) \"B\"\n" "string(1) \"B\"\n" "string(1) \"A\"\n" "string(1) \"A\"\n"); // getting the original function MVCRO("getOrigFuncName());\n" "class X {\n" " function f($x) { yield $x; }\n" " static function g($x) { yield get_called_class(); }\n" "}\n" "class Y extends X {}\n" "$x = new X;\n" "$c = $x->f(32);\n" "var_dump($c->getOrigFuncName());\n" "$c = X::g(32);\n" "var_dump($c->getOrigFuncName());\n" "$c = Y::g(32);\n" "var_dump($c->getOrigFuncName());\n" "$fcn = function ($x) { yield $x; };\n" "$c = $fcn(32);\n" "var_dump($c->getOrigFuncName());\n", "string(1) \"f\"\n" "string(4) \"X::f\"\n" "string(4) \"X::g\"\n" "string(4) \"Y::g\"\n" "string(9) \"{closure}\"\n"); MVCRO("getMessage());" " yield 4;" " }" " yield 5;" "}" "foreach (gen() as $x) { var_dump($x); }" "$g = gen();" "$g->next();" "var_dump($g->current());" "$g->next();" "var_dump($g->current());" "$g->next();" "var_dump($g->current());" "$g->raise(new Exception('foobar'));" "var_dump($g->current());" "$g->next();" "var_dump($g->current());" , "int(1)\n" "int(2)\n" "int(3)\n" "int(5)\n" "int(1)\n" "int(2)\n" "int(3)\n" "string(6) \"foobar\"\n" "int(4)\n" "int(5)\n"); MVCRO("next();" "} catch(YieldedException $e) {" " try {" " $g->raise(new ReflectedException());" " } catch (Exception $e) {" " var_dump($e->getMessage());" " }" "}" , "string(33) \"Got yieldedException, re-raising.\"\n" "string(32) \"Continuation is already finished\"\n"); MVCRO("drc[$key] = true;" " yield (true);" " }" " public function edd($key) {" " if (array_key_exists($key, $this->drc)) {" " var_dump(true);" " } " " }" "}" "class C { use DY; }" "class D extends C { }" "$obj = new D;" "foreach($obj->dty('foo') as $var) {" " var_dump($var);" "}" "$obj->edd('foo');", "bool(true)\n" "bool(true)\n"); MVCRO("gpc();" " }" "}" "class C1 {" " use T;" " protected function gpc() {" " return 1;" " }" "}" "class C2 {" " use T;" " protected function gpc() {" " return 2;" " }" "}" "$obj1 = new C1();" "$obj2 = new C2();" "$c1 = $obj1->gen();" "$c2 = $obj2->gen();" "$c1->next();" "var_dump($c1->current());" "$c2->next();" "var_dump($c2->current());", "int(1)\n" "int(2)\n"); MVCRO("foo = 1;" " }" " var_dump($results);" " yield 1;" "}" "function bar() {" " foreach (foo(array()) as $r) {" " var_dump($r);" " }" "}" "bar();", "int(0)\n" "array(0) {\n" "}\n" "int(1)\n"); MVCRO("a; }" "}" "if (isset($g)) {" " class Y {}" "} else {" " class Y extends X {}" "}" "class Z extends Y {}" "function test() {" " $z = new Z;" " foreach ($z->foo() as $v) {" " var_dump($v);" " }" "}" "test();", "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" " [2]=>\n" " int(3)\n" "}\n"); // Testing destructor/assignment corner cases MVCRO("getMessage());\n" " }\n" " }\n" "}\n" "function dumpCurrent() {\n" " var_dump($GLOBALS['cont']->current());\n" " if (isset($GLOBALS['gonext'])) {\n" " $GLOBALS['cont']->next();\n" " }\n" "}\n" "function gen() {\n" " yield new Evil;\n" " yield null;\n" " yield new Evil;\n" " yield new Evil;\n" "}\n" "function main() {\n" " $GLOBALS['cont'] = $c = gen();\n" " $c->next();\n" "\n" " $c->send(new Evil);\n" " $GLOBALS['gonext'] = true;\n" " $c->next();\n" " $c->send(null);\n" " $c->send(null);\n" " echo \"Finished!\\n\";\n" "}\n" "main();\n" "echo \"Returned from main safely\\n\";\n" , "in __destruct()\n" "NULL\n" "in __destruct()\n" "NULL\n" "in __destruct()\n" "object(Evil)#4 (0) {\n" "}\n" "Caught: Continuation is already running\n" "in __destruct()\n" "NULL\n" "Caught: Continuation is already finished\n" "Finished!\n" "Returned from main safely\n"); MVCRO("data);\n" " }\n" " public function key() {\n" " return key($this->data);\n" " }\n" " public function next() {\n" " next($this->data);\n" " }\n" " public function rewind() {\n" " echo \"hagfish\\n\";\n" " reset($this->data);\n" " }\n" " public function valid() {\n" " return current($this->data);\n" " }\n" "}\n" "\n" "function run_test() {\n" " $f = new Foo();\n" "\n" " foreach ($f as $value) {\n" " echo $value . \"\\n\";\n" " }\n" "\n" " yield 1230;\n" "\n" " foreach($f as $value) {\n" " echo $value . \"\\n\";\n" " }\n" "}\n" "\n" "foreach (run_test() as $_) {}\n", "hagfish\n1\n2\n3\nhagfish\n1\n2\n3\n"); MVCRO("next();\n" " while ($gen->valid()) {\n" " var_dump($gen->current());\n" " $gen->next();\n" " }\n" " } catch (Exception $ex) {\n" " echo \"EXCEPTION\\n\";\n" " }\n" " var_dump($gen->valid());\n" " var_dump($gen->current());\n" "}\n", "Testing mode 0:\n" "int(0)\n" "int(47)\n" "bool(false)\n" "NULL\n" "Testing mode 1:\n" "int(1)\n" "bool(false)\n" "NULL\n" "Testing mode 2:\n" "int(2)\n" "EXCEPTION\n" "bool(false)\n" "NULL\n"); return true; } bool TestCodeRun::TestHint() { MVCR("generator() as $v) {\n" " var_dump($v);\n" "}\n", "int(1)\n" "int(2)\n"); MVCRO("getMethod('f');\n" " $params = $rf->getParameters();\n" " $first = true;\n" "\n" " $clsDecl = \"class Y extends X {\npublic function f(\";\n" " foreach ($params as $rp) {\n" " if (!$first) $clsDecl .= ', ';\n" " $first = false;\n" " $th = $rp->getTypehintText();\n" " if ($th) {\n" " $clsDecl .= ($th . ' ');\n" " }\n" " $clsDecl .= ('$' . $rp->getName());\n" " if ($rp->isDefaultValueAvailable()) {\n" " $clsDecl .= (' = ' . $rp->getDefaultValueText());\n" " }\n" " }\n" " $clsDecl .= \") {}\n}\n\";\n" " echo $clsDecl;\n" "}\n" "main();\n" , "class Y extends X {\n" "public function f($x1, $x2 = NULL, $x3 = 123, string $x4, " "string $x5 = NULL, string $x6 = \"abc\", array $x7, array $x8 = NULL, " "C $x9, D $x10 = NULL, bool $x11, boolean $x12 = true, int $x13, " "integer $x14 = 73, real $x15, double $x16 = 1.5, float $x17) {}\n" "}\n" ); return true; } bool TestCodeRun::TestUserAttributes() { HipHopSyntax w(this); MVCRO(">\n" "class C extends B {\n" " public function foo() { echo \"C::foo\\n\"; }\n" " public static function bar() { echo \"C::bar\\n\"; }\n" "}\n" "function test() {\n" " $obj = new C;\n" " $obj->foo();\n" " C::bar();\n" "}\n" "test();\n" , "C::foo\n" "C::bar\n"); MVCRO("> interface I {}\n" "<< Foo2, Bar2(), Baz2('blah',array(1,2)) >> trait T {}\n" "<< Foo3, Bar3(), Baz3('blah',array(1,2)) >> function f() {}\n" "<< Foo4, Bar4(), Baz4('blah',array(1,2)) >>\n" "function g() { yield null; }\n" "class C {\n" " << Foo5, Bar5(), Baz5('blah',array(1,2)) >>\n" " public function f() {}\n" " << Foo6, Bar6(), Baz6('blah',array(1,2)) >>\n" " public function g() { yield null; }\n" "}\n" "echo \"Done\\n\";\n" , "Done\n"); MVCRO(">\n" "class C {\n" " <>\n" " function f() {}\n" "}\n" "$rc = new ReflectionClass('C');\n" "$attrs = $rc->getAttributes();\n" "ksort($attrs);\n" "var_dump($attrs);\n" "$rm = $rc->getMethod('f');\n" "$attrs = $rm->getAttributes();\n" "ksort($attrs);\n" "var_dump($attrs);\n" "\n" "<>\n" "function f() {}\n" "$rf = new ReflectionFunction('f');\n" "$attrs = $rf->getAttributes();\n" "ksort($attrs);\n" "var_dump($attrs);\n" , "array(2) {\n" " [\"A\"]=>\n" " array(1) {\n" " [0]=>\n" " int(1)\n" " }\n" " [\"B\"]=>\n" " array(2) {\n" " [0]=>\n" " string(3) \"foo\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " int(42)\n" " [1]=>\n" " int(73)\n" " }\n" " }\n" "}\n" "array(2) {\n" " [\"A\"]=>\n" " array(1) {\n" " [0]=>\n" " int(2)\n" " }\n" " [\"B\"]=>\n" " array(2) {\n" " [0]=>\n" " string(3) \"bar\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " int(43)\n" " [1]=>\n" " int(74)\n" " }\n" " }\n" "}\n" "array(2) {\n" " [\"A\"]=>\n" " array(1) {\n" " [0]=>\n" " int(3)\n" " }\n" " [\"B\"]=>\n" " array(2) {\n" " [0]=>\n" " string(3) \"bar\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " int(44)\n" " [1]=>\n" " int(75)\n" " }\n" " }\n" "}\n"); MVCRO(">\n" "function f() {}\n" "$rf = new ReflectionFunction('f');\n" "var_dump($rf->getAttribute('A'));\n" "var_dump($rf->getAttribute('B'));\n" "var_dump($rf->getAttributes());\n" "var_dump($rf->getAttributeRecursive('A'));\n" "var_dump($rf->getAttributeRecursive('B'));\n" "var_dump($rf->getAttributesRecursive());\n" , "array(1) {\n" " [0]=>\n" " int(1)\n" "}\n" "NULL\n" "array(1) {\n" " [\"A\"]=>\n" " array(1) {\n" " [0]=>\n" " int(1)\n" " }\n" "}\n" "array(1) {\n" " [0]=>\n" " int(1)\n" "}\n" "NULL\n" "array(1) {\n" " [\"A\"]=>\n" " array(1) {\n" " [0]=>\n" " int(1)\n" " }\n" "}\n"); MVCRO(">\n" " private function foo() {}\n" "}\n" "class B extends A {}\n" "class C extends B {\n" " <>\n" " protected function foo() {}\n" "}\n" "class D extends C {}\n" "class E extends D {\n" " <>\n" " public function foo() {}\n" "}\n" "class F extends E {}\n" "\n" "$rm = new ReflectionMethod('F', 'foo');\n" "\n" "var_dump($rm->getAttribute('W'));\n" "var_dump($rm->getAttribute('X'));\n" "var_dump($rm->getAttribute('Y'));\n" "var_dump($rm->getAttribute('Z'));\n" "\n" "$attrs = $rm->getAttributes();\n" "ksort($attrs);\n" "var_dump($attrs);\n" "\n" "var_dump($rm->getAttributeRecursive('W'));\n" "var_dump($rm->getAttributeRecursive('X'));\n" "var_dump($rm->getAttributeRecursive('Y'));\n" "var_dump($rm->getAttributeRecursive('Z'));\n" "\n" "$attrs = $rm->getAttributesRecursive();\n" "ksort($attrs);\n" "var_dump($attrs);\n" , "NULL\n" "NULL\n" "array(1) {\n" " [0]=>\n" " int(5)\n" "}\n" "array(1) {\n" " [0]=>\n" " int(6)\n" "}\n" "array(2) {\n" " [\"Y\"]=>\n" " array(1) {\n" " [0]=>\n" " int(5)\n" " }\n" " [\"Z\"]=>\n" " array(1) {\n" " [0]=>\n" " int(6)\n" " }\n" "}\n" "NULL\n" "array(1) {\n" " [0]=>\n" " int(3)\n" "}\n" "array(1) {\n" " [0]=>\n" " int(5)\n" "}\n" "array(1) {\n" " [0]=>\n" " int(6)\n" "}\n" "array(3) {\n" " [\"X\"]=>\n" " array(1) {\n" " [0]=>\n" " int(3)\n" " }\n" " [\"Y\"]=>\n" " array(1) {\n" " [0]=>\n" " int(5)\n" " }\n" " [\"Z\"]=>\n" " array(1) {\n" " [0]=>\n" " int(6)\n" " }\n" "}\n"); MVCRO("getMethod($fn);\n" "}\n" "\n" "function show($fn, $class=null) {\n" " $rf = null;\n" " if ($class) {\n" " $rf = get_rf_for_method($fn, $class);\n" " } else {\n" " $rf = new ReflectionFunction($fn);\n" " }\n" " $params = $rf->getParameters();\n" " foreach ($params as $param) {\n" " echo \"{$param->getName()}:\\n\";\n" " $attrs = $param->getAttributes();\n" " ksort($attrs);\n" " var_dump($attrs);\n" " }\n" "}\n" "\n" "function showr($fn, $class=null) {\n" " $rf = null;\n" " if ($class) {\n" " $rf = get_rf_for_method($fn, $class);\n" " } else {\n" " $rf = new ReflectionFunction($fn);\n" " }\n" " $params = $rf->getParameters();\n" " foreach ($params as $param) {\n" " echo \"{$param->getName()}:\\n\";\n" " $attrs = $param->getAttributesRecursive();\n" " ksort($attrs);\n" " var_dump($attrs);\n" " }\n" "}\n" "\n" "function doboth($fn, $class=null) {\n" " echo \">>> \";\n" " if ($class) echo \"$class::\";\n" " echo \"$fn =>\\n---- non-recursive: ----\\n\";\n" " show($fn, $class);\n" " echo \"\\n---- recursive: ----\\n\";\n" " showr($fn, $class);\n" " echo \"\\n\";\n" "}\n" "\n" "//------------------------\n" "\n" "function no_attrs($p1, $p2) {}\n" "function simple_attr(<> $param) {}\n" "function two_attrs(<> $p1, <> $p2) {}\n" "\n" "class C {\n" " public static function m(<> $param) {}\n" " public static function n(<> $param) {}\n" " public function o(<> $param) {}\n" " public function p(<> $param) {}\n" " public function q(<> $tuv) {}\n" " public function wxy(<> $z, <> $wont_you_sing_with_me) {}\n" "}\n" "\n" "class D extends C {\n" " // Static functions shouldn't care about the parent class\n" " public static function m($param) {}\n" "\n" " // TODO: should we include n, and should m's attrs inherit from C::m?\n" "\n" " // Changing the value of the attribute\n" " public function o(<> $param) {}\n" "\n" " // Changing the name of the parameter\n" " public function q($rstuv) {}\n" "\n" " // Adding an attribute and leaving one off\n" " public function wxy(<> $z, $wont_you_sing_with_me) {}\n" "}\n" "\n" "//------------------------\n" "\n" "doboth('no_attrs');\n" "doboth('simple_attr');\n" "doboth('two_attrs');\n" "doboth('m', 'C');\n" "doboth('n', 'C');\n" "doboth('o', 'C');\n" "doboth('p', 'C');\n" "doboth('q', 'C');\n" "doboth('wxy', 'C');\n" "doboth('m', 'D');\n" "doboth('n', 'D');\n" "doboth('o', 'D');\n" "doboth('p', 'D');\n" "doboth('q', 'D');\n" "doboth('wxy', 'D');" , ">>> no_attrs =>\n" "---- non-recursive: ----\n" "p1:\n" "array(0) {\n" "}\n" "p2:\n" "array(0) {\n" "}\n" "\n" "---- recursive: ----\n" "p1:\n" "array(0) {\n" "}\n" "p2:\n" "array(0) {\n" "}\n" "\n" ">>> simple_attr =>\n" "---- non-recursive: ----\n" "param:\n" "array(1) {\n" " [\"Attribute\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(1) {\n" " [\"Attribute\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> two_attrs =>\n" "---- non-recursive: ----\n" "p1:\n" "array(1) {\n" " [\"Attr1\"]=>\n" " array(0) {\n" " }\n" "}\n" "p2:\n" "array(1) {\n" " [\"Attr2\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "p1:\n" "array(1) {\n" " [\"Attr1\"]=>\n" " array(0) {\n" " }\n" "}\n" "p2:\n" "array(1) {\n" " [\"Attr2\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> C::m =>\n" "---- non-recursive: ----\n" "param:\n" "array(1) {\n" " [\"Attr\"]=>\n" " array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" " [2]=>\n" " int(3)\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(1) {\n" " [\"Attr\"]=>\n" " array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" " [2]=>\n" " int(3)\n" " }\n" "}\n" "\n" ">>> C::n =>\n" "---- non-recursive: ----\n" "param:\n" "array(2) {\n" " [\"Bar\"]=>\n" " array(0) {\n" " }\n" " [\"Foo\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(2) {\n" " [\"Bar\"]=>\n" " array(0) {\n" " }\n" " [\"Foo\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> C::o =>\n" "---- non-recursive: ----\n" "param:\n" "array(1) {\n" " [\"Hi\"]=>\n" " array(1) {\n" " [0]=>\n" " string(3) \"bye\"\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(1) {\n" " [\"Hi\"]=>\n" " array(1) {\n" " [0]=>\n" " string(3) \"bye\"\n" " }\n" "}\n" "\n" ">>> C::p =>\n" "---- non-recursive: ----\n" "param:\n" "array(2) {\n" " [\"A\"]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"b\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"c\"\n" " [1]=>\n" " string(1) \"d\"\n" " }\n" " }\n" " [\"E\"]=>\n" " array(1) {\n" " [0]=>\n" " string(2) \"fg\"\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(2) {\n" " [\"A\"]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"b\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"c\"\n" " [1]=>\n" " string(1) \"d\"\n" " }\n" " }\n" " [\"E\"]=>\n" " array(1) {\n" " [0]=>\n" " string(2) \"fg\"\n" " }\n" "}\n" "\n" ">>> C::q =>\n" "---- non-recursive: ----\n" "tuv:\n" "array(1) {\n" " [\"RS\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "tuv:\n" "array(1) {\n" " [\"RS\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> C::wxy =>\n" "---- non-recursive: ----\n" "z:\n" "array(1) {\n" " [\"And_\"]=>\n" " array(0) {\n" " }\n" "}\n" "wont_you_sing_with_me:\n" "array(1) {\n" " [\"NextTime\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "z:\n" "array(1) {\n" " [\"And_\"]=>\n" " array(0) {\n" " }\n" "}\n" "wont_you_sing_with_me:\n" "array(1) {\n" " [\"NextTime\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> D::m =>\n" "---- non-recursive: ----\n" "param:\n" "array(0) {\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(1) {\n" " [\"Attr\"]=>\n" " array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" " [2]=>\n" " int(3)\n" " }\n" "}\n" "\n" ">>> D::n =>\n" "---- non-recursive: ----\n" "param:\n" "array(2) {\n" " [\"Bar\"]=>\n" " array(0) {\n" " }\n" " [\"Foo\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(2) {\n" " [\"Bar\"]=>\n" " array(0) {\n" " }\n" " [\"Foo\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> D::o =>\n" "---- non-recursive: ----\n" "param:\n" "array(1) {\n" " [\"Hi\"]=>\n" " array(1) {\n" " [0]=>\n" " string(5) \"hello\"\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(1) {\n" " [\"Hi\"]=>\n" " array(1) {\n" " [0]=>\n" " string(5) \"hello\"\n" " }\n" "}\n" "\n" ">>> D::p =>\n" "---- non-recursive: ----\n" "param:\n" "array(2) {\n" " [\"A\"]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"b\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"c\"\n" " [1]=>\n" " string(1) \"d\"\n" " }\n" " }\n" " [\"E\"]=>\n" " array(1) {\n" " [0]=>\n" " string(2) \"fg\"\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(2) {\n" " [\"A\"]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"b\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"c\"\n" " [1]=>\n" " string(1) \"d\"\n" " }\n" " }\n" " [\"E\"]=>\n" " array(1) {\n" " [0]=>\n" " string(2) \"fg\"\n" " }\n" "}\n" "\n" ">>> D::q =>\n" "---- non-recursive: ----\n" "rstuv:\n" "array(0) {\n" "}\n" "\n" "---- recursive: ----\n" "rstuv:\n" "array(1) {\n" " [\"RS\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> D::wxy =>\n" "---- non-recursive: ----\n" "z:\n" "array(1) {\n" " [\"EnglishPeopleCallThisZed\"]=>\n" " array(0) {\n" " }\n" "}\n" "wont_you_sing_with_me:\n" "array(0) {\n" "}\n" "\n" "---- recursive: ----\n" "z:\n" "array(2) {\n" " [\"And_\"]=>\n" " array(0) {\n" " }\n" " [\"EnglishPeopleCallThisZed\"]=>\n" " array(0) {\n" " }\n" "}\n" "wont_you_sing_with_me:\n" "array(1) {\n" " [\"NextTime\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n"); return true; } #ifdef TAINTED #define INIT_TEST_TAINT_HELPERS \ "$taint_counter = 0;\n" \ "function assert_tainted($str, $taint) {\n" \ " global $taint_counter;\n" \ " if (!fb_get_taint($str, $taint)) {\n" \ " var_dump($taint_counter);\n" \ " }\n" \ " $taint_counter++;" \ "}\n" \ "function assert_not_tainted($str, $taint) {\n" \ " global $taint_counter;\n" \ " if (fb_get_taint($str, $taint)) {\n" \ " var_dump($taint_counter);\n" \ " }\n" \ " $taint_counter++;" \ "}\n" // We reconstruct our strings to ensure they aren't ever treated as // literals by hphp. #define INIT_TEST_TAINT_STRINGS \ "$tmp = \"heLlO\\nworld\\ntoto\\narent\\ntaTa\";\n" \ "$good1 = '';\n" \ "for ($i = 0; $i < strlen($tmp); $i++) {\n" \ " $good1 .= $tmp[$i];\n" \ "}\n" \ "$tmp = 'world';\n" \ "$good2 = '';\n" \ "for ($i = 0; $i < strlen($tmp); $i++) {\n" \ " $good2 .= $tmp[$i];\n" \ "}\n" \ "$tmp = \"eViL\\nsTring\\nare\\tfun\\narent\\tworld?\";\n" \ "$bad1 = '';\n" \ "for ($i = 0; $i < strlen($tmp); $i++) {\n" \ " $bad1 .= $tmp[$i];\n" \ "}\n" \ "$tmp = 'arent';\n" \ "$bad2 = '';\n" \ "for ($i = 0; $i < strlen($tmp); $i++) {\n" \ " $bad2 .= $tmp[$i];\n" \ "}\n" \ "unset($tmp);\n" \ "fb_set_taint($bad1, TAINT_ALL);\n" \ "fb_set_taint($bad2, TAINT_ALL);\n" bool TestCodeRun::TestTaint() { HipHopSyntax w(this); // Literals and assignments MVCRO("m_a = $a;\n" " $this->m_b = $b;\n" " }\n" " function test() {\n" " var_dump(fb_get_taint($this->m_a, TAINT_ALL));\n" " var_dump(fb_get_taint($this->m_b, TAINT_ALL));\n" " }\n" "}\n" "$foo = new Foo($a, $b);\n" "$foo->test();\n" "var_dump(fb_get_taint(Foo::FOO, TAINT_ALL));\n" , "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n"); // Copy-on-taint and taint independence MVCRO("'foo');\n" "$tmp = 'qqq';\n" "$b = '';\n" "for ($i = 0; $i < strlen($tmp); $i++) {\n" " $b .= $tmp[$i];\n" "}\n" "unset($tmp);\n" "class c {}\n" "$c = new c;\n" "$c->p = 'zzz';\n" "assert_not_tainted(\"AAA ${a['x']} $a[x] $b $c->p\", TAINT_ALL);\n" "fb_set_taint($b, TAINT_ALL);\n" "assert_tainted(\"AAA ${a['x']} $a[x] $b $c->p\", TAINT_ALL);\n" "class X {\n" " static function g() {}\n" "};\n" "$tmp = 'efg';\n" "$a = '';\n" "for ($i = 0; $i < strlen($tmp); $i++) {\n" " $a .= $tmp[$i];\n" "}\n" "unset($tmp);\n" "$b = rand() % 42;\n" "assert_tainted('abc' . X::g() . $b . $a, TAINT_ALL);\n" "fb_set_taint($a, TAINT_ALL);\n" "assert_tainted('abc' . X::g() . 42 . $a, TAINT_ALL);\n" "assert_tainted('abc' . X::g() . $b . $a, TAINT_ALL);\n" "function f() {\n" " $tmp = 'x';\n" " $a = '';\n" " for ($i = 0; $i < strlen($tmp); $i++) {\n" " $a .= $tmp[$i];\n" " }\n" " unset($tmp);\n" " fb_set_taint($a, TAINT_ALL);\n" " return $a;\n" "}\n" "function g() {}\n" "function test1($a) {\n" " $buf = '';\n" " foreach ($a as $s) {\n" " $buf .= f() . g() . 'h' . f() . 'h' . g();\n" " }\n" " foreach ($a as $s) {\n" " $buf .= ($s . 'h' . $s);\n" " }\n" " return $buf;\n" "}\n" "assert_tainted(test1(array(1)), TAINT_ALL);\n" "function test2() {\n" " return f() . g() . f() . g();\n" "}\n" "assert_tainted(test2(), TAINT_ALL);\n" "function test3() {\n" " return f() . g() . f() . g() . f() . g() . f() . g() . f();\n" "}\n" "assert_tainted(test3(), TAINT_ALL);\n" "function test4() {\n" " $s = f();\n" " $s .=\n" " ('foo'.\n" " 'bar'.\n" " f().\n" " 'foo'.\n" " 'baz'.\n" " f().\n" " 'fuz'.\n" " 'boo'.\n" " f().\n" " 'fiz'.\n" " 'faz');\n" " $s .= f();\n" " return $s;\n" "}\n" "assert_tainted(test4(), TAINT_ALL);\n" "function test6() {\n" " return g().f().g();\n" "}\n" "assert_tainted(test6(), TAINT_ALL);\n", ""); // Arrays MVCRO(" $good2,\n" " $bad1 => $bad2,\n" " $bad2 => array(\n" " $good2 => $bad2,\n" " $bad2 => $good3,\n" " ),\n" ");\n" "assert_not_tainted($arr, TAINT_ALL);\n" "assert_tainted(print_r($arr, true), TAINT_ALL);\n" "assert_not_tainted($arr[$good1], TAINT_ALL);\n" "assert_tainted($arr[$bad1], TAINT_ALL);\n" "assert_not_tainted($arr[$bad2], TAINT_ALL);\n" "assert_tainted(print_r($arr[$bad2], true), TAINT_ALL);\n" "assert_tainted($arr[$bad2][$good2], TAINT_ALL);\n" "assert_not_tainted($arr[$bad2][$bad2], TAINT_ALL);\n" "$keys = array_keys($arr);\n" "assert_not_tainted($keys[0], TAINT_ALL);\n" "assert_tainted($keys[1], TAINT_ALL);\n" "assert_tainted($keys[2], TAINT_ALL);\n", ""); // Typecasts MVCRO(" rand(),\n" " $a => 'barbaz',\n" ");\n" "var_dump(fb_get_taint($arr, TAINT_ALL));\n" "var_dump(fb_get_taint($arr['foostr'], TAINT_ALL));\n" "var_dump(fb_get_taint($arr[$a], TAINT_ALL));\n" "class CleanObj {\n" " function __toString() { return 'obj'; }\n" "}\n" "class TaintedObj {\n" " function __toString() {\n" " $bad1 = \"eViL\\nsTring\\nare\\tfun\\narent\\tthey?\";\n" " fb_set_taint($bad1, TAINT_MUTATED);\n" " return 'obj' . $bad1;\n" " }\n" "}\n" "$obj1 = new CleanObj();\n" "var_dump(fb_get_taint($obj1, TAINT_MUTATED));\n" "$obj2 = new TaintedObj();\n" "var_dump(fb_get_taint($obj2, TAINT_MUTATED));\n", "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n"); // Tokens MVCRO("foostr();\n" "foostr::staticFoostr();\n", "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n"); // Closures MVCRO(" $v) {\n" " if ($check_key) {\n" " var_dump(fb_get_taint($k, TAINT_ALL));\n" " }\n" " if ($check_val) {\n" " var_dump(fb_get_taint($v, TAINT_ALL));\n" " }\n" " }\n" "}\n" "$mixed_arr = array(\n" " $bad3 => $good1,\n" " $good3 => $bad1,\n" " $good4 => $good2,\n" " $bad4 => $bad2,\n" ");\n" "$num_arr = array($good1, $bad1, $good2, $bad2);\n" "$arr = array_change_key_case($mixed_arr);\n" "foreach ($arr as $k => $v) {\n" " var_dump(fb_get_taint($k, TAINT_HTML));\n" " var_dump(fb_get_taint($k, TAINT_MUTATED));\n" " var_dump(fb_get_taint($v, TAINT_ALL));\n" "}\n" "$arr = array_chunk($mixed_arr, 2, true);\n" "check_array($arr[0]);\n" "check_array($arr[1]);\n" "check_array(array_combine(\n" " array($bad3, $good3, $good4, $bad4),\n" " $num_arr\n" "));\n" "check_array(array_count_values($mixed_arr), true, false);\n" "check_array(array_fill_keys($num_arr, $bad1));\n" "check_array(array_fill(0, 2, $good1), false);\n" "check_array(array_fill(0, 2, $bad1), false);\n" "check_array(array_filter(\n" " $mixed_arr,\n" " function($str) { return strlen($str) < 42; }\n" "));\n" "check_array(array_flip($mixed_arr));\n" "check_array(array_keys($mixed_arr), false);\n" "check_array(array_map(\n" " function($str) { return $str . $str; },\n" " $mixed_arr\n" "));\n" "$arr = array_chunk($mixed_arr, 2, true);\n" "check_array(array_merge($arr[0], $arr[1]));\n" "check_array(array_replace(\n" " $mixed_arr,\n" " array(\n" " $bad3 => $bad1,\n" " $good3 => $bad2,\n" " $good4 => $good1,\n" " $bad4 => $good2,\n" " )\n" "));\n" "check_array(array_pad($mixed_arr, 5, $good1));\n" "check_array(array_pad($mixed_arr, 5, $bad1));\n" "$arr = $num_arr;\n" "$v = array_pop($arr);\n" "$u = array_pop($arr);\n" "check_array($arr, false);\n" "var_dump(fb_get_taint($u, TAINT_ALL));\n" "var_dump(fb_get_taint($v, TAINT_ALL));\n" "array_push($arr, $u);\n" "array_push($arr, $v);\n" "check_array($arr, false);\n" "var_dump(fb_get_taint(array_reduce(\n" " $mixed_arr,\n" " function($a, $b) { return $a . $b; },\n" " ''\n" "), TAINT_ALL));\n" "check_array(array_reverse($mixed_arr));\n" "var_dump(fb_get_taint(array_search($good1, $mixed_arr), TAINT_ALL));\n" "var_dump(fb_get_taint(array_search($bad1, $mixed_arr), TAINT_ALL));\n" "var_dump(fb_get_taint(array_search($good2, $mixed_arr), TAINT_ALL));\n" "var_dump(fb_get_taint(array_search($bad2, $mixed_arr), TAINT_ALL));\n" "$arr = $num_arr;\n" "$v = array_shift($arr);\n" "$u = array_shift($arr);\n" "var_dump(fb_get_taint($v, TAINT_ALL));\n" "var_dump(fb_get_taint($u, TAINT_ALL));\n" "check_array($arr, false);\n" "array_unshift($arr, $u);\n" "array_unshift($arr, $v);\n" "check_array($arr, false);\n" "check_array(array_slice($mixed_arr, 0, 4), false);\n" "check_array(array_slice($mixed_arr, 0, 4, true));\n" "$arr = $mixed_arr;\n" "$ins = array_splice($arr, 1, 2);\n" "array_splice($arr, 1, 0, $ins);\n" "check_array($arr, false);\n" "check_array(array_values($mixed_arr), false);\n" "$arr = $mixed_arr;\n" "array_walk(\n" " $arr,\n" " function ($v, $k, $x) { $v .= $x; $k .= $x; },\n" " 'foobar'\n" ");\n" "check_array($arr);\n" "check_array(compact('bad3', 'good3', 'good4', 'bad4'), false);\n" "check_array(array_diff($num_arr, array_slice($num_arr, 0, 2)), false);\n" "check_array(array_diff($num_arr, array_slice($num_arr, 2, 2)), false);\n" "check_array(array_diff_key(\n" " array_flip($mixed_arr),\n" " array_flip(array_slice($mixed_arr, 2, 2))\n" "), false);\n" "check_array(array_diff_key(\n" " array_flip($mixed_arr),\n" " array_flip(array_slice($mixed_arr, 0, 2))\n" "), false);\n" "check_array(array_intersect($mixed_arr, $num_arr), false);\n" "check_array(array_intersect_key(\n" " array_flip($mixed_arr),\n" " array_flip($num_arr)\n" "), false);\n" "$arr = $mixed_arr;\n" "sort($arr);\n" "check_array($arr, false);\n" "asort($mixed_arr);\n" "check_array($mixed_arr);\n" "ksort($mixed_arr);\n" "check_array($mixed_arr);\n", // array_change_key_case "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" // array_chunk TEST_TAINT_EXT_ARRAY_STD_TAINTS // array_combine TEST_TAINT_EXT_ARRAY_STD_TAINTS // array_count_values TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_fill_keys "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" // array_fill "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" // array_filter TEST_TAINT_EXT_ARRAY_STD_TAINTS // array_flip "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" // array_keys TEST_TAINT_EXT_ARRAY_KEY_TAINTS // array_map TEST_TAINT_EXT_ARRAY_STD_TAINTS // array_merge TEST_TAINT_EXT_ARRAY_STD_TAINTS // array_replace "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" // array_pad TEST_TAINT_EXT_ARRAY_STD_TAINTS "bool(true)\n" "bool(false)\n" TEST_TAINT_EXT_ARRAY_STD_TAINTS "bool(true)\n" "bool(true)\n" // array_pop TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_push TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_reduce "bool(true)\n" // array_reverse "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" // array_search TEST_TAINT_EXT_ARRAY_KEY_TAINTS // array_shift TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_unshift TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_slice TEST_TAINT_EXT_ARRAY_VAL_TAINTS TEST_TAINT_EXT_ARRAY_STD_TAINTS // array_splice TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_values TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_walk TEST_TAINT_EXT_ARRAY_STD_TAINTS // compact TEST_TAINT_EXT_ARRAY_KEY_TAINTS // array_diff TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_diff_key TEST_TAINT_EXT_ARRAY_KEY_TAINTS // array_intersect TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_intersect_key TEST_TAINT_EXT_ARRAY_KEY_TAINTS // sort "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" // asort "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" // ksort "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n"); #undef TEST_TAINT_EXT_ARRAY_VAL_RESULT #undef TEST_TAINT_EXT_ARRAY_KEY_RESULT #undef TEST_TAINT_EXT_ARRAY_STD_RESULT /** * BC Math * * bc{add, sub, mul, div, pow, mod, powmod, sqrt}: These taint with the * same semantics as concatenation; that is, they propagate taint only * and do not mutate. * * The remaining functions, bcscale and bccomp, have no need for taint. */ MVCRO("good = $good1;\n" " $this->bad = $bad1;\n" " }\n" " public function foo() { }\n" "}\n" "$a = new Foo();\n" "$arr = get_object_vars($a);\n" "assert_not_tainted($arr['good'], TAINT_ALL);\n" "assert_tainted($arr['bad'], TAINT_ALL);\n", ""); /** * Closure * Continuation * Ctype * * No functions are defined in closure, only object creation helpers * are defined in continuation, and character typing doesn't produce * any output; none of these need taint. */ /** * Curl * * Functions such as curl_exec() and curl_getinfo() return fully tainted * strings; all remaining functions have no need for taint. */ MVCRO("name, TAINT_HTML);\n" "$res = mysql_query('SELECT * FROM test');\n" "$ret = mysql_result($res, 0, 'name');\n" "assert_tainted($ret, TAINT_HTML);\n" "$ret = mysql_result($res, 0, 'name');\n" "assert_tainted($ret, TAINT_HTML);\n" "$ret = mysql_fetch_field($res, 1);\n" "assert_tainted($ret->name, TAINT_HTML);\n" "$ret = mysql_field_name($res, 1);\n" "assert_tainted($ret, TAINT_HTML);\n" "$ret = mysql_field_table($res, 1);\n" "assert_tainted($ret, TAINT_HTML);\n" "mysql_query('DROP TABLE test');\n", ""); /** * Network (TODO) */ /** * OpenSSL (TODO) */ /** * Option * * get_defined_constants: Taint is passed by reference. * * The remaining functions are control functions not requiring taint. */ MVCRO(" $good1);\n" "$mixed_arr = array($good2 => $bad1, $bad2 => $good1);\n" "$bad_arr = array($bad2 => $bad1);\n" "var_dump(fb_get_taint(strval($good1), TAINT_ALL));\n" "var_dump(fb_get_taint(strval($bad1), TAINT_ALL));\n" "var_dump(fb_get_taint(print_r($good1, true), TAINT_ALL));\n" "var_dump(fb_get_taint(print_r($bad1, true), TAINT_ALL));\n" "var_dump(fb_get_taint(print_r($good_arr, true), TAINT_ALL));\n" "var_dump(fb_get_taint(print_r($mixed_arr, true), TAINT_ALL));\n" "var_dump(fb_get_taint(print_r($bad_arr, true), TAINT_ALL));\n" "var_dump(fb_get_taint(var_export($good1, true), TAINT_ALL));\n" "var_dump(fb_get_taint(var_export($bad1, true), TAINT_ALL));\n" "var_dump(fb_get_taint(var_export($good_arr, true), TAINT_ALL));\n" "var_dump(fb_get_taint(var_export($mixed_arr, true), TAINT_ALL));\n" "var_dump(fb_get_taint(var_export($bad_arr, true), TAINT_ALL));\n" "ob_start();\n" "var_export($good1);\n" "var_dump(fb_get_taint(ob_get_clean(), TAINT_ALL));\n" "ob_start();\n" "var_export($bad1);\n" "var_dump(fb_get_taint(ob_get_clean(), TAINT_ALL));\n" "ob_start();\n" "var_dump($good1);\n" "var_dump(fb_get_taint(ob_get_clean(), TAINT_ALL));\n" "ob_start();\n" "var_dump($bad1);\n" "var_dump(fb_get_taint(ob_get_clean(), TAINT_ALL));\n" "ob_start();\n" "debug_zval_dump($good1);\n" "var_dump(fb_get_taint(ob_get_clean(), TAINT_ALL));\n" "ob_start();\n" "debug_zval_dump($bad1);\n" "var_dump(fb_get_taint(ob_get_clean(), TAINT_ALL));\n" "var_dump(fb_get_taint(serialize($good1), TAINT_HTML));\n" "var_dump(fb_get_taint(serialize($good1), TAINT_MUTATED));\n" "var_dump(fb_get_taint(serialize($bad1), TAINT_HTML));\n" "var_dump(fb_get_taint(serialize($bad1), TAINT_MUTATED));\n" "var_dump(fb_get_taint(unserialize($serialized_good), TAINT_HTML));\n" "var_dump(fb_get_taint(unserialize($serialized_good), TAINT_MUTATED));\n" "var_dump(fb_get_taint(unserialize($serialized_bad), TAINT_HTML));\n" "var_dump(fb_get_taint(unserialize($serialized_bad), TAINT_MUTATED));\n" "$arr = get_defined_vars();\n" "var_dump(fb_get_taint($arr['good1'], TAINT_ALL));\n" "var_dump(fb_get_taint($arr['bad1'], TAINT_ALL));\n" "$arr = array(\n" " 'good1' => $good1,\n" " 'bad1' => $bad1,\n" ");\n" "extract($arr, EXTR_PREFIX_ALL, 'extract');\n" "var_dump(fb_get_taint($extract_good1, TAINT_ALL));\n" "var_dump(fb_get_taint($extract_bad1, TAINT_ALL));\n", "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n"); /** * XML (TODO) * XMLReader (TODO) * XMLWriter (TODO) */ /** * zlib (TODO) */ return true; } #endif bool TestCodeRun::TestParser() { MVCRO("a = function ($x) { echo '!' . $x; };\n" "($foo->a)(\"foo\\n\");\n" "Foo::$b = function ($x) { echo '?' . $x; };\n" "(Foo::$b)(\"bar\\n\");\n" "Foo::$c[0] = function ($x) { echo '.' . $x; };\n" "(Foo::$c[0])(\"baz\\n\");\n" , "!foo\n" "?bar\n" ".baz\n" ); MVCRO("prop = 3;\n" "var_dump($c->prop);\n" , "int(1)\n" "int(2)\n" "int(3)\n" ); return true; } bool TestCodeRun::TestTypeAssertions() { MVCR(" 1)));\n"); MVCR("x)) {\n" " var_dump($x->x);\n" " }\n" " if ($x instanceof Y && isset($x->y)) {\n" " var_dump($x->y);\n" " }\n" " if (is_a($x, 'X1')) {\n" " var_dump($x->x);\n" " }\n" "}\n" "f(null);\n" "f(new X);\n" "f(new Y);\n" "f(new X1);\n" "f(new stdClass());\n"); MVCR("container = $container;\n" " }\n" " public function offsetSet($offset, $value) {\n" " if (is_null($offset)) {\n" " $this->container[] = $value;\n" " } else {\n" " $this->container[$offset] = $value;\n" " } \n" " }\n" " public function offsetExists($offset) {\n" " return isset($this->container[$offset]);\n" " }\n" " public function offsetUnset($offset) {\n" " unset($this->container[$offset]);\n" " }\n" " public function offsetGet($offset) {\n" " return isset($this->container[$offset]) ?\n" " $this->container[$offset] : null;\n" " }\n" "}\n" "$x = new X(array(0, 1, 2));\n" "f($x);\n" "f(array(0, 1, 2));\n" "g($x);\n" "g(array(0, 1, 2));\n" "h(array(0, 1, 2));\n" "h('foobar');\n" "h(new stdClass());\n" "var_dump(i($x));\n" "var_dump(i(array(0, 1, 2)));\n"); MVCR("f();\n" " }\n" " if ($x instanceof X) {\n" " $x->f();\n" " }\n" " if ($x instanceof Y) {\n" " $x->f();\n" " }\n" "}\n" "f(new Base);\n" "f(new X);\n" "f(new Y);\n"); MVCR("bar();\n" " $this->baz();\n" " var_dump($this->propX);\n" " return $this->propY;\n" " }\n" " return null;\n" " }\n" "}\n" "class Y extends X {\n" " public $propY;\n" " function bar(){\n" " echo 'Y';\n" " }\n" "}\n" "$y = new Y;\n" "$y->propX = 16;\n" "$y->propY = 32;\n" "var_dump($y->foo());\n" "class A1 {\n" " public $a1prop;\n" " function a1method() {\n" " return 0;\n" " }\n" " function doStuff() {\n" " if ($this instanceof D1) {\n" " var_dump($this->d1prop);\n" " var_dump($this->d1method());\n" " } else if ($this instanceof C1) {\n" " var_dump($this->c1prop);\n" " var_dump($this->c1method());\n" " } else if ($this instanceof B1) {\n" " var_dump($this->b1prop);\n" " var_dump($this->b1method());\n" " } else if ($this instanceof A1) {\n" " var_dump($this->a1prop);\n" " var_dump($this->a1method());\n" " }\n" " }\n" "}\n" "class B1 extends A1 {\n" " public $b1prop;\n" " function b1method() {\n" " return 1;\n" " }\n" "}\n" "if (rand(0, 1)) {\n" " class C1 extends B1 {\n" " public $c1prop;\n" " function c1method() {\n" " return 2;\n" " }\n" " }\n" "} else {\n" " class C1 extends B1 {\n" " public $c1prop;\n" " function c1method() {\n" " return 2;\n" " }\n" " }\n" "}\n" "class D1 extends C1 {\n" " public $d1prop;\n" " function d1method() {\n" " return 3;\n" " }\n" "}\n" "$a1 = new A1;\n" "$a1->a1prop = 0;\n" "$a1->doStuff();\n" "$b1 = new B1;\n" "$b1->b1prop = 1;\n" "$b1->doStuff();\n" "$c1 = new C1;\n" "$c1->c1prop = 2;\n" "$c1->doStuff();\n" "$d1 = new D1;\n" "$d1->d1prop = 3;\n" "$d1->doStuff();\n"); MVCR("\n" , "" ); MVCRO( "sayHello();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" "?>\n" , "Hello Universe!\n" ); MVCRO( "sayHello();\n" "$o->sayWorld();\n" "$o->sayExclamationMark();\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" "$o->sayWorld();\n" "$o->sayExclamationMark();\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" " echo 'World!';\n" " }\n" "}\n" "class MyHelloWorld {\n" " use SayWorld;\n" " public function sayHello() {\n" " echo 'Hello ';\n" " }\n" "}\n" "$o = new MyHelloWorld();\n" "$o->sayHelloWorld();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "Hello from class!\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "Hello from trait!\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "Hello from MY_TRAIT2!\n" ); MVCRO( "falaOi();\n" "?>\n\n" , "Hello from MY_TRAIT1!\n" ); MVCRO( "falaOi();\n" "$o->falaTchau();\n" "$o->sayHello();\n" "$o->sayGoodbye();\n" "?>\n" , "Hello from MY_TRAIT1!\n" "Goodbye from MY_TRAIT2!\n" "Hello from MY_TRAIT1!\n" "Goodbye from MY_TRAIT2!\n" ); MVCRO( "falaTchau();\n" "?>\n" , "Goodbye from MY_TRAIT2!\n" ); MVCRO( "getCompanyName() . \"\\n\";\n" " echo \"I'm \" . $this->getName() . \"\\n\";\n" " }\n" "}\n" "class Portuguese extends Language {\n" " use Company, Person {\n" " Person::getName insteadof Company;\n" " Company::getName as getCompanyName;\n" " }\n" " public function sayHello() {\n" " echo \"Oi \" . $this->getCompanyName() . \"\\n\";\n" " echo \"Eu sou \" . $this->getName() . \"\\n\";\n" " }\n" "}\n" "$e = new English();\n" "$e->sayHello();\n" "$p = new Portuguese();\n" "$p->sayHello();\n" , "Hello Facebook\n" "I'm Ottoni\n" "Oi Facebook\n" "Eu sou Ottoni\n" ); MVCRO( "fala();\n" "?>\n" , "Hello\n" ); MVCRO( "say();\n" "$talker->fala();\n" "$talker->parla();\n" "?>\n" , "Banana\n" "Banana\n" "Banana\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "World!\n" ); MVCRO( "sayHello();\n" "?>\n" , "Hello from MY_TRAIT2\n" ); MVCRO( "getHi() . $this->getName();\n" " }\n" "}\n" "$e = new English();\n" "$e->sayHello();\n" "?>\n\n" , "Hi Facebook\n" ); MVCRO( "bar();\n" " }\n" " abstract function bar();\n" "}\n" "class C {\n" " use T;\n" " function bar() {\n" " echo \"BAR!\\n\";\n" " }\n" "}\n" "$x = new C();\n" "$x->foo();\n" "?>\n" , "FooBAR!\n" ); MVCRO( "sayHelloWorld();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "\n\n" , "B: B\n" ); MVCRO( "Func1();\n" "?>\n\n" , "Hello\n" ); MVCRO( "x . \"\\n\";\n" " echo \"y = \" . $this->y . \"\\n\";\n" " }\n" "}\n" "class D {\n" " public $y = 4;\n" "}\n" "$o = new C;\n" "$o->printY();\n" "?>\n" , "x = 10\n" "y = 3\n" ); MVCRO( "y);\n" " var_dump($this->x);\n" " }\n" "}\n" "$o = new C;\n" "$o->printProps();\n" "?>\n" , "int(3)\n" "int(4)\n" ); MVCRO( "x);\n" " }\n" "}\n" "$o = new MY_CLASS;\n" "$o->printProps();\n" "?>\n" , "int(1977)\n" ); MVCRO( "x);\n" " }\n" "}\n" "$o = new C;\n" "$o->printProps();\n" "?>\n" , "int(3)\n" ); MVCRO( "printX();\n" "var_dump(MY_BASE::$x);\n" "var_dump(MY_CLASS::$x);\n" "?>\n" , "int(3)\n" "int(3)\n" "int(4)\n" ); MVCRO( "printX();\n" "?>\n" , "int(3)\n" ); MVCRO( "x);\n" " }\n" "}\n" "$o = new MY_CLASS;\n" "$o->printX();\n" "?>\n" , "int(4)\n" ); MVCRO( "x);\n" " }\n" "}\n" "$o = new MY_CLASS;\n" "$o->printX();\n" "?>\n" , "string(3) \"123\"\n" ); MVCRO( "x);\n" " $this->x = 10;\n" " var_dump($this->x);\n" " }\n" "}\n" "$o = new MY_CLASS;\n" "$o->printX();\n" "?>\n" , "NULL\n" "int(10)\n" ); MVCRO( "bigTalk($m);\n" " }\n" "}\n" "trait B {\n" " public function smallTalk() {\n" " echo \"b\\n\";\n" " }\n" " public function bigTalk($n) {\n" " if ($n == 0) return;\n" " echo \"B$n\\n\";\n" " $this->bigTalk($n - 1);\n" " }\n" "}\n" "class Talker {\n" " use A, B {\n" " B::smallTalk insteadof A;\n" " A::bigTalk insteadof B;\n" " B::bigTalk as bTalk;\n" " }\n" "}\n" "$talker = new Talker();\n" "$talker->smallTalk();\n" "$talker->bigTalk(1);\n" "$talker->bTalk(2);\n" "?>\n" , "b\n" "A1\n" "B2\n" "A1\n" ); MVCRO( "p();\n" "?>\n" , "A\n" ); MVCRO( "foo();\n" "?>\n" , "FooBAR!\n" "__class__: D\n" ); MVCRO( "inc();\n" "$p = new C2();\n" "$p->inc();\n" "$o->inc();\n" "$p->inc();\n" "?>\n" , "1\n" "1\n" "2\n" "2\n" ); MVCRO( "\n" , "Hello from static function!\n" ); MVCRO( "\n" , "Hello World!\n" ); MVCRO( "\n" , "Hello World!\n" "World!\n" ); MVCRO( "foo();\n" "?>\n" , "FooBAR!\n" "I'm in class D\n" ); MVCRO( "sayHello();\n" "$a = new MyClass2;\n" "$a->sayHello();\n" "?>\n" , "Hello World!\n" "Hello World!\n" ); MVCRO( "hello . ' ' . $this->world;\n" " }\n" "}\n" "var_dump(property_exists('TraitsTest', 'hello'));\n" "var_dump(property_exists('TraitsTest', 'world'));\n" "$t = new TraitsTest;\n" "$t->test();\n" "?>\n" , "bool(true)\n" "bool(true)\n" "Hello World!\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" " $this->sayWorld();\n" " echo \"!\\n\";\n" " }\n" " use World {\n" " World::say as sayWorld;\n" " }\n" "}\n" "$o = new MyHelloWorld();\n" "$o->say();\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" , "Hello\n" ); MVCRO( "sayNum();\n" , "1\n" ); MVCRO( "sayNum();\n" , "1\n" ); MVCRO( "print_meth();\n" , "meth: MyClass\n" ); MVCRO( "fala();\n" "?>\n\n" , "Hello\n" ); MVCRO( " __CLASS__: <\" . __CLASS__ .\n" " \"> __METHOD__: <\" . __METHOD__ . \">\";\n" "}\n" "class NoTraitUsed {\n" " public static function test() {\n" " return \"__TRAIT__: <\" . __TRAIT__ .\n" " \"> __CLASS__: <\" . __CLASS__ .\n" " \"> __METHOD__: <\" . __METHOD__ . \">\";\n" " }\n" "}\n" "trait TestTrait {\n" " public static function test() {\n" " return \"__TRAIT__: <\" . __TRAIT__ .\n" " \"> __CLASS__: <\" . __CLASS__ .\n" " \"> __METHOD__: <\" . __METHOD__ . \">\";\n" " }\n" "}\n" "echo Direct::test().\"\\n\";\n" "echo IndirectInheritance::test().\"\\n\";\n" "echo Indirect::test().\"\\n\";\n" "echo NoTraitUsed::test().\"\\n\";\n" "echo test().\"\\n\";\n" , "__TRAIT__: __CLASS__: __METHOD__: \n" "__TRAIT__: __CLASS__: __METHOD__: \n" "__TRAIT__: __CLASS__: __METHOD__: \n" "__TRAIT__: <> __CLASS__: __METHOD__: \n" "__TRAIT__: <> __CLASS__: <> __METHOD__: \n" ); MVCRO( "sayHello();\n" "$a->sayHello2();\n" "?>\n" , "Hello World 1!\n" "Hello World 2!\n" ); MVCRO( "falaOi();\n" "?>\n" , "Hello World!\n" ); MVCRO( "\n" , "array(1) {\n" " [0]=>\n" " string(15) \"this_is_a_trait\"\n" "}\n" ); MVCRO( "isTrait());\n" "$rtrait = new ReflectionClass('this_is_a_trait');\n" "var_dump($rtrait->isTrait());\n" "$rinterface = new ReflectionClass('this_is_an_interface');\n" "var_dump($rinterface->isTrait());\n" , "bool(false)\n" "bool(true)\n" "bool(false)\n" ); if (false) { MVCRO( "\n" " string(6) \"test\\c\"\n" "}\n" ); } MVCRO( "\n" , "array(1) {\n" " [0]=>\n" " string(8) \"MY_TRAIT\"\n" "}\n" ); MVCRO( "\n" , "bool(false)\n" "bool(true)\n" "bool(true)\n" ); } MVCRO( "isConstructor());\n" "$rbarfoo = new ReflectionMethod('Bar::Foo');\n" "var_dump($rbarfoo->isConstructor());\n" "$rbarbar = new ReflectionMethod('Bar::Bar');\n" "var_dump($rbarbar->isConstructor());\n" , "bool(false)\n" "bool(false)\n" "bool(true)\n" ); MVCRO( "isConstructor());\n" "var_dump($rconstr->isDestructor());\n" "var_dump($rdestr->isConstructor());\n" "var_dump($rdestr->isDestructor());\n" "var_dump($rfunc->isConstructor());\n" "var_dump($rfunc->isDestructor());\n" , "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" ); if (false) { MVCRO( "hello(), PHP_EOL;\n" " echo $a->foo(), PHP_EOL;\n" "}\n" , "hello from t1\n" "hello from t2\n" ); } MVCRO( "getTraitNames());\n" "?>\n" , "array(1) {\n" " [0]=>\n" " string(8) \"MY_TRAIT\"\n" "}\n" ); MVCRO( "getTraitNames());\n" "echo \"\\nT3:\\n\";\n" "var_dump(class_uses('T3'));\n" "$rt3 = new ReflectionClass('T3');\n" "var_dump($rt3->getTraitNames());\n" "echo \"\\nC1:\\n\";\n" "var_dump(class_uses('C1'));\n" "$rc1 = new ReflectionClass('C1');\n" "var_dump($rc1->getTraitNames());\n" "echo \"\\nC2:\\n\";\n" "var_dump(class_uses('C2'));\n" "$rc2 = new ReflectionClass('C2');\n" "var_dump($rc2->getTraitNames());\n" "echo \"\\nC3:\\n\";\n" "var_dump(class_uses('C3'));\n" "$rc3 = new ReflectionClass('C3');\n" "var_dump($rc3->getTraitNames());\n" "echo \"\\nC4:\\n\";\n" "var_dump(class_uses('C4'));\n" "$rc4 = new ReflectionClass('C4');\n" "var_dump($rc4->getTraitNames());\n" "echo \"\\nC5:\\n\";\n" "var_dump(class_uses('C5'));\n" "$rc5 = new ReflectionClass('C5');\n" "var_dump($rc5->getTraitNames());\n" "echo \"\\nI1:\\n\";\n" "var_dump(class_uses('I1'));\n" "$ri1 = new ReflectionClass('I1');\n" "var_dump($ri1->getTraitNames());\n" "?>\n" , "T1:\n" "array(0) {\n" "}\n" "array(0) {\n" "}\n\n" "T3:\n" "array(1) {\n" " [\"T2\"]=>\n" " string(2) \"T2\"\n" "}\n" "array(1) {\n" " [0]=>\n" " string(2) \"T2\"\n" "}\n\n" "C1:\n" "array(0) {\n" "}\n" "array(0) {\n" "}\n\n" "C2:\n" "array(1) {\n" " [\"T1\"]=>\n" " string(2) \"T1\"\n" "}\n" "array(1) {\n" " [0]=>\n" " string(2) \"T1\"\n" "}\n\n" "C3:\n" "array(2) {\n" " [\"T1\"]=>\n" " string(2) \"T1\"\n" " [\"T2\"]=>\n" " string(2) \"T2\"\n" "}\n" "array(2) {\n" " [0]=>\n" " string(2) \"T1\"\n" " [1]=>\n" " string(2) \"T2\"\n" "}\n\n" "C4:\n" "array(1) {\n" " [\"T3\"]=>\n" " string(2) \"T3\"\n" "}\n" "array(1) {\n" " [0]=>\n" " string(2) \"T3\"\n" "}\n\n" "C5:\n" "array(0) {\n" "}\n" "array(0) {\n" "}\n\n" "I1:\n" "array(0) {\n" "}\n" "array(0) {\n" "}\n" ); MVCRO( "\n" " string(2) \"T2\"\n" "}\n" "array(2) {\n" " [\"T3\"]=>\n" " string(2) \"T3\"\n" " [\"T1\"]=>\n" " string(2) \"T1\"\n" "}\n" ); MVCRO( "\n" " string(6) \"Hello1\"\n" " [\"Hello2\"]=>\n" " string(6) \"Hello2\"\n" "}\n" ); MVCRO( "getTraitAliases());\n" "$rc2 = new ReflectionClass('C2');\n" "var_dump($rc2->getTraitAliases());\n" "$rc3 = new ReflectionClass('T3');\n" "var_dump($rc3->getTraitAliases());\n" , "array(1) {\n" " [\"G\"]=>\n" " string(5) \"T2::F\"\n" "}\n" "array(0) {\n" "}\n" "array(1) {\n" " [\"G\"]=>\n" " string(9) \"(null)::F\"\n" "}\n" ); MVCRO( "F($x);\n" "echo $x;\n" "echo \"\\n\";\n" "$y = \"zero\";\n" "$o->F($y, \"0\");\n" "echo $y;\n" "?>\n\n" , "value = default\n" "zero = 0\n" ); // Zend tests MVCRO( "\n" "===DONE===\n" , "*** Testing class_uses() : basic ***\n" "array(2) {\n" " [\"foo\"]=>\n" " string(3) \"foo\"\n" " [\"bar\"]=>\n" " string(3) \"bar\"\n" "}\n" "array(2) {\n" " [\"foo\"]=>\n" " string(3) \"foo\"\n" " [\"bar\"]=>\n" " string(3) \"bar\"\n" "}\n" "array(1) {\n" " [\"foo\"]=>\n" " string(3) \"foo\"\n" "}\n" "array(1) {\n" " [\"foo\"]=>\n" " string(3) \"foo\"\n" "}\n" "array(0) {\n" "}\n" "array(0) {\n" "}\n" "===DONE===\n" ); MVCRO( "\n" , "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" ); MVCRO( "saySomething();\n" "?>\n\n" , "Hello\n" ); MVCRO( "2));\n" "$o= myHelloWorld::getInstance(array(1=>2));\n" "\n" "?>\n" , "int(1)\n" "int(2)\n" "array(1) {\n" " [1]=>\n" " int(2)\n" "}\n" ); MVCRO( "\n" , "string(11) \"__construct\"\n" "string(10) \"__destruct\"\n" ); MVCRO( "\n\n" , "Test\n" ); MVCRO( "sayHello();\n" "$o->sayWorld();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "inc();\n" "$o->inc();\n" "\n" "?>\n" , "1\n" "2\n" ); MVCRO( "getTraitAliases());\n" " echo \"\\n\";\n" "}\n" "?>\n" , "class C1:\n" "array(0) {\n" "}\n" "\n" "class C2:\n" "array(0) {\n" "}\n" "\n" "class C3:\n" "array(1) {\n" " [\"a1\"]=>\n" " string(10) \"(null)::m1\"\n" "}\n" "\n" "class C4:\n" "array(2) {\n" " [\"a1\"]=>\n" " string(10) \"(null)::m1\"\n" " [\"a2\"]=>\n" " string(10) \"(null)::m2\"\n" "}\n" "\n" ); MVCRO( "saySomething();\n" "$o->sayWorld();\n" "?>\n\n" , "Hello World\n" ); MVCRO( "hello . ' ' . $this->world;\n" " }\n" "}\n" "\n" "var_dump(property_exists('TraitsTest', 'hello'));\n" "var_dump(property_exists('TraitsTest', 'world'));\n" "\n" "$t = new TraitsTest;\n" "$t->test();\n" "?>\n\n" , "bool(true)\n" "bool(true)\n" "hello World!\n" ); MVCRO( "\n" , "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" ); MVCRO( "\n\n" , "B\n" ); MVCRO( "xyz;\n" "$o->xyz = 2;\n" "clone $o;\n" "\n" "?>\n" , "123\n" "string(3) \"xyz\"\n" "string(7) \"xyz===2\"\n" "string(7) \"__clone\"\n" ); MVCRO( "sayHello(); // echos Hello Universe!\n" "?>\n\n" , "Hello Universe!\n" ); MVCRO( "\n\n" , "*** Testing get_declared_traits() : basic functionality ***\n" "\n" "-- Testing get_declared_traits() function with Zero arguments --\n" "array(1) {\n" " [0]=>\n" " string(7) \"MyTrait\"\n" "}\n" "\n" "-- Ensure trait is listed --\n" "bool(true)\n" "\n" "-- Ensure userspace interfaces are not listed --\n" "bool(false)\n" "\n" "-- Ensure userspace classes are not listed --\n" "bool(false)\n" "Done\n" ); MVCRO( "\n" , "string(0) \"\"\n" "string(0) \"\"\n" "string(0) \"\"\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "hello();\n" "?>\n\n" , "Hello\n" ); MVCRO( "isConstructor());\n" "\n" "$rbarfoo = new ReflectionMethod('Bar::Foo');\n" "var_dump($rbarfoo->isConstructor());\n" "\n" "$rbarbar = new ReflectionMethod('Bar::Bar');\n" "var_dump($rbarbar->isConstructor());\n" "?>\n" , "bool(false)\n" "bool(false)\n" "bool(true)\n" ); MVCRO( "\n\n" , "bool(true)\n" "Done\n" ); MVCRO( "sayHello();\n" "$o->sayWorld();\n" "\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "\n\n" , "Test\n" ); MVCRO( "get_class_name_obj();\n" "var_dump($r);\n" "\n" "$r = UsingIndirect::get_class_name();\n" "var_dump($r);\n" "\n" "$o = new UsingIndirect();\n" "$r = $o->get_class_name_obj();\n" "var_dump($r);\n" "\n" "\n" "?>\n" , "string(9) \"SomeClass\"\n" "string(9) \"SomeClass\"\n" "string(13) \"UsingIndirect\"\n" "string(13) \"UsingIndirect\"\n" ); MVCRO( "getWorld();\n" " }\n" " abstract public function getWorld();\n" " }\n" "\n" "class MyHelloWorld {\n" " private $world;\n" " use Hello;\n" " public function getWorld() {\n" " return $this->world;\n" " }\n" " public function setWorld($val) {\n" " $this->world = $val;\n" " }\n" "}\n" "\n" "$o = new MyHelloWorld();\n" "$o->setWorld(' World!');\n" "$o->sayHelloWorld();\n" "\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" "$o->sayWorld();\n" "$o->sayExclamationMark();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "\n\n" , "Test B\n" ); MVCRO( "\n\n" , "*** Testing trait_exists() : basic functionality ***\n" "Calling trait_exists() on non-existent trait with autoload explicitly enabled:\n" "In __autoload(C)\n" "bool(false)\n" "\n" "Calling trait_exists() on existing trait with autoload explicitly enabled:\n" "bool(true)\n" "\n" "Calling trait_exists() on non-existent trait with autoload explicitly enabled:\n" "bool(false)\n" "\n" "Calling trait_exists() on existing trait with autoload explicitly disabled:\n" "bool(true)\n" "\n" "Calling trait_exists() on non-existent trait with autoload unspecified:\n" "In __autoload(E)\n" "bool(false)\n" "\n" "Calling trait_exists() on existing trait with autoload unspecified:\n" "bool(true)\n" "Done\n" ); MVCRO( "\n" , "TestTrait\n" "TestTrait\n" "TestTrait\n" ); MVCRO( "\n\n" , "Forwarded Test A\n" ); MVCRO( "\n" , "OK\n" ); MVCRO( "inc();\n" "$o->inc();\n" "\n" "$p = new C2();\n" "$p->inc();\n" "$p->inc();\n" "\n" "?>\n" , "1\n" "2\n" "1\n" "2\n" ); MVCRO( "\n" , "string(20) \"C:3:\"bar\":6:{foobar}\"\n" "string(6) \"foobar\"\n" "object(bar)#1 (0) {\n" "}\n" ); MVCRO( "smallTalk();\n" "$t->bigTalk();\n" "$t->talk();\n" "\n" "?>\n\n" , "bAB\n" ); MVCRO( "sayHello(); // echos Hello Universe!\n" "?>\n\n" , "Hello Universe!\n" ); MVCRO( "\n" , "array(1) {\n" " [0]=>\n" " string(1) \"c\"\n" "}\n" ); MVCRO( "isTrait());\n" "\n" "$x = new ReflectionClass('bar');\n" "var_dump($x->isTrait());\n" "\n" "$x = new ReflectionClass('baz');\n" "var_dump($x->isTrait());\n" "\n" "?>\n" , "bool(false)\n" "bool(true)\n" "bool(false)\n" ); MVCRO( "\n" , "abc\n" "def\n" ); MVCRO( "\n" "===DONE===\n" , "*** Testing class_uses() : basic ***\n" "array(1) {\n" " [\"foo\"]=>\n" " string(3) \"foo\"\n" "}\n" "array(1) {\n" " [\"foo\"]=>\n" " string(3) \"foo\"\n" "}\n" "===DONE===\n" ); MVCRO( "\n\n" , "Test\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "World!\n" ); MVCRO( "foo();\n" "\n" "?>\n\n" , "b\n" ); MVCRO( "text;\n" " }\n" "}\n" "\n" "trait T2 {\n" " public function setTextT2($val) {\n" " $this->text = $val;\n" " }\n" "}\n" "\n" "class TraitsTest {\n" " use T1;\n" " use T2;\n" " private $text = 'test';\n" " public function setText($val) {\n" " $this->text = $val;\n" " }\n" "}\n" "\n" "$o = new TraitsTest();\n" "var_dump($o->getText());\n" "\n" "$o->setText('foo');\n" "\n" "var_dump($o->getText());\n" "\n" "$o->setText('bar');\n" "\n" "var_dump($o->getText());\n" "?>\n" , "string(4) \"test\"\n" "string(3) \"foo\"\n" "string(3) \"bar\"\n" ); MVCRO( "foo();\n" "C::foo();\n" "D::foo();\n" "T::foo();\n" "T2::foo();\n" "T3::foo();\n" "?>" , "I'm in class C\n" "I'm in class C\n" "I'm in class C\n" "I'm in class T\n" "I'm in class T2\n" "I'm in class T3\n" ); MVCRO( "sayClass(); // echo Cls\n" "$o->sayParent(); // echos Base\n" "?>\n" "\n" , "Cls\n" "Base\n" ); MVCRO( "printX();\n" "$o2->printX();\n" "T::$x++;\n" "var_dump(T::$x);\n" "var_dump(C1::$x);\n" "var_dump(C2::$x);\n" "$o1->printX();\n" "$o2->printX();\n" "C1::$x++;\n" "var_dump(T::$x);\n" "var_dump(C1::$x);\n" "var_dump(C2::$x);\n" "$o1->printX();\n" "$o2->printX();\n" "C2::$x++;\n" "var_dump(T::$x);\n" "var_dump(C1::$x);\n" "var_dump(C2::$x);\n" "$o1->printX();\n" "$o2->printX();\n" "$o1->x++;\n" "var_dump(T::$x);\n" "var_dump(C1::$x);\n" "var_dump(C2::$x);\n" "$o1->printX();\n" "$o2->printX();\n" , "int(1)\n" "int(1)\n" "int(1)\n" "int(1)\n" "int(1)\n" "int(2)\n" "int(1)\n" "int(1)\n" "int(1)\n" "int(1)\n" "int(2)\n" "int(2)\n" "int(1)\n" "int(2)\n" "int(1)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" ); MVCRO( "bar();\n" , "I am bar\n" "I am foo\n" ); MVCRO( "inc(\"c1\");\n" "$c2->inc(\"c2\");\n" "$d1->inc(\"d1\");\n" "$b1->inc(\"b1\");\n" "$b1->inc(\"b1\");\n" "$c2->inc(\"c2\");\n" "$d1->inc(\"d1\");\n" "$c1->inc(\"c1\");\n" , "c1 (C): 1\n" "c2 (C): 2\n" "d1 (C): 1\n" "b1 (B): 1\n" "b1 (B): 2\n" "c2 (C): 3\n" "d1 (C): 2\n" "c1 (C): 4\n" ); MVCRO( "bar();\n" " }\n" "}\n" "class B {\n" " public function bar() {\n" " echo \"I'm bar\\n\";\n" " }\n" "}\n" "class C extends B {\n" " use T;\n" "}\n" "$o = new C;\n" "$o->foo();\n" "\n" , "I'm bar\n" ); MVCRO( "bar();\n" " }\n" "}\n" "\n" "trait T2 {\n" " public function bar() {\n" " echo \"Hello from bar()\\n\";\n" " }\n" "}\n" "\n" "class C {\n" " use T1, T2;\n" "}\n" "\n" "$o = new C;\n" "$o->foo();\n" "\n" "\n" , "Hello from bar()\n" ); MVCRO( "f();" " }" " function h() {" " return $this->p();" " }" "}" "class C {" " use T;" "}" "$c = new C;" "echo $c->g();" "echo $c->h();", "12"); MVCRO( "test());" "var_dump($obj->test1());" "var_dump($obj->test2());" "var_dump(call_user_func(array($obj, \"test\")));" "var_dump(call_user_func(array($obj, \"test1\")));" "var_dump(call_user_func(array($obj, \"test2\")));" "var_dump(T::test8(1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(T::test81(1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(T::test82(1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(call_user_func(\"T::test8\", 1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(call_user_func(\"T::test81\", 1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(call_user_func(\"T::test82\", 1, 2, 3, 4, 5, 6, 7, 8));" "$obj = new T;" "var_dump($obj->test8(1, 2, 3, 4, 5, 6, 7, 8));" "var_dump($obj->test81(1, 2, 3, 4, 5, 6, 7, 8));" "var_dump($obj->test82(1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(call_user_func(array($obj, \"test8\"), " "1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(call_user_func(array($obj, \"test81\"), " "1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(call_user_func(array($obj, \"test82\"), " "1, 2, 3, 4, 5, 6, 7, 8));", "int(1)\n" "int(1)\n" "int(1)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(3)\n" "int(3)\n" "int(3)\n" "int(4)\n" "int(4)\n" "int(4)\n" "int(1)\n" "int(1)\n" "int(1)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(3)\n" "int(3)\n" "int(3)\n" "int(4)\n" "int(4)\n" "int(4)\n" ); MVCRO("entCanComment);" " var_dump(must_prepare($this->entCanComment));" " }" "}" "class EntShare {" " use EntWithViewerComments;" "}" "$obj1 = new EntShare;" "$obj1->canViewerComment();" , "int(1)\nint(1)\n"); MVCROF( "x = 'set from trait'; } }" "" "class A {" " function useA() { $this->x = 'set from A'; }" "}" "class B extends A {" " use T;" " function useB() { $this->x = 'set from B'; }" "}" "class C extends B {" " function useC() { $this->x = 'set from C'; }" "}" "class D extends C {" " function useD() { $this->x = 'set from D'; }" "}" "$x = new D(); echo serialize($x), \"\\n\";" "$x = new D(); $x->useT(); echo serialize($x), \"\\n\";" "$x = new D(); $x->useA(); echo serialize($x), \"\\n\";" "$x = new D(); $x->useB(); echo serialize($x), \"\\n\";" "$x = new D(); $x->useC(); echo serialize($x), \"\\n\";" "$x = new D(); $x->useD(); echo serialize($x), \"\\n\";", "test/output/trait1.out"); MVCRO("xT1);\n" "var_dump($y->xT2);\n" "var_dump($y->xT3);\n" "var_dump($y->xA);\n" "var_dump($y->xB);\n" , "O:1:\"A\":5:{s:2:\"xA\";s:2:\"xA\";s:3:\"xT3\";s:3:\"xT3\";" "s:2:\"xB\";s:2:\"xB\";s:3:\"xT1\";s:3:\"xT1\";s:3:\"xT2\";" "s:3:\"xT2\";}\n" "string(3) \"xT1\"\n" "string(3) \"xT2\"\n" "string(3) \"xT3\"\n" "string(2) \"xA\"\n" "string(2) \"xB\"\n" ); MVCRO( "x; } }" "class Y extends X { use T; function y() { return ++$this->x; } }" "class Z extends Y { function z() { return ++$this->x; } }" "$a = new Z();" "echo join(\" \", array($a->x(), $a->x(), $a->y(), $a->y(), " "$a->z(), $a->z())), \"\\n\";", "1 2 1 2 2 3\n"); MVCRO("protectedMethod();" " }" " protected function protectedMethod() {" " return 'fallback protected method';" " }" " public function getStringThroughPrivateMethod() {" " return $this->privateMethod();" " }" " private function privateMethod() {" " return 'fallback private method';" " }" "}" "" "class A {" " use TraitFoo;" " protected function protectedMethod() {" " return 'in a protectedMethod';" " }" " private function privateMethod() {" " return 'in a privateMethod';" " }" "}" "$a = new A();" "echo $a->getStringThroughProtectedMethod().\"\\n\";" "echo $a->getStringThroughPrivateMethod().\"\\n\";", "in a protectedMethod\n" "in a privateMethod\n"); { // begin trait tests requiring EnableHipHopSyntax HipHopSyntax w(this); MVCRO("fruit() as $fruit) {\n" " var_dump($fruit);\n" "}\n" , "string(5) \"apple\"\n" "string(6) \"banana\"\n" ); MVCRO("fruit() as $fruit) {\n" " var_dump($fruit);\n" "}\n" "foreach ($o->fruit2() as $fruit) {\n" " var_dump($fruit);\n" "}\n" , "string(5) \"apple\"\n" "string(6) \"banana\"\n" "string(4) \"pear\"\n" "string(5) \"grape\"\n" ); MVCRO("doIt();\n" " } catch (Exception $e) {\n" " $res = $e->getMessage();\n" " }\n" " yield $res;\n" "}\n" "$x = new X;\n" "foreach (f($x) as $i) { var_dump($i); }\n" , "string(6) \"foobar\"\n" ); MVCRO("foo('this') as $v) { var_dump($v); }\n" , "int(5)\n" ); MVCRO("getOrigFuncName());\n" "trait T {\n" " function f($x) { yield get_called_class(); }\n" "}\n" "class X { use T; }\n" "$x = new X;\n" "$c = $x->f(32);\n" "var_dump($c->getOrigFuncName());\n" "$fcn = function ($x) { yield $x; };\n" "$c = $fcn(32);\n" "var_dump($c->getOrigFuncName());\n" , "string(1) \"f\"\n" "string(4) \"X::f\"\n" "string(9) \"{closure}\"\n" ); MVCRO("info() as $info) {\n" " var_dump($info);\n" "}\n" "$o2 = new C2;\n" "foreach ($o2->info() as $info) {\n" " var_dump($info);\n" "}\n" , "string(7) \"T::info\"\n" "string(2) \"C1\"\n" "string(1) \"T\"\n" "string(7) \"T::info\"\n" "string(2) \"C2\"\n" "string(1) \"T\"\n" ); MVCRO("f();\n" "foreach ($f() as $v) { var_dump($v); }\n" , "int(1)\n" "int(2)\n" ); MVCRO("bar(function() {yield 1; yield 2; yield 3;});" " }" " public function bar(Closure $c) {" " $a = $c();" " foreach ($a as $b) {" " echo $b.\"\\n\";" " }" " }" "}" "class A { use T; }" "$a = new A();" "$a->foo();" , "1\n" "2\n" "3\n" ); MVCRO("foo();\n" " yield null;\n" " }\n" "}\n" "class D {\n" " use U;\n" " protected function foo() {\n" " echo \"U::foo\\n\";\n" " }\n" "}\n" "$obj = new D;\n" "$x = $obj->test();\n" "foreach ($x as $v) {}\n" , "D\n" "U::foo\n" ); MVCRO("m();\n" "fb_intercept(\"A::m\", function() { echo \"new\n\"; });\n" "$a2 = new A;\n" "$a2->m();\n" "$b1 = new B;\n" "$b1->m();\n" "T::m();\n" , "original\n" "new\n" "original\n" "original\n"); MVCRO("m();\n" "fb_intercept(\"T::m\", function() { echo \"new\n\"; });\n" "$a2 = new A;\n" "$a2->m();\n" "$b1 = new B;\n" "$b1->m();\n" "T::m();\n" , "original\n" "original\n" "original\n" "original\n" "new\n"); MVCRONW("\n" " int(789)\n" "}\n" ); MVCRO("goo($p);" " }, $values);" " var_dump($values);" " }" " public function bar() { return $this; }" " public function goo($p) { return $p; }" "}" "class A { use T;}\n" "$obj = new A;" "var_dump($obj->bar());" "$obj->foo();", "object(A)#1 (0) {\n" "}\n" "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" " [2]=>\n" " int(3)\n" "}\n"); MVCRO("input();\n" " $a = function ($arg) use ($abc, $this) {\n" " var_dump($arg);\n" " var_dump($abc);\n" " return $this->output();\n" " };\n" " return $a;\n" " }\n" " function input() { return 1; }\n" " function output() { return 2; }\n" "}\n" "class Foo {\n" " use Too;\n" " function input() { return \"str1\"; }\n" " function output() { return \"str2\"; }\n" "}\n" "class Goo {\n" " use Too;\n" " function input() { return false; }\n" " function output() { return true; }\n" "}\n" "$of = new Foo;\n" "$f = $of->gen();\n" "var_dump($f(1000));\n" "$og = new Goo;\n" "$g = $og->gen();\n" "var_dump($g(2000));\n" , "int(1000)\n" "string(4) \"str1\"\n" "string(4) \"str2\"\n" "int(2000)\n" "bool(false)\n" "bool(true)\n" ); MVCRO("x);\n" , "int(123)\n" ); MVCRO("x);\n" "var_dump($obj->y);\n" , "string(1) \"1\"\n" "string(1) \"2\"\n" ); MVCRO("x);\n" , "int(123)\n" ); MVCRO("x);\n" "var_dump($obj->y);\n" , "int(123)\n" "int(456)\n" ); MVCRO("x);\n" , "int(123)\n" ); MVCRO("x);\n" "var_dump($obj->y);\n" , "int(123)\n" "int(456)\n" ); MVCRO("testDoSomething().\"\n\";\n" "echo $a->testDoSomethingInTrait().\"\n\";\n" "echo $a->testDoSomethingPublicInTrait().\"\n\";\n" , "doSomething\n" "doSomethingInTrait\n" "doSomethingPublicInTrait\n" ); MVCRO("dump_vars();\n" , "array(2) {\n" " [\"y\"]=>\n" " int(2)\n" " [\"x\"]=>\n" " int(1)\n" "}\n" ); MVCRO("bar();" " }" " private function bar() {" " echo \"in bar...\\n\";" " }" "}" "class B { use T; }" "class C extends B { }" "$obj = new C;" "$obj->foo();", "in bar...\n"); MVCRO("foo;" " }" "}" "" "class Base {" " public static function create() {" " return new static();" " }" "}" "" "class UsePrivateState extends Base {" " use PrivateState;" "}" "" "class DerivedUsePrivateState extends UsePrivateState {" "" "}" "" "" "$state = new DerivedUsePrivateState();" "$method = new ReflectionMethod('DerivedUsePrivateState', 'getFoo');" "echo $method->invoke($state).\"\\n\";" "", "2\n"); MVCRO("foo(1);\n" , "1 \n" ); MVCRO("init();", "A::init"); MVCRO("foo();\n" " }\n" "}\n" "$d = new D;\n" "E::test($d);\n" "echo \"Done\\n\";\n" , "Done\n" ); MVCRO("foo();\n" " }\n" "}\n" "$d = new D;\n" "E::test($d);\n" "echo \"Done\\n\";\n" , "T::foo\n" "Done\n" ); MVCRO("foo().\"\\n\";\n" , "Foo\n"); MVCRO("f().\"\\n\";\n" , "Bar\n"); MVCRO("f();\n" " }\n" "}\n" "$b = new Bar();\n" "echo $b->inv().\"\\n\";\n" , "Bar\n"); MVCRO("f();\n" " }\n" "}\n" "$b = new Bar();\n" "echo $b->inv().\"\\n\";\n" , "Bar\n"); MVCRO("f();\n" " }\n" "}\n" "$b = new Bar();\n" "echo $b->inv().\"\\n\";\n" , "Bar\n"); MVCRO("hello();\n" "$oc = new C();\n" "$oc->hello();\n" "$od = new D();\n" "$od->hello();\n" , "Hello from B!\n" "Hello from B!\n" "Hello from B!\n" ); MVCRO("foo();\n" , "hello\n"); MVCRO("foo();\n" , "hello\n"); MVCRO("foo();\n" , "hello\n"); MVCRO("foo();\n" , "C::hello\n"); MVCRO("foo();\n" , "B::hello\n"); MVCRO("foo(); }" "}" "trait BT {" " function foo() { var_dump('ok'); }" "}" "class B extends A {" " use BT;" "}" "function test() {" " $b = new B;" " $b->bar();" "}" "test();", "string(2) \"ok\"\n"); MVCRO("getProperties() as $prop) {\n" " $props[] = $prop->getName();\n" " }\n" " asort($props);\n" " show_without_extra_vardump_nonsense($props);\n" " $meths = array();\n" " echo \"yall know what time it is now too. time to show you some methods\\n\";\n" " foreach ($r->getMethods() as $meth) {\n" " $meths[] = $meth->getName();\n" " }\n" " asort($meths);\n" " show_without_extra_vardump_nonsense($meths);\n" "}\n" "\n" "trait T {\n" " private $priv;\n" " protected $prot;\n" " public $pub;\n" "\n" " private static $priv_st;\n" " protected static $prot_st;\n" " public static $pub_st;\n" "\n" " private function fpriv() {}\n" " protected function fprot() {}\n" " public function fpub() {}\n" "\n" " private static function fpriv_st() {}\n" " protected static function fprot_st() {}\n" " public static function fpub_st() {}\n" "}\n" "\n" "trait U {\n" " public $foo;\n" " public static $static;\n" "\n" " public function ffoo() {}\n" " public static function fstatic() {}\n" "}\n" "\n" "class C {\n" " use T;\n" "\n" " private $c_priv;\n" "}\n" "\n" "class D extends C {\n" " use U;\n" "\n" " public $class_prop;\n" " public function class_method() {}\n" "\n" "}\n" "\n" "$r = new ReflectionClass('C');\n" "do_wonderful_things_with($r);\n" "\n" "$r = new ReflectionClass('D');\n" "do_wonderful_things_with($r);\n" , "yall know what time it is. time to show you some properties\n" "array (7) {\n" " c_priv\n" " priv\n" " priv_st\n" " prot\n" " prot_st\n" " pub\n" " pub_st\n" "}\n" "yall know what time it is now too. time to show you some methods\n" "array (6) {\n" " fpriv\n" " fpriv_st\n" " fprot\n" " fprot_st\n" " fpub\n" " fpub_st\n" "}\n" "yall know what time it is. time to show you some properties\n" "array (7) {\n" " class_prop\n" " foo\n" " prot\n" " prot_st\n" " pub\n" " pub_st\n" " static\n" "}\n" "yall know what time it is now too. time to show you some methods\n" "array (9) {\n" " class_method\n" " ffoo\n" " fpriv\n" " fpriv_st\n" " fprot\n" " fprot_st\n" " fpub\n" " fpub_st\n" " fstatic\n" "}\n" ); return true; } bool TestCodeRun::TestUConverter() { // ext/intl/tests/uconverter_enum.phpt MVCRO(" 100);" "var_dump(in_array('UTF-7', $avail));" "var_dump(in_array('CESU-8', $avail));" "var_dump(in_array('ISO-8859-1', $avail));" "$latin1 = UConverter::getAliases('latin1');" "var_dump(in_array('ISO-8859-1', $latin1));" , "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" ); // ext/intl/tests/uconverter_func_basic.phpt MVCRO(" $subst);" " $ret = UConverter::transcode(\"This is an ascii string\", 'ascii', 'utf-8', $opts);" " if ($ret === NULL) {" " echo \"Error: \", intl_get_error_message(), \"\\n\";" " } else {" " var_dump($ret);" " }" " $ret = UConverter::transcode(\"Snowman: (\\xE2\\x98\\x83)\", 'ascii', 'utf-8', $opts);" " if ($ret === NULL) {" " echo \"Error: \", intl_get_error_message(), \"\\n\";" " } else {" " var_dump($ret);" " }" "}" , "string(23) \"This is an ascii string\"\n" "string(12) \"Snowman: (?)\"\n" "Error: ucnv_setSubstChars() returned error 1: U_ILLEGAL_ARGUMENT_ERROR\n" "Error: ucnv_setSubstChars() returned error 1: U_ILLEGAL_ARGUMENT_ERROR\n" "Error: ucnv_setSubstChars() returned error 1: U_ILLEGAL_ARGUMENT_ERROR\n" "Error: ucnv_setSubstChars() returned error 1: U_ILLEGAL_ARGUMENT_ERROR\n" ); // ext/intl/tests/uconverter_oop_algo.phpt MVCRO("getSourceType());" "var_dump(UConverter::UTF8 === $c->getDestinationType());" "$c = new UConverter('koi8-r', 'utf-32be');" "var_dump(UConverter::UTF32_BigEndian === $c->getSourceType());" "var_dump(UConverter::SBCS === $c->getDestinationType());" , "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" ); // ext/intl/tests/uconverter_oop_basic.phpt MVCRO("convert(\"This is an ascii string\"));" "var_dump(urlencode($c->convert(\"Espa\\xF1ol\")));" "var_dump(urlencode($c->convert(\"Stra\\xDFa\")));" "var_dump(urlencode($c->convert(\"Stra\\xC3\\x9Fa\", true)));" "$k = new UConverter('utf-8', 'koi8-r');" "var_dump(bin2hex($k->convert(\"\\xE4\")));" , "string(23) \"This is an ascii string\"\n" "string(12) \"Espa%C3%B1ol\"\n" "string(11) \"Stra%C3%9Fa\"\n" "string(8) \"Stra%DFa\"\n" "string(4) \"d094\"\n" ); // ext/intl/tests/uconverter_oop_callback.phpt MVCRO("convert($word);" "}" "unset($c);" , "toUCallback(REASON_RESET, ...)\n" "toUCallback(REASON_RESET, ...)\n" "fromUCallback(REASON_RESET, ...)\n" "fromUCallback(REASON_RESET, ...)\n" "toUCallback(REASON_RESET, ...)\n" "toUCallback(REASON_ILLEGAL, ...)\n" "toUCallback(REASON_RESET, ...)\n" "toUCallback(REASON_ILLEGAL, ...)\n" "fromUCallback(REASON_RESET, ...)\n" "fromUCallback(REASON_UNASSIGNED, ...)\n" "fromUCallback(REASON_RESET, ...)\n" "fromUCallback(REASON_UNASSIGNED, ...)\n" "toUCallback(REASON_RESET, ...)\n" "toUCallback(REASON_RESET, ...)\n" "fromUCallback(REASON_RESET, ...)\n" "fromUCallback(REASON_UNASSIGNED, ...)\n" "fromUCallback(REASON_RESET, ...)\n" "fromUCallback(REASON_UNASSIGNED, ...)\n" "toUCallback(REASON_CLOSE, ...)\n" "fromUCallback(REASON_CLOSE, ...)\n" "toUCallback(REASON_CLOSE, ...)\n" "fromUCallback(REASON_CLOSE, ...)\n" ); // ext/intl/tests/uconverter_oop_callback_return.phpt MVCRO("convert(\"\\x80\\x81\\x82\\x83\"));" "var_dump($c->convert(\"\\xC3\\xB1\\xC3\\xB2\\xC3\\xB3\\xC3\\xB4\"));" , "string(3) \"abc\"\n" "string(3) \"ABC\"\n" ); // ext/intl/tests/uconverter_oop_subst.phpt MVCRO("') as $subst) {" " if (!$c->setSubstChars($subst)) {" " echo \"**Disallowed\\n\";" " continue;" " }" " var_dump($c->convert(\"This is an ascii string\"));" " var_dump($c->convert(\"Snowman: (\\xE2\\x98\\x83)\"));" "}" , "string(23) \"This is an ascii string\"\n" "string(12) \"Snowman: (?)\"\n" "**Disallowed\n" "**Disallowed\n" ); MVCRO("", ""); // Wrong type, fail MVCRONW("(X $a) { echo 1; } t(42);", "1"); // Generic with as MVCRO("{}", ""); // Silent type hint MVCRO("> {}", ""); // Arrays with generic types MVCRO(" $x) {}", ""); MVCRO(" $x) {}", ""); // Kitchen sink MVCRO("(blarg $list, int $idx):X {\n" " return $list->d[$idx];\n" "}\n" "function pair(X $x, Y $y):(X,Y) { return array($x, $y); }\n" "function car((X,?Y) $pair):X {\n" " return $pair[0];\n" "}\n" "interface Face {\n" "}\n" "class blarg { function __construct($x) { $this->d = $x; } }\n" "function blarg(/*...*/):blarg { return new blarg(func_get_args()); }\n" "\n" "class Foo implements Face {\n" " const string BLEH = \"b\";\n" "}\n" "\n" "$blork = pair('c', '-');\n" "\n" "function right_shift_hack(Foo,Foo>>,Foo>>>,Foo>>>> $bonk,\n" " (function(Foo,Bar):C) $d) {\n" "}\n" "\n" "$a = blarg('a','aa','aaa');\n" "$d = (function():UNICORNS{return 'd';});\n" "echo vidx($a, 0), Foo::BLEH, car($blork), $d();\n", "abcd"); MVCRO("();\n" " $x = new Foo>();\n" " $y = new Foo();\n" " $z = new Foo,Blah>();\n" " yo();\n" " yo>();\n" " yo();\n" " yo,Blah<:my:xhp:class>>();\n" " $x->baz();\n" " $x->baz>();\n" " $y->baz();\n" " $y->baz,Blah<:my:xhp:class>>();\n" " Foo::biz();\n" " Foo>::biz();\n" " Foo::biz();\n" " Foo>::biz>();\n" " Foo::biz();\n" " Foo>::biz,Blah<:my:xhp:class>>();\n" " Foo::biz();\n" " Foo,Blah>::biz();\n" " Foo::biz();\n" " Foo,Blah>::biz>();\n" " Foo::biz();\n" " Foo,Blah>::biz,Blah<:my:xhp:class>>();\n" " var_dump(Foo::SOME_CONST);\n" " var_dump(Foo>::SOME_CONST);\n" " var_dump(Foo::SOME_CONST);\n" " var_dump(Foo,Blah>::SOME_CONST);\n" " var_dump(Foo::$staticProp);\n" " var_dump(Foo>::$staticProp);\n" " var_dump(Foo::$staticProp);\n" " var_dump(Foo,Blah>::$staticProp);\n" "}\n" "echo \"Done\\n\";\n" , "Done\n" ); MVCRO(";\n" " abstract function g2() : Foo<(function(int):void)>;\n" " abstract function g3() : Foo<(function(int,string):void)>;\n" " abstract function g4() : Foo<(function(...):void)>;\n" " abstract function g5() : Foo<(function(int,...):void)>;\n" " abstract function g6() : Foo<(function(int,string,...):void)>;\n" " abstract function h1((function():void) $x) : void;\n" " abstract function h2((function(int):void) $x) : void;\n" " abstract function h3((function(int,string):void) $x) : void;\n" " abstract function h4((function(...):void) $x) : void;\n" " abstract function h5((function(int,...):void) $x) : void;\n" " abstract function h6((function(int,string,...):void) $x) : void;\n" " abstract function j1(Foo<(function():void)> $x) : void;\n" " abstract function j2(Foo<(function(int):void)> $x) : void;\n" " abstract function j3(Foo<(function(int,string):void)> $x) : void;\n" " abstract function j4(Foo<(function(...):void)> $x): void;\n" " abstract function j5(Foo<(function(int,...):void)> $x): void;\n" " abstract function j6(Foo<(function(int,string,...):void)> $x): " "void;\n" "}\n" "echo \"Done\\n\";\n" , "Done\n" ); return true; } // please leave this unit test at last for debugging ad hoc code bool TestCodeRun::TestAdHoc() { return true; }