File *PhpStreamWrapper::openFD(const char *sFD) { if (!RuntimeOption::ClientExecutionMode()) { raise_warning("Direct access to file descriptors " "is only available from command-line"); return nullptr; } char *end = nullptr; long nFD = strtol(sFD, &end, 10); if ((sFD == end) || (*end != '\0')) { raise_warning("php://fd/ stream must be specified in the form " "php://fd/<orig fd>"); return nullptr; } long dtablesize = getdtablesize(); if ((nFD < 0) || (nFD >= dtablesize)) { raise_warning("The file descriptors must be non-negative numbers " "smaller than %ld", dtablesize); return nullptr; } return NEWOBJ(PlainFile)(dup(nFD), true); }
static Variant HHVM_FUNCTION(gmp_fact, const Variant& data) { mpz_t gmpReturn; if (data.isResource()) { mpz_t gmpData; if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_FACT, gmpData, data, 0, true)) { return false; } if (mpz_sgn(gmpData) < 0) { mpz_clear(gmpData); raise_warning(cs_GMP_INVALID_VALUE_MUST_BE_POSITIVE, cs_GMP_FUNC_NAME_GMP_FACT); return false; } mpz_init(gmpReturn); mpz_fac_ui(gmpReturn, mpz_get_ui(gmpData)); mpz_clear(gmpData); } else { if (data.toInt64() < 0) { raise_warning(cs_GMP_INVALID_VALUE_MUST_BE_POSITIVE, cs_GMP_FUNC_NAME_GMP_FACT); return false; } mpz_init(gmpReturn); mpz_fac_ui(gmpReturn, data.toInt64()); } Variant ret = NEWOBJ(GMPResource)(gmpReturn); mpz_clear(gmpReturn); return ret; }
bool TestExtIcu_uspoof::test_SpoofChecker_areconfusable() { p_SpoofChecker checker(NEWOBJ(c_SpoofChecker)()); VS(checker->t_areconfusable("hello, world", "goodbye, world"), false); VS(checker->t_areconfusable("hello, world", "hello, world"), true); VS(checker->t_areconfusable("hello, world", "he11o, wor1d"), true); VS(checker->t_areconfusable("hell\u00f8", "hello\u0337"), true); VS(checker->t_areconfusable("facebook", "f\u0430\u0441\u0435b\u043e\u043ek"), true); // TODO: ICU bug 8341: \u017f should be treated as a spoof of "f". Once // that bug is fixed, enable this test. // //VS(checker->t_areconfusable("facebook", "\u017facebook"), true); VS(checker->t_areconfusable("paypal", "payp\u0430l"), true); VS(checker->t_areconfusable( "NAPKIN PEZ", "\u039d\u0391\u03a1\u039a\u0399\u039d \u03a1\u0395\u0396"), true); VS(checker->t_areconfusable( "facebook", "ufiek-a\u048ba\u049d \u049da\u048b\u00f0a\u048b\u01e5a\u048b-\u049dota-" "\u00f0o\u00f0ol"), false); try { checker->t_areconfusable( "this is not UTF-8: \x87\xFB\xCA\x94\xDB", "so there."); } catch (Exception& e) { return Count(true); } return Count(false); }
virtual File* open(const String& filename, const String& mode, int options, const Variant& context) { std::string url(filename.c_str()); auto pound = url.find('#'); if (pound == std::string::npos) { return nullptr; } // 6 is the position after zip:// auto path = url.substr(6, pound - 6); auto file = url.substr(pound + 1); if (path.empty() || file.empty()) { return nullptr; } int err; auto z = zip_open(path.c_str(), 0, &err); if (z == nullptr) { return nullptr; } return NEWOBJ(ZipStream)(z, file); }
static Variant HHVM_FUNCTION(gmp_or, const Variant& dataA, const Variant& dataB) { mpz_t gmpDataA, gmpDataB, gmpReturn; if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_OR, gmpDataA, dataA)) { return false; } if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_OR, gmpDataB, dataB)) { mpz_clear(gmpDataA); return false; } mpz_init(gmpReturn); mpz_ior(gmpReturn, gmpDataA, gmpDataB); Variant ret = NEWOBJ(GMPResource)(gmpReturn); mpz_clear(gmpDataA); mpz_clear(gmpDataB); mpz_clear(gmpReturn); return ret; }
bool TestExtIcu_uspoof::test_SpoofChecker_areconfusable() { p_SpoofChecker checker(NEWOBJ(c_SpoofChecker)()); VS(checker->t_areconfusable("hello, world", "goodbye, world"), false); VS(checker->t_areconfusable("hello, world", "hello, world"), true); VS(checker->t_areconfusable("hello, world", "he11o, wor1d"), true); VS(checker->t_areconfusable("hell\u00f8", "hello\u0337"), true); VS(checker->t_areconfusable("facebook", "f\u0430\u0441\u0435b\u043e\u043ek"), true); VS(checker->t_areconfusable("facebook", "\U0001d41faceboo\u1d0b"), true); VS(checker->t_areconfusable("facebook", "\u017facebook"), true); VS(checker->t_areconfusable("paypal", "payp\u0430l"), true); VS(checker->t_areconfusable( "NAPKIN PEZ", "\u039d\u0391\u03a1\u039a\u0399\u039d \u03a1\u0395\u0396"), true); VS(checker->t_areconfusable( "facebook", "ufiek-a\u048ba\u049d \u049da\u048b\u00f0a\u048b\u01e5a\u048b-\u049dota-" "\u00f0o\u00f0ol"), false); try { checker->t_areconfusable( "this is not UTF-8: \x87\xFB\xCA\x94\xDB", "so there."); } catch (Exception& e) { return Count(true); } return Count(false); }
File* PhpStreamWrapper::open(const String& filename, const String& mode, int options, CVarRef context) { if (strncasecmp(filename.c_str(), "php://", 6)) { return nullptr; } const char *req = filename.c_str() + sizeof("php://") - 1; if (!strcasecmp(req, "stdin")) { return NEWOBJ(PlainFile)(dup(STDIN_FILENO), true); } if (!strcasecmp(req, "stdout")) { return NEWOBJ(PlainFile)(dup(STDOUT_FILENO), true); } if (!strcasecmp(req, "stderr")) { return NEWOBJ(PlainFile)(dup(STDERR_FILENO), true); } if (!strncasecmp(req, "fd/", sizeof("fd/") - 1)) { return openFD(req + sizeof("fd/") - 1); } if (!strncasecmp(req, "temp", sizeof("temp") - 1) || !strcasecmp(req, "memory")) { std::unique_ptr<TempFile> file(NEWOBJ(TempFile)()); if (!file->valid()) { raise_warning("Unable to create temporary file"); return nullptr; } return file.release(); } if (!strcasecmp(req, "input")) { auto raw_post = g_context->getRawPostData(); return NEWOBJ(MemFile)(raw_post.c_str(), raw_post.size()); } if (!strcasecmp(req, "output")) { return NEWOBJ(OutputFile)(filename); } return nullptr; }
ZipFile::ZipFile() : m_gzFile(nullptr) { m_innerFile = NEWOBJ(PlainFile)(); m_innerFile->unregister(); // so Sweepable won't touch my child m_isLocal = true; }
ZipFile::ZipFile() : m_gzFile(nullptr) { m_innerFile = NEWOBJ(PlainFile)(); m_isLocal = true; }
SmartResource<TimeZone> TimeZone::Current() { return NEWOBJ(TimeZone)(CurrentName()); }
ObjectData *coo_Directory() { return NEWOBJ(c_Directory)(); }
Object c_DateInterval::ti_createfromdatestring(const String& time) { SmartResource<DateInterval> di(NEWOBJ(DateInterval)(time, true)); return c_DateInterval::wrap(di); }
Variant c_Collator::ti_create(const char* cls, CStrRef locale) { STATIC_METHOD_INJECTION_BUILTIN(Collator, Collator::create); return (NEWOBJ(c_Collator)())->create(locale); }
ObjectData *coo_RuntimeException() { return NEWOBJ(c_RuntimeException)(); }
ObjectData *coo_OutOfRangeException() { return NEWOBJ(c_OutOfRangeException)(); }
SmartObject<DateInterval> DateInterval::cloneDateInterval() const { if (!m_di) return NEWOBJ(DateInterval)(); return NEWOBJ(DateInterval)(timelib_rel_time_clone(m_di.get())); }
SmartObject<TimeZone> TimeZone::Current() { return NEWOBJ(TimeZone)(CurrentName()); }
ObjectData *coo_BadFunctionCallException() { return NEWOBJ(c_BadFunctionCallException)(); }
Variant f_collator_create(CStrRef locale) { return (NEWOBJ(c_Collator)())->create(locale); }
ObjectData *coo_DomainException() { return NEWOBJ(c_DomainException)(); }
Object f_timezone_open(const String& timezone) { c_DateTimeZone *ctz = NEWOBJ(c_DateTimeZone)(); Object ret(ctz); ctz->t___construct(timezone); return ret; }
ObjectData *coo_ErrorException() { return NEWOBJ(c_ErrorException)(); }
static void HHVM_METHOD(IntlDateFormatter, __clone) { auto data = NEWOBJ(IntlDateFormatter)(IntlDateFormatter::Get(this_)); this_->o_set(s_resdata, Resource(data), s_IntlDateFormatter.get()); }
ObjectData *coo_BadMethodCallException() { return NEWOBJ(c_BadMethodCallException)(); }
SmartResource<TimeZone> TimeZone::cloneTimeZone() const { if (!m_tzi) return NEWOBJ(TimeZone)(); return NEWOBJ(TimeZone)(timelib_tzinfo_clone(m_tzi.get())); }
ObjectData *coo_PDOException() { return NEWOBJ(c_PDOException)(); }
bool TestExtSqlite3::test_sqlite3() { p_SQLite3 db(NEWOBJ(c_SQLite3)()); db->t_open(":memory:test"); db->t_exec("DROP TABLE foo"); db->t_exec("CREATE TABLE foo (bar STRING)"); db->t_exec("INSERT INTO foo VALUES ('ABC')"); db->t_exec("INSERT INTO foo VALUES ('DEF')"); VS(db->t_lastinsertrowid(), 2); VS(db->t_changes(), 1); VS(db->t_lasterrorcode(), 0); VS(db->t_lasterrormsg(), "not an error"); VS(db->t_escapestring("'\""), "''\""); VS(db->t_querysingle("SELECT * FROM foo"), "ABC"); VS(db->t_querysingle("SELECT * FROM foo", true), CREATE_MAP1("bar", "ABC")); // testing query() and SQLite3Result { Object objResult = db->t_query("SELECT * FROM foo").toObject(); c_SQLite3Result *res = objResult.getTyped<c_SQLite3Result>(); VS(res->t_fetcharray(), CREATE_MAP2(0, "ABC", "bar", "ABC")); VS(res->t_numcolumns(), 1); VS(res->t_columnname(0), "bar"); VS(res->t_columntype(0), k_SQLITE3_TEXT); VS(res->t_fetcharray(k_SQLITE3_NUM), CREATE_VECTOR1("DEF")); } // testing prepare() and sqlite3stmt { Object objStmt = db->t_prepare("SELECT * FROM foo WHERE bar = :id"); c_SQLite3Stmt *stmt = objStmt.getTyped<c_SQLite3Stmt>(); VS(stmt->t_paramcount(), 1); Variant id = "DEF"; VERIFY(stmt->t_bindvalue(":id", id, SQLITE3_TEXT)); id = "ABC"; { Object objResult = stmt->t_execute(); c_SQLite3Result *res = objResult.getTyped<c_SQLite3Result>(); VS(res->t_fetcharray(k_SQLITE3_NUM), CREATE_VECTOR1("DEF")); } VERIFY(stmt->t_clear()); VERIFY(stmt->t_reset()); id = "DEF"; VERIFY(stmt->t_bindparam(":id", ref(id), SQLITE3_TEXT)); id = "ABC"; { Object objResult = stmt->t_execute(); c_SQLite3Result *res = objResult.getTyped<c_SQLite3Result>(); VS(res->t_fetcharray(k_SQLITE3_NUM), CREATE_VECTOR1("ABC")); } } // testing UDF { VERIFY(db->t_createfunction("tolower", "lower", 1)); Object objResult = db->t_query("SELECT tolower(bar) FROM foo").toObject(); c_SQLite3Result *res = objResult.getTyped<c_SQLite3Result>(); VS(res->t_fetcharray(k_SQLITE3_NUM), CREATE_VECTOR1("abc")); } { VERIFY(db->t_createaggregate("sumlen", "sumlen_step", "sumlen_fini", 1)); Object objResult = db->t_query("SELECT sumlen(bar) FROM foo").toObject(); c_SQLite3Result *res = objResult.getTyped<c_SQLite3Result>(); VS(res->t_fetcharray(k_SQLITE3_NUM), CREATE_VECTOR1(6)); } db->t_close(); VS(db->t_version(), CREATE_MAP2("versionString", "3.6.23.1", "versionNumber", 3006023)); f_unlink(":memory:test"); return Count(true); }
void Variant::unserialize(VariableUnserializer *uns, Uns::Mode mode /* = Uns::Mode::Value */) { // NOTE: If you make changes to how serialization and unserialization work, // make sure to update the reserialize() method in "runtime/ext/ext_apc.cpp" // and to update test_apc_reserialize() in "test/ext/test_ext_apc.cpp". char type, sep; type = uns->readChar(); sep = uns->readChar(); if (type != 'R') { uns->add(this, mode); } if (type == 'N') { if (sep != ';') throw Exception("Expected ';' but got '%c'", sep); setNull(); // NULL *IS* the value, without we get undefined warnings return; } if (sep != ':') { throw Exception("Expected ':' but got '%c'", sep); } switch (type) { case 'r': { int64_t id = uns->readInt(); Variant *v = uns->getByVal(id); if (v == nullptr) { throw Exception("Id %" PRId64 " out of range", id); } operator=(*v); } break; case 'R': { int64_t id = uns->readInt(); Variant *v = uns->getByRef(id); if (v == nullptr) { throw Exception("Id %" PRId64 " out of range", id); } assignRef(*v); } break; case 'b': { int64_t v = uns->readInt(); operator=((bool)v); } break; case 'i': { int64_t v = uns->readInt(); operator=(v); } break; case 'd': { double v; char ch = uns->peek(); bool negative = false; char buf[4]; if (ch == '-') { negative = true; ch = uns->readChar(); ch = uns->peek(); } if (ch == 'I') { uns->read(buf, 3); buf[3] = '\0'; if (strcmp(buf, "INF")) { throw Exception("Expected 'INF' but got '%s'", buf); } v = atof("inf"); } else if (ch == 'N') { uns->read(buf, 3); buf[3] = '\0'; if (strcmp(buf, "NAN")) { throw Exception("Expected 'NAN' but got '%s'", buf); } v = atof("nan"); } else { v = uns->readDouble(); } operator=(negative ? -v : v); } break; case 's': { String v; v.unserialize(uns); operator=(v); } break; case 'S': if (uns->getType() == VariableUnserializer::Type::APCSerialize) { union { char buf[8]; StringData *sd; } u; uns->read(u.buf, 8); operator=(u.sd); } else { throw Exception("Unknown type '%c'", type); } break; case 'a': { Array v = Array::Create(); v.unserialize(uns); operator=(v); return; // array has '}' terminating } break; case 'L': { int64_t id = uns->readInt(); sep = uns->readChar(); if (sep != ':') { throw Exception("Expected ':' but got '%c'", sep); } String rsrcName; rsrcName.unserialize(uns); sep = uns->readChar(); if (sep != '{') { throw Exception("Expected '{' but got '%c'", sep); } sep = uns->readChar(); if (sep != '}') { throw Exception("Expected '}' but got '%c'", sep); } DummyResource* rsrc = NEWOBJ(DummyResource); rsrc->o_setResourceId(id); rsrc->m_class_name = rsrcName; operator=(rsrc); return; // resource has '}' terminating } break; case 'O': case 'V': case 'K': { String clsName; clsName.unserialize(uns); sep = uns->readChar(); if (sep != ':') { throw Exception("Expected ':' but got '%c'", sep); } int64_t size = uns->readInt(); char sep = uns->readChar(); if (sep != ':') { throw Exception("Expected ':' but got '%c'", sep); } sep = uns->readChar(); if (sep != '{') { throw Exception("Expected '{' but got '%c'", sep); } const bool allowObjectFormatForCollections = true; Class* cls; // If we are potentially dealing with a collection, we need to try to // load the collection class under an alternate name so that we can // deserialize data that was serialized before the migration of // collections to the HH namespace. if (type != 'O') { // Collections are CPP builtins; don't attempt to autoload cls = Unit::getClass(clsName.get(), /* autoload */ false); if (!cls) { cls = tryAlternateCollectionClass(clsName.get()); } } else if (allowObjectFormatForCollections) { // In order to support the legacy {O|V}:{Set|Vector|Map} // serialization, we defer autoloading until we know that there's // no alternate (builtin) collection class. cls = Unit::getClass(clsName.get(), /* autoload */ false); if (!cls) { cls = tryAlternateCollectionClass(clsName.get()); } if (!cls) { cls = Unit::loadClass(clsName.get()); // with autoloading } } else { cls = Unit::loadClass(clsName.get()); // with autoloading } Object obj; if (RuntimeOption::UnserializationWhitelistCheck && (type == 'O') && !uns->isWhitelistedClass(clsName)) { const char* err_msg = "The object being unserialized with class name '%s' " "is not in the given whitelist. " "See http://fburl.com/SafeSerializable for more detail"; if (RuntimeOption::UnserializationWhitelistCheckWarningOnly) { raise_warning(err_msg, clsName.c_str()); } else { raise_error(err_msg, clsName.c_str()); } } if (cls) { // Only unserialize CPP extension types which can actually // support it. Otherwise, we risk creating a CPP object // without having it initialized completely. if (cls->instanceCtor() && !cls->isCppSerializable()) { obj = ObjectData::newInstance( SystemLib::s___PHP_Unserializable_ClassClass); obj->o_set(s_PHP_Unserializable_Class_Name, clsName); } else { obj = ObjectData::newInstance(cls); if (UNLIKELY(cls == c_Pair::classof() && size != 2)) { throw Exception("Pair objects must have exactly 2 elements"); } } } else { obj = ObjectData::newInstance( SystemLib::s___PHP_Incomplete_ClassClass); obj->o_set(s_PHP_Incomplete_Class_Name, clsName); } operator=(obj); if (size > 0) { if (type == 'O') { // Collections are not allowed if (obj->isCollection()) { if (size > 0) { throw Exception("%s does not support the 'O' serialization " "format", clsName.data()); } // Be lax and tolerate the 'O' serialization format for collection // classes if there are 0 properties. raise_warning("%s does not support the 'O' serialization " "format", clsName.data()); } /* Count backwards so that i is the number of properties remaining (to be used as an estimate for the total number of dynamic properties when we see the first dynamic prop). see getVariantPtr */ for (int64_t i = size; i--; ) { String key = uns->unserializeKey().toString(); int ksize = key.size(); const char *kdata = key.data(); int subLen = 0; if (kdata[0] == '\0') { if (UNLIKELY(!ksize)) { throw EmptyObjectPropertyException(); } // private or protected subLen = strlen(kdata + 1) + 2; if (UNLIKELY(subLen >= ksize)) { if (subLen == ksize) { throw EmptyObjectPropertyException(); } else { throw Exception("Mangled private object property"); } } String k(kdata + subLen, ksize - subLen, CopyString); Class* ctx = (Class*)-1; if (kdata[1] != '*') { ctx = Unit::lookupClass( String(kdata + 1, subLen - 2, CopyString).get()); } unserializeProp(uns, obj.get(), k, ctx, key, i + 1); } else { unserializeProp(uns, obj.get(), key, nullptr, key, i + 1); } } } else { assert(type == 'V' || type == 'K'); if (!obj->isCollection()) { throw Exception("%s is not a collection class", clsName.data()); } collectionUnserialize(obj.get(), uns, size, type); } } sep = uns->readChar(); if (sep != '}') { throw Exception("Expected '}' but got '%c'", sep); } obj->invokeWakeup(); return; // object has '}' terminating } break; case 'C': { String clsName; clsName.unserialize(uns); sep = uns->readChar(); if (sep != ':') { throw Exception("Expected ':' but got '%c'", sep); } String serialized; serialized.unserialize(uns, '{', '}'); Object obj; try { obj = create_object_only(clsName); } catch (ClassNotFoundException &e) { if (!uns->allowUnknownSerializableClass()) { throw; } obj = create_object_only(s_PHP_Incomplete_Class); obj->o_set(s_PHP_Incomplete_Class_Name, clsName); obj->o_set("serialized", serialized); } if (!obj->instanceof(SystemLib::s_SerializableClass)) { raise_warning("Class %s has no unserializer", obj->o_getClassName().data()); } else { obj->o_invoke_few_args(s_unserialize, 1, serialized); obj.get()->clearNoDestruct(); } operator=(obj); return; // object has '}' terminating } break; default: throw Exception("Unknown type '%c'", type); } sep = uns->readChar(); if (sep != ';') { throw Exception("Expected ';' but got '%c'", sep); } }
ObjectData* EvalObjectData::clone() { return NEWOBJ(EvalObjectData)(this); }
File* UserStreamWrapper::open(CStrRef filename, CStrRef mode, int options, CVarRef context) { std::unique_ptr<File> file(NEWOBJ(UserFile)(m_cls, options, context)); file->open(filename, mode); return file.release(); }