void ForEachStatement::eval(VariableEnvironment &env) const { if (env.isGotoing()) return; ENTER_STMT; DECLARE_THREAD_INFO; LOOP_COUNTER(1); Variant map(m_source->eval(env)); if (m_key) { TempExpressionList *texp = m_key->cast<TempExpressionList>(); if (texp) { for (ArrayIter iter = map.begin(env.currentContext(), true); !iter.end(); iter.next()) { { LOOP_COUNTER_CHECK_INFO(1); const Variant &value = iter.second(); const Variant &key = iter.first(); TempExpressionHelper helper(texp, env); m_value->set(env, value); texp->setImpl(env, key); } if (!m_body) continue; EVAL_STMT_HANDLE_GOTO_BEGIN(restart1); EVAL_STMT_HANDLE_BREAK(m_body, env); EVAL_STMT_HANDLE_GOTO_END(restart1); } } else { for (ArrayIter iter = map.begin(env.currentContext(), true); !iter.end(); iter.next()) { LOOP_COUNTER_CHECK_INFO(1); const Variant &value = iter.second(); const Variant &key = iter.first(); m_value->set(env, value); m_key->set(env, key); if (!m_body) continue; EVAL_STMT_HANDLE_GOTO_BEGIN(restart2); EVAL_STMT_HANDLE_BREAK(m_body, env); EVAL_STMT_HANDLE_GOTO_END(restart2); } } } else { for (ArrayIter iter = map.begin(env.currentContext(), true); !iter.end(); iter.next()) { LOOP_COUNTER_CHECK_INFO(1); m_value->set(env, iter.second()); if (!m_body) continue; EVAL_STMT_HANDLE_GOTO_BEGIN(restart3); EVAL_STMT_HANDLE_BREAK(m_body, env); EVAL_STMT_HANDLE_GOTO_END(restart3); } } }
void BaseMap::setAllImpl(const Variant& iterable) { if (iterable.isNull()) return; size_t sz; ArrayIter iter = getArrayIterHelper(iterable, sz); for (; iter; ++iter) { set(iter.first(), iter.second()); } }
bool BuiltinSymbols::Load(AnalysisResultPtr ar, bool extOnly /* = false */) { if (Loaded) return true; Loaded = true; // load extension functions first, so system/classes may call them ParseExtFunctions(ar, ExtensionFunctions, false); AnalysisResultPtr ar2 = AnalysisResultPtr(new AnalysisResult()); s_variables = VariableTablePtr(new VariableTable(*ar2.get())); s_constants = ConstantTablePtr(new ConstantTable(*ar2.get())); // parse all PHP files under system/classes if (!extOnly) { ar = AnalysisResultPtr(new AnalysisResult()); ar->loadBuiltinFunctions(); string slib = systemlib_path(); if (slib.empty()) { for (const char **cls = SystemClasses; *cls; cls++) { string phpBaseName = "/system/classes/"; phpBaseName += *cls; phpBaseName += ".php"; Parse(ar, phpBaseName, Option::GetSystemRoot() + phpBaseName); } } else { Parse(ar, slib, slib); } ar->analyzeProgram(true); ar->inferTypes(); const StringToFileScopePtrMap &files = ar->getAllFiles(); for (StringToFileScopePtrMap::const_iterator iterFile = files.begin(); iterFile != files.end(); iterFile++) { const StringToClassScopePtrVecMap &classes = iterFile->second->getClasses(); for (StringToClassScopePtrVecMap::const_iterator iter = classes.begin(); iter != classes.end(); ++iter) { assert(iter->second.size() == 1); iter->second[0]->setSystem(); assert(!s_classes[iter->first]); s_classes[iter->first] = iter->second[0]; } } } else { NoSuperGlobals = true; } // load extension constants, classes and dynamics ParseExtConsts(ar, ExtensionConsts, false); ParseExtClasses(ar, ExtensionClasses, false); for (unsigned int i = 0; i < Option::SepExtensions.size(); i++) { Option::SepExtensionOptions &options = Option::SepExtensions[i]; string soname = options.soname; if (soname.empty()) { soname = string("lib") + options.name + ".so"; } if (!options.lib_path.empty()) { soname = options.lib_path + "/" + soname; } if (!LoadSepExtensionSymbols(ar, options.name, soname)) { return false; } } if (!extOnly) { Array constants = ClassInfo::GetSystemConstants(); LocationPtr loc(new Location); for (ArrayIter it = constants.begin(); it; ++it) { CVarRef key = it.first(); if (!key.isString()) continue; std::string name = key.toCStrRef().data(); if (s_constants->getSymbol(name)) continue; if (name == "true" || name == "false" || name == "null") continue; CVarRef value = it.secondRef(); if (!value.isInitialized() || value.isObject()) continue; ExpressionPtr e = Expression::MakeScalarExpression(ar2, ar2, loc, value); TypePtr t = value.isNull() ? Type::Null : value.isBoolean() ? Type::Boolean : value.isInteger() ? Type::Int64 : value.isDouble() ? Type::Double : value.isArray() ? Type::Array : Type::Variant; s_constants->add(key.toCStrRef().data(), t, e, ar2, e); } s_variables = ar2->getVariables(); for (int i = 0, n = NumGlobalNames(); i < n; ++i) { s_variables->add(GlobalNames[i], Type::Variant, false, ar, ConstructPtr(), ModifierExpressionPtr()); } } s_constants->setDynamic(ar, "SID", true); return true; }
bool BuiltinSymbols::Load(AnalysisResultPtr ar) { if (Loaded) return true; Loaded = true; if (g_context.isNull()) init_thread_locals(); ClassInfo::Load(); // load extension functions first, so system/php may call them ImportExtFunctions(ar, ClassInfo::GetSystem()); ConstantTablePtr cns = ar->getConstants(); // load extension constants, classes and dynamics ImportNativeConstants(ar, cns); ImportExtConstants(ar, cns, ClassInfo::GetSystem()); ImportExtClasses(ar); Array constants = ClassInfo::GetSystemConstants(); LocationPtr loc(new Location); for (ArrayIter it = constants.begin(); it; ++it) { CVarRef key = it.first(); if (!key.isString()) continue; std::string name = key.toCStrRef().data(); if (cns->getSymbol(name)) continue; if (name == "true" || name == "false" || name == "null") continue; CVarRef value = it.secondRef(); if (!value.isInitialized() || value.isObject()) continue; ExpressionPtr e = Expression::MakeScalarExpression(ar, ar, loc, value); TypePtr t = value.isNull() ? Type::Null : value.isBoolean() ? Type::Boolean : value.isInteger() ? Type::Int64 : value.isDouble() ? Type::Double : value.isArray() ? Type::Array : Type::Variant; cns->add(key.toCStrRef().data(), t, e, ar, e); } for (int i = 0, n = NumGlobalNames(); i < n; ++i) { ar->getVariables()->add(GlobalNames[i], Type::Variant, false, ar, ConstructPtr(), ModifierExpressionPtr()); } cns->setDynamic(ar, "PHP_BINARY", true); cns->setDynamic(ar, "PHP_BINDIR", true); cns->setDynamic(ar, "PHP_OS", true); cns->setDynamic(ar, "PHP_SAPI", true); cns->setDynamic(ar, "SID", true); // Systemlib files were all parsed by hphp_process_init const StringToFileScopePtrMap &files = ar->getAllFiles(); for (const auto& file : files) { file.second->setSystem(); const auto& classes = file.second->getClasses(); for (const auto& clsVec : classes) { assert(clsVec.second.size() == 1); auto cls = clsVec.second[0]; cls->setSystem(); ar->addSystemClass(cls); for (const auto& func : cls->getFunctions()) { FunctionScope::RecordFunctionInfo(func.first, func.second); } } const auto& functions = file.second->getFunctions(); for (const auto& func : functions) { func.second->setSystem(); ar->addSystemFunction(func.second); FunctionScope::RecordFunctionInfo(func.first, func.second); } } return true; }
bool WddxPacket::recursiveAddVar(const String& varName, const Variant& varVariant, bool hasVarTag) { bool isArray = varVariant.isArray(); bool isObject = varVariant.isObject(); if (isArray || isObject) { if (hasVarTag) { m_packetString.append("<var name='"); m_packetString.append(varName.data()); m_packetString.append("'>"); } Array varAsArray; Object varAsObject = varVariant.toObject(); if (isArray) varAsArray = varVariant.toArray(); if (isObject) varAsArray = varAsObject.toArray(); int length = varAsArray.length(); if (length > 0) { ArrayIter it = ArrayIter(varAsArray); if (it.first().isString()) isObject = true; if (isObject) { m_packetString.append("<struct>"); if (!isArray) { m_packetString.append("<var name='php_class_name'><string>"); m_packetString.append(varAsObject->getClassName()); m_packetString.append("</string></var>"); } } else { m_packetString.append("<array length='"); m_packetString.append(std::to_string(length)); m_packetString.append("'>"); } for (ArrayIter it(varAsArray); it; ++it) { Variant key = it.first(); Variant value = it.second(); recursiveAddVar(key.toString(), value, isObject); } if (isObject) { m_packetString.append("</struct>"); } else { m_packetString.append("</array>"); } } else { //empty object if (isObject) { m_packetString.append("<struct>"); if (!isArray) { m_packetString.append("<var name='php_class_name'><string>"); m_packetString.append(varAsObject->getClassName()); m_packetString.append("</string></var>"); } m_packetString.append("</struct>"); } } if (hasVarTag) { m_packetString.append("</var>"); } return true; } String varType = getDataTypeString(varVariant.getType()); if (!getWddxEncoded(varType, "", varName, false).empty()) { String varValue; if (varType.compare("boolean") == 0) { varValue = varVariant.toBoolean() ? "true" : "false"; } else { varValue = StringUtil::HtmlEncode(varVariant.toString(), StringUtil::QuoteStyle::Double, "UTF-8", false, false).toCppString(); } m_packetString.append( getWddxEncoded(varType, varValue, varName, hasVarTag)); return true; } return false; }
bool TestCppBase::TestArray() { // Array::Create(), Array constructors and informational { Array arr; VERIFY(arr.empty()); VERIFY(arr.size() == 0); VERIFY(arr.length() == 0); VERIFY(arr.isNull()); arr = Array::Create(); VERIFY(arr.empty()); VERIFY(arr.size() == 0); VERIFY(arr.length() == 0); VERIFY(!arr.isNull()); arr = Array::Create(0); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY((int)arr[0] == 0); VS(arr, Array(ArrayInit(1).set(0).create())); arr = Array::Create("test"); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY(arr[0] == "test"); VS(arr, Array(ArrayInit(1).set("test").create())); Array arrCopy = arr; arr = Array::Create(arr); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY(arr[0].toArray().size() == 1); VS(arr[0], arrCopy); VS(arr, Array(ArrayInit(1).set(arrCopy).create())); arr = Array::Create("name", 1); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY((int)arr[s_name] == 1); VS(arr, Array(ArrayInit(1).set(s_name, 1).create())); arr = Array::Create(s_name, "test"); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY(arr[s_name] == "test"); VS(arr, Array(ArrayInit(1).set(s_name, "test").create())); arrCopy = arr; arr = Array::Create(s_name, arr); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VS(arr[s_name], arrCopy); VERIFY(arr[s_name].toArray().size() == 1); VS(arr, Array(ArrayInit(1).set(s_name, arrCopy).create())); } // iteration { Array arr = CREATE_MAP2("n1", "v1", "n2", "v2"); int i = 0; for (ArrayIter iter = arr.begin(); iter; ++iter, ++i) { if (i == 0) { VERIFY(iter.first() == "n1"); VERIFY(iter.second() == "v1"); } else { VERIFY(iter.first() == "n2"); VERIFY(iter.second() == "v2"); } } VERIFY(i == 2); } /* TODO: fix this { Variant arr = CREATE_MAP2("n1", "v1", "n2", "v2"); arr.escalate(); for (ArrayIterPtr iter = arr.begin(arr, true); !iter->end(); iter->next()){ unset(arr.lvalAt(iter->first())); } VS(arr, Array::Create()); } */ // conversions { Array arr0; VERIFY(arr0.toBoolean() == false); VERIFY(arr0.toByte() == 0); VERIFY(arr0.toInt16() == 0); VERIFY(arr0.toInt32() == 0); VERIFY(arr0.toInt64() == 0); VERIFY(arr0.toDouble() == 0.0); VERIFY(arr0.toString() == ""); Array arr1 = Array::Create("test"); VERIFY(arr1.toBoolean() == true); VERIFY(arr1.toByte() == 1); VERIFY(arr1.toInt16() == 1); VERIFY(arr1.toInt32() == 1); VERIFY(arr1.toInt64() == 1); VERIFY(arr1.toDouble() == 1.0); VERIFY(arr1.toString() == "Array"); } // offset { Array arr; arr.set(0, "v1"); arr.set(1, "v2"); VS(arr, CREATE_VECTOR2("v1", "v2")); } { Array arr; arr.set(s_n1, "v1"); arr.set(s_n2, "v2"); VS(arr, CREATE_MAP2("n1", "v1", "n2", "v2")); } { Array arr; arr.lvalAt(0) = String("v1"); arr.lvalAt(1) = String("v2"); VS(arr, CREATE_VECTOR2("v1", "v2")); } { Array arr; arr.lvalAt(s_n1) = String("v1"); arr.lvalAt(s_n2) = String("v2"); VS(arr, CREATE_MAP2("n1", "v1", "n2", "v2")); } { Array arr; Variant name = "name"; arr.lvalAt(name) = String("value"); VS(arr, CREATE_MAP1("name", "value")); } { Array arr; arr.lvalAt(s_A) = 10; arr.lvalAt(s_A)++; VS(arr[s_A], 11); } { Array arr; arr.lvalAt(1) = 10; VS(arr[1], 10); VS(arr[1.5], 10); VS(arr[Variant(1.5)], 10); VS(arr[s_1], 10); VS(arr[Variant("1")], 10); } { Array arr; arr.lvalAt(Variant(1.5)) = 10; VS(arr[1], 10); VS(arr[1.5], 10); VS(arr[Variant(1.5)], 10); VS(arr[s_1], 10); VS(arr[Variant("1")], 10); } { Array arr; arr.lvalAt(s_1) = 10; VS(arr[1], 10); VS(arr[1.5], 10); VS(arr[Variant(1.5)], 10); VS(arr[s_1], 10); VS(arr[Variant("1")], 10); } { Array arr; arr.lvalAt(Variant("1")) = 10; VS(arr[1], 10); VS(arr[1.5], 10); VS(arr[Variant(1.5)], 10); VS(arr[s_1], 10); VS(arr[Variant("1")], 10); } // membership { Array arr; arr.lvalAt(0) = String("v1"); arr.lvalAt(1) = String("v2"); VERIFY(arr.exists(0)); arr.remove(0); VERIFY(!arr.exists(0)); VS(arr, Array::Create(1, "v2")); arr.append("v3"); VS(arr, CREATE_MAP2(1, "v2", 2, "v3")); } { static const StaticString s_0("0"); Array arr; arr.lvalAt(0) = String("v1"); VERIFY(arr.exists(0)); arr.remove(String(s_0)); VERIFY(!arr.exists(0)); } { Array arr; arr.lvalAt(0) = String("v1"); VERIFY(arr.exists(0)); arr.remove(Variant("0")); VERIFY(!arr.exists(0)); } { Array arr; arr.lvalAt(0) = String("v1"); VERIFY(arr.exists(0)); arr.remove(Variant(Variant("0"))); VERIFY(!arr.exists(0)); } { Array arr; arr.lvalAt(0) = String("v1"); VERIFY(arr.exists(0)); arr.remove(Variant(Variant(0.5))); VERIFY(!arr.exists(0)); } { Array arr; arr.lvalAt(Variant()) = 123; VERIFY(arr.exists(empty_string)); arr.remove(Variant()); VERIFY(!arr.exists(empty_string)); } { Array arr; arr.lvalAt(s_n1) = String("v1"); arr.lvalAt(s_n2) = String("v2"); VERIFY(arr.exists(s_n1)); arr.remove(s_n1); VERIFY(!arr.exists(s_n1)); VS(arr, Array::Create(s_n2, "v2")); arr.append("v3"); VS(arr, CREATE_MAP2("n2", "v2", 0, "v3")); } { Array arr; arr.lvalAt() = String("test"); VS(arr, CREATE_VECTOR1("test")); } { Array arr; arr.lvalAt(s_name) = String("value"); VERIFY(arr.exists(s_name)); } { Array arr; arr.lvalAt(1) = String("value"); VERIFY(arr.exists(1)); VERIFY(arr.exists(1.5)); VERIFY(arr.exists(s_1)); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } { Array arr; arr.lvalAt(s_1) = String("value"); VERIFY(arr.exists(1)); VERIFY(arr.exists(1.5)); VERIFY(arr.exists(s_1)); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } { Array arr; arr.lvalAt(1.5) = String("value"); VERIFY(arr.exists(1)); VERIFY(arr.exists(1.5)); VERIFY(arr.exists(s_1)); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } { Array arr; arr.lvalAt(Variant(1.5)) = String("value"); VERIFY(arr.exists(1)); VERIFY(arr.exists(1.5)); VERIFY(arr.exists(s_1)); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } { Array arr; arr.lvalAt(Variant("1")) = String("value"); VERIFY(arr.exists(1)); VERIFY(arr.exists(1.5)); VERIFY(arr.exists(s_1)); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } // merge { Array arr = Array::Create(0) + Array::Create(1); VS(arr, Array::Create(0)); arr += CREATE_VECTOR2(0, 1); VS(arr, CREATE_VECTOR2(0, 1)); arr = Array::Create(0).merge(Array::Create(1)); VS(arr, CREATE_VECTOR2(0, 1)); arr = arr.merge(CREATE_VECTOR2(0, 1)); VS(arr, CREATE_VECTOR4(0, 1, 0, 1)); arr = Array::Create("s0").merge(Array::Create("s1")); VS(arr, CREATE_VECTOR2("s0", "s1")); arr = Array::Create("n0", "s0") + Array::Create("n1", "s1"); VS(arr, CREATE_MAP2("n0", "s0", "n1", "s1")); arr += CREATE_MAP2("n0", "s0", "n1", "s1"); VS(arr, CREATE_MAP2("n0", "s0", "n1", "s1")); arr = Array::Create("n0", "s0").merge(Array::Create("n1", "s1")); VS(arr, CREATE_MAP2("n0", "s0", "n1", "s1")); Array arrX = CREATE_MAP2("n0", "s2", "n1", "s3"); arr = arr.merge(arrX); VS(arr, CREATE_MAP2("n0", "s2", "n1", "s3")); } // slice { Array arr = CREATE_VECTOR2("test1", "test2"); Array sub = arr.slice(1, 1, true); VS(sub, CREATE_MAP1(1, "test2")); } { Array arr = CREATE_VECTOR2("test1", "test2"); Array sub = arr.slice(1, 1, false); VS(sub, CREATE_VECTOR1("test2")); } { Array arr = CREATE_MAP2("n1", "test1", "n2", "test2"); Array sub = arr.slice(1, 1, true); VS(sub, CREATE_MAP1("n2", "test2")); } { Array arr = CREATE_MAP2("n1", "test1", "n2", "test2"); Array sub = arr.slice(1, 1, false); VS(sub, CREATE_MAP1("n2", "test2")); } // escalation { Array arr; lval(arr.lvalAt(0)).lvalAt(0) = 1.2; VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2))); } { Array arr; lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2; VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2))); } { Array arr = Array::Create(); lval(arr.lvalAt(0)).lvalAt(0) = 1.2; VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2))); } { Array arr = Array::Create(); lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2; VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2))); } { Array arr = Array::Create("test"); arr.lvalAt(0) = CREATE_VECTOR1(1.2); VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2))); } { Array arr = Array::Create("test"); lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2; VS(arr, CREATE_MAP2(0, "test", s_name, CREATE_VECTOR1(1.2))); } { Array arr = Array::Create(); arr.append("apple"); arr.set(2, "pear"); VS(arr[2], "pear"); } { Array arr = CREATE_MAP2(0, "a", 1, "b"); VERIFY(arr->isVectorData()); } { Array arr = CREATE_MAP2(1, "a", 0, "b"); VERIFY(!arr->isVectorData()); } { Array arr = CREATE_MAP2(1, "a", 2, "b"); VERIFY(!arr->isVectorData()); } { Array arr = CREATE_MAP1(1, "a"); arr.set(0, "b"); VERIFY(!arr->isVectorData()); } return Count(true); }
bool TestExtPdo::test_pdo_sqlite() { CreateSqliteTestTable(); try { string source = "sqlite:/tmp/foo.db"; p_PDO dbh(NEWOBJ(c_PDO)()); dbh->t___construct(source.c_str(), TEST_USERNAME, TEST_PASSWORD, CREATE_MAP1(q_PDO$$ATTR_PERSISTENT, false)); Variant vstmt = dbh->t_prepare("select * from foo"); c_PDOStatement *stmt = vstmt.toObject().getTyped<c_PDOStatement>(); VERIFY(stmt->t_execute()); Variant rs = stmt->t_fetch(q_PDO$$FETCH_ASSOC); VS(rs, CREATE_MAP1("bar", "ABC")); rs = stmt->t_fetch(q_PDO$$FETCH_ASSOC); VS(rs, CREATE_MAP1("bar", "DEF")); } catch (Object &e) { VS(e, null); } try { string source = "sqlite:/tmp/foo.db"; p_PDO dbh(NEWOBJ(c_PDO)()); dbh->t___construct(source.c_str(), TEST_USERNAME, TEST_PASSWORD, CREATE_MAP1(q_PDO$$ATTR_PERSISTENT, false)); Variant vstmt = dbh->t_query("select * from foo"); ArrayIter iter = vstmt.begin(); VERIFY(!iter.end()); VS(iter.first(), 0); VS(iter.second(), CREATE_MAP2("bar", "ABC", 0, "ABC")); iter.next(); VERIFY(!iter.end()); VS(iter.first(), 1); VS(iter.second(), CREATE_MAP2("bar", "DEF", 0, "DEF")); iter.next(); VERIFY(iter.end()); } catch (Object &e) { VS(e, null); } try { string source = "sqlite:/tmp/foo.db"; p_PDO dbh(NEWOBJ(c_PDO)()); dbh->t___construct(source.c_str(), TEST_USERNAME, TEST_PASSWORD, CREATE_MAP1(q_PDO$$ATTR_PERSISTENT, false)); dbh->t_query("CREATE TABLE IF NOT EXISTS foobar (id INT)"); dbh->t_query("INSERT INTO foobar (id) VALUES (1)"); Variant res = dbh->t_query("SELECT id FROM foobar LIMIT 1"); c_PDOStatement *stmt = res.toObject().getTyped<c_PDOStatement>(); Variant ret = stmt->t_fetch(); VS(ret["id"], "1"); } catch (Object &e) { VS(e, null); } CleanupSqliteTestTable(); return Count(true); }
bool WddxPacket::recursiveAddVarImpl(const String& varName, const Variant& varVariant, bool hasVarTag, SeenContainers& seen) { bool isArray = varVariant.isArray(); bool isObject = varVariant.isObject(); if (isArray || isObject) { Array varAsArray; Object varAsObject; ArrayOrObject ptr; if (isArray) { varAsArray = varVariant.toArray(); ptr = varAsArray.get(); } if (isObject) { varAsObject = varVariant.toObject(); varAsArray = varAsObject.toArray(); ptr = varAsObject.get(); } assert(!ptr.isNull()); if (!seen.emplace(ptr).second) { raise_warning("recursion detected"); return false; } SCOPE_EXIT { seen.erase(ptr); }; if (hasVarTag) { m_packetString.append("<var name='"); m_packetString.append(varName.data()); m_packetString.append("'>"); } int length = varAsArray.length(); if (length > 0) { ArrayIter it = ArrayIter(varAsArray); if (it.first().isString()) isObject = true; if (isObject) { m_packetString.append("<struct>"); if (!isArray) { m_packetString.append("<var name='php_class_name'><string>"); m_packetString.append(varAsObject->getClassName()); m_packetString.append("</string></var>"); } } else { m_packetString.append("<array length='"); m_packetString.append(std::to_string(length)); m_packetString.append("'>"); } for (; it; ++it) { auto key = it.first(); auto const& value = it.secondRef(); recursiveAddVarImpl(key.toString(), value, isObject, seen); } if (isObject) { m_packetString.append("</struct>"); } else { m_packetString.append("</array>"); } } else { //empty object if (isObject) { m_packetString.append("<struct>"); if (!isArray) { m_packetString.append("<var name='php_class_name'><string>"); m_packetString.append(varAsObject->getClassName()); m_packetString.append("</string></var>"); } m_packetString.append("</struct>"); } } if (hasVarTag) { m_packetString.append("</var>"); } return true; }
bool TestCppBase::TestArray() { // Array::Create(), Array constructors and informational { Array arr; VERIFY(arr.empty()); VERIFY(arr.size() == 0); VERIFY(arr.length() == 0); VERIFY(arr.isNull()); arr = Array::Create(); VERIFY(arr.empty()); VERIFY(arr.size() == 0); VERIFY(arr.length() == 0); VERIFY(!arr.isNull()); arr = Array::Create(0); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY(arr[0].toInt32() == 0); arr = Array::Create("test"); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY(equal(arr[0], String("test"))); Array arrCopy = arr; arr = Array::Create(arr); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY(arr[0].toArray().size() == 1); VS(arr[0], arrCopy); arr = Array::Create("name", 1); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY(arr[s_name].toInt32() == 1); arr = Array::Create(s_name, "test"); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY(equal(arr[s_name], String("test"))); arrCopy = arr; arr = Array::Create(s_name, arr); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VS(arr[s_name], arrCopy); VERIFY(arr[s_name].toArray().size() == 1); } // iteration { Array arr = make_map_array("n1", "v1", "n2", "v2"); int i = 0; for (ArrayIter iter = arr.begin(); iter; ++iter, ++i) { if (i == 0) { VERIFY(equal(iter.first(), String("n1"))); VERIFY(equal(iter.second(), String("v1"))); } else { VERIFY(equal(iter.first(), String("n2"))); VERIFY(equal(iter.second(), String("v2"))); } } VERIFY(i == 2); } static const StaticString s_Array("Array"); // conversions { Array arr0; VERIFY(arr0.toBoolean() == false); VERIFY(arr0.toByte() == 0); VERIFY(arr0.toInt16() == 0); VERIFY(arr0.toInt32() == 0); VERIFY(arr0.toInt64() == 0); VERIFY(arr0.toDouble() == 0.0); VERIFY(arr0.toString().empty()); Array arr1 = Array::Create("test"); VERIFY(arr1.toBoolean() == true); VERIFY(arr1.toByte() == 1); VERIFY(arr1.toInt16() == 1); VERIFY(arr1.toInt32() == 1); VERIFY(arr1.toInt64() == 1); VERIFY(arr1.toDouble() == 1.0); VERIFY(arr1.toString() == s_Array); } // offset { Array arr; arr.set(0, "v1"); arr.set(1, "v2"); VS(arr, make_packed_array("v1", "v2")); } { Array arr; arr.set(s_n1, "v1"); arr.set(s_n2, "v2"); VS(arr, make_map_array("n1", "v1", "n2", "v2")); } { Array arr; arr.lvalAt(0) = String("v1"); arr.lvalAt(1) = String("v2"); VS(arr, make_packed_array("v1", "v2")); } { Array arr; arr.lvalAt(s_n1) = String("v1"); arr.lvalAt(s_n2) = String("v2"); VS(arr, make_map_array("n1", "v1", "n2", "v2")); } { Array arr; Variant name = "name"; arr.lvalAt(name) = String("value"); VS(arr, make_map_array("name", "value")); } { Array arr; arr.lvalAt(1) = 10; VS(arr[1], 10); VS(arr[Variant(1.5)], 10); VS(arr[s_1], 10); VS(arr[Variant("1")], 10); } { Array arr; arr.lvalAt(Variant(1.5)) = 10; VS(arr[1], 10); VS(arr[Variant(1.5)], 10); VS(arr[s_1], 10); VS(arr[Variant("1")], 10); } { Array arr; arr.lvalAt(s_1) = 10; VS(arr[1], 10); VS(arr[Variant(1.5)], 10); VS(arr[s_1], 10); VS(arr[Variant("1")], 10); } { Array arr; arr.lvalAt(Variant("1")) = 10; VS(arr[1], 10); VS(arr[Variant(1.5)], 10); VS(arr[s_1], 10); VS(arr[Variant("1")], 10); } // membership { Array arr; arr.lvalAt(0) = String("v1"); arr.lvalAt(1) = String("v2"); VERIFY(arr.exists(0)); arr.remove(0); VERIFY(!arr.exists(0)); VS(arr, Array::Create(1, "v2")); arr.append("v3"); VS(arr, make_map_array(1, "v2", 2, "v3")); } { static const StaticString s_0("0"); Array arr; arr.lvalAt(0) = String("v1"); VERIFY(arr.exists(0)); arr.remove(String(s_0)); VERIFY(!arr.exists(0)); } { Array arr; arr.lvalAt(0) = String("v1"); VERIFY(arr.exists(0)); arr.remove(Variant("0")); VERIFY(!arr.exists(0)); } { Array arr; arr.lvalAt(0) = String("v1"); VERIFY(arr.exists(0)); arr.remove(Variant(Variant("0"))); VERIFY(!arr.exists(0)); } { Array arr; arr.lvalAt(0) = String("v1"); VERIFY(arr.exists(0)); arr.remove(Variant(Variant(0.5))); VERIFY(!arr.exists(0)); } { Array arr; arr.lvalAt(Variant()) = 123; VERIFY(arr.exists(empty_string_ref)); arr.remove(Variant()); VERIFY(!arr.exists(empty_string_ref)); } { Array arr; arr.lvalAt(s_n1) = String("v1"); arr.lvalAt(s_n2) = String("v2"); VERIFY(arr.exists(s_n1)); arr.remove(s_n1); VERIFY(!arr.exists(s_n1)); VS(arr, Array::Create(s_n2, "v2")); arr.append("v3"); VS(arr, make_map_array("n2", "v2", 0, "v3")); } { Array arr; arr.lvalAt() = String("test"); VS(arr, make_packed_array("test")); } { Array arr; arr.lvalAt(s_name) = String("value"); VERIFY(arr.exists(s_name)); } { Array arr; arr.lvalAt(1) = String("value"); VERIFY(arr.exists(1)); VERIFY(arr.exists(s_1)); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } { Array arr; arr.lvalAt(s_1) = String("value"); VERIFY(arr.exists(1)); VERIFY(arr.exists(s_1)); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } { Array arr; arr.lvalAt(Variant(1.5)) = String("value"); VERIFY(arr.exists(1)); VERIFY(arr.exists(s_1)); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } { Array arr; arr.lvalAt(Variant("1")) = String("value"); VERIFY(arr.exists(1)); VERIFY(arr.exists(s_1)); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } // merge { Array arr = Array::Create(0) + Array::Create(1); VS(arr, Array::Create(0)); arr += make_packed_array(0, 1); VS(arr, make_packed_array(0, 1)); arr = Array::Create(0).merge(Array::Create(1)); VS(arr, make_packed_array(0, 1)); arr = arr.merge(make_packed_array(0, 1)); VS(arr, make_packed_array(0, 1, 0, 1)); arr = Array::Create("s0").merge(Array::Create("s1")); VS(arr, make_packed_array("s0", "s1")); arr = Array::Create("n0", "s0") + Array::Create("n1", "s1"); VS(arr, make_map_array("n0", "s0", "n1", "s1")); arr += make_map_array("n0", "s0", "n1", "s1"); VS(arr, make_map_array("n0", "s0", "n1", "s1")); arr = Array::Create("n0", "s0").merge(Array::Create("n1", "s1")); VS(arr, make_map_array("n0", "s0", "n1", "s1")); Array arrX = make_map_array("n0", "s2", "n1", "s3"); arr = arr.merge(arrX); VS(arr, make_map_array("n0", "s2", "n1", "s3")); } { Array arr = make_map_array(0, "a", 1, "b"); VERIFY(arr->isVectorData()); } { Array arr = make_map_array(1, "a", 0, "b"); VERIFY(!arr->isVectorData()); } { Array arr = make_map_array(1, "a", 2, "b"); VERIFY(!arr->isVectorData()); } { Array arr = make_map_array(1, "a"); arr.set(0, "b"); VERIFY(!arr->isVectorData()); } return Count(true); }
static Variant yaf_route_rewrite_match(const Object& o, const char* req_uri, int req_uri_len) { char match[8192]; auto ptr_match = o->o_realProp(YAF_ROUTE_PROPETY_NAME_MATCH, ObjectData::RealPropUnchecked, "Yaf_Route_Rewrite"); snprintf(match, sizeof(match), "%s", ptr_match->toString().c_str()); std::string pattern; pattern.append(YAF_ROUTE_REGEX_DILIMITER_STR); pattern.append("^"); char* save_ptr; char* seg = strtok_r(match, YAF_ROUTER_URL_DELIMIETER, &save_ptr); while (seg != NULL) { int len = strlen(seg); if (len) { pattern.append(YAF_ROUTER_URL_DELIMIETER); if (*seg == '*') { pattern.append("(?P<__yaf_route_rest>.*)"); break; } if (*seg == ':') { pattern.append("(?P<"); pattern.append(std::string(seg+1)); pattern.append(std::string(">[^") + YAF_ROUTER_URL_DELIMIETER + "]+)"); } else { pattern.append(seg); } } seg = strtok_r(NULL, YAF_ROUTER_URL_DELIMIETER, &save_ptr); } pattern.append(YAF_ROUTE_REGEX_DILIMITER_STR); pattern.append("i"); Variant matches; Variant ret = preg_match_all(String(pattern), String(std::string(req_uri, req_uri_len)), matches); int match_count = 0; if (ret.isIntVal() ) { match_count = ret.toInt32(); } if (match_count <= 0) { return init_null_variant; } if (!matches.isArray()) { return init_null_variant; } Array args = Array::Create(); Array& arr_matches = matches.toArrRef(); ArrayIter iter = arr_matches.begin(); while (!iter.end()) { Variant key = iter.first(); Variant value = iter.second(); if (!key.isString()) { iter.next(); continue; } if (!strncmp(key.toString().c_str(), "__yaf_route_rest", key.toString().length())) { Variant retval = yaf_router_parse_parameters(value.toArrRef()[0].toString().c_str()); if (retval.isArray()) { args.merge(retval.toArray()); } } else { args.set(key, value.toArrRef()[0]); } iter.next(); } return args; }
bool BuiltinSymbols::Load(AnalysisResultPtr ar, bool extOnly /* = false */) { if (Loaded) return true; Loaded = true; if (g_context.isNull()) init_thread_locals(); ClassInfo::Load(); // load extension functions first, so system/classes may call them ImportExtFunctions(ar, s_functions, ClassInfo::GetSystem()); AnalysisResultPtr ar2 = AnalysisResultPtr(new AnalysisResult()); s_variables = VariableTablePtr(new VariableTable(*ar2.get())); s_constants = ConstantTablePtr(new ConstantTable(*ar2.get())); // parse all PHP files under system/classes if (!extOnly) { ar = AnalysisResultPtr(new AnalysisResult()); ar->loadBuiltinFunctions(); string slib = get_systemlib(); Scanner scanner(slib.c_str(), slib.size(), Option::ScannerType, "systemlib.php"); Compiler::Parser parser(scanner, "systemlib.php", ar); if (!parser.parse()) { Logger::Error("Unable to parse systemlib.php: %s", parser.getMessage().c_str()); assert(false); } ar->analyzeProgram(true); ar->inferTypes(); const StringToFileScopePtrMap &files = ar->getAllFiles(); for (StringToFileScopePtrMap::const_iterator iterFile = files.begin(); iterFile != files.end(); iterFile++) { const StringToClassScopePtrVecMap &classes = iterFile->second->getClasses(); for (StringToClassScopePtrVecMap::const_iterator iter = classes.begin(); iter != classes.end(); ++iter) { assert(iter->second.size() == 1); iter->second[0]->setSystem(); assert(!s_classes[iter->first]); s_classes[iter->first] = iter->second[0]; } } } else { NoSuperGlobals = true; } // load extension constants, classes and dynamics ImportExtConstants(ar, s_constants, ClassInfo::GetSystem()); ImportExtClasses(ar); if (!extOnly) { Array constants = ClassInfo::GetSystemConstants(); LocationPtr loc(new Location); for (ArrayIter it = constants.begin(); it; ++it) { CVarRef key = it.first(); if (!key.isString()) continue; std::string name = key.toCStrRef().data(); if (s_constants->getSymbol(name)) continue; if (name == "true" || name == "false" || name == "null") continue; CVarRef value = it.secondRef(); if (!value.isInitialized() || value.isObject()) continue; ExpressionPtr e = Expression::MakeScalarExpression(ar2, ar2, loc, value); TypePtr t = value.isNull() ? Type::Null : value.isBoolean() ? Type::Boolean : value.isInteger() ? Type::Int64 : value.isDouble() ? Type::Double : value.isArray() ? Type::Array : Type::Variant; s_constants->add(key.toCStrRef().data(), t, e, ar2, e); } s_variables = ar2->getVariables(); for (int i = 0, n = NumGlobalNames(); i < n; ++i) { s_variables->add(GlobalNames[i], Type::Variant, false, ar, ConstructPtr(), ModifierExpressionPtr()); } } s_constants->setDynamic(ar, "SID", true); return true; }