req::ptr<PDOResource> PDODriver::createResource(const String& datasource, const String& username, const String& password, const Array& options) { auto const rsrc = createResourceImpl(); auto const& conn = rsrc->conn(); conn->data_source = datasource.toCppString(); conn->username = username.toCppString(); conn->password = password.toCppString(); if (options.exists(PDO_ATTR_AUTOCOMMIT)) { conn->auto_commit = options[PDO_ATTR_AUTOCOMMIT].toInt64(); } else { conn->auto_commit = 1; } if (!conn->create(options)) { Array err; bool hasError = conn->fetchErr(nullptr, err); if (hasError && !err.empty()) { throw_pdo_exception(uninit_null(), "[%" PRId64 "]: %s", err[0].toInt64(), err[1].toString().data()); } return nullptr; } return rsrc; }
Variant IniSetting::FromString(const String& ini, const String& filename, bool process_sections /* = false */, int scanner_mode /* = NormalScanner */) { Lock lock(s_mutex); // ini parser is not thread-safe // We are parsing something new, so reset this flag s_config_is_a_constant = false; auto ini_cpp = ini.toCppString(); auto filename_cpp = filename.toCppString(); if (process_sections) { CallbackData data; SectionParserCallback cb; data.arr = Array::Create(); if (zend_parse_ini_string(ini_cpp, filename_cpp, scanner_mode, cb, &data)) { return data.arr; } } else { ParserCallback cb; Variant ret = Array::Create(); if (zend_parse_ini_string(ini_cpp, filename_cpp, scanner_mode, cb, &ret)) { return ret; } } return false; }
bool IniSetting::SetSystem(const String& name, const Variant& value) { // Shouldn't be calling this function after the runtime options are loaded. assert(!s_system_settings_are_set); // Since we're going to keep these settings for the lifetime of the program, // we need to make them static. Variant eval_scalar_variant = value; eval_scalar_variant.setEvalScalar(); s_system_settings[name.toCppString()] = eval_scalar_variant; return ini_set(name.toCppString(), value, PHP_INI_SET_EVERY); }
bool IniSetting::SetUser(const String& name, const Variant& value) { auto it = s_saved_defaults->find(name.toCppString()); if (it == s_saved_defaults->end()) { Variant def; auto success = Get(name, def); // def gets populated here if (success) { (*s_saved_defaults)[name.toCppString()] = def; } } return ini_set(name.toCppString(), value, PHP_INI_SET_USER); }
Variant IniSetting::Unbox(const Variant& boxed, std::set<ArrayData*>& seen, bool& use_defaults, const String& array_key) { assert(boxed.isArray()); Variant unboxed(Array::Create()); auto ad = boxed.getArrayData(); if (seen.insert(ad).second) { for (auto it = boxed.toArray().begin(); it; it.next()) { auto key = it.first(); // asserting here to ensure that key is a scalar type that can be // converted to a string. assert(key.isScalar()); auto& elem = it.secondRef(); unboxed.asArrRef().set( key, elem.isArray() ? Unbox(elem, seen, use_defaults, key.toString()) : elem ); } seen.erase(ad); } else { // The insert into seen wasn't successful. We have recursion. // break the recursive cycle, so the elements can be freed by the MM. // The const_cast is ok because we fully own the array, with no sharing. // Use the current array key to give a little help in the log message const_cast<Variant&>(boxed).unset(); use_defaults = true; Logger::Warning("INI Recursion Detected at offset named %s. " "Using default runtime settings.", array_key.toCppString().c_str()); } return unboxed; }
bool PDOSqliteResource::createFunction(const String& name, const Variant& callback, int argcount) { if (!is_callable(callback)) { raise_warning("function '%s' is not callable", callback.toString().data()); return false; } auto udf = req::make_unique<UDF>(); udf->func = callback; udf->argc = argcount; udf->name = name.toCppString(); auto stat = sqlite3_create_function( conn()->m_db, udf->name.c_str(), argcount, SQLITE_UTF8, static_cast<SQLite3::UserDefinedFunc*>(udf.get()), php_sqlite3_callback_func, nullptr, nullptr ); if (stat != SQLITE_OK) { return false; } m_udfs.emplace_back(std::move(udf)); return true; }
void init(const Array& options, const String& pid) { mc::McrouterOptions opts; parseOptions(opts, options); mcr::McrouterInstance* router; if (pid.empty()) { m_transientRouter = mcr::McrouterInstance::create(opts.clone()); router = m_transientRouter.get(); } else { router = mcr::McrouterInstance::init(pid.toCppString(), opts); } if (!router) { mcr_throwException("Unable to initialize MCRouter instance"); } m_client = router->createClient( {onReply,onCancel,nullptr}, this, 0); if (!m_client) { mcr_throwException("Unable to initilize MCRouterClient instance"); } }
bool PDOSqliteConnection::createFunction(const String& name, const Variant& callback, int argcount) { if (!is_callable(callback)) { raise_warning("function '%s' is not callable", callback.toString().data()); return false; } auto udf = std::make_shared<UDF>(); udf->func = callback; udf->argc = argcount; udf->name = name.toCppString(); auto stat = sqlite3_create_function(m_db, udf->name.c_str(), argcount, SQLITE_UTF8, udf.get(), php_sqlite3_callback_func, nullptr, nullptr); if (stat != SQLITE_OK) { return false; } m_udfs.push_back(udf); return true; }
bool IniSetting::GetSystem(const String& name, Variant& value) { auto it = s_system_settings.find(name.toCppString()); if (it == s_system_settings.end()) { return false; } value = it->second; return true; }
bool IniSetting::Get(const String& name, Variant& value) { auto cb = get_callback(name.toCppString()); if (!cb) { return false; } value = cb->getCallback(); return true; }
static Variant HHVM_METHOD(Yaf_Controller_Abstract, render, const String& tpl, const Variant& parameters) { //raise_warning("start render in controller!"); auto _viewTmp = this_->o_realProp("_view", ObjectData::RealPropUnchecked, "Yaf_Controller_Abstract"); if (_viewTmp->isNull()) { return false; } auto _view = _viewTmp->toObject(); std::string self_name = this_->o_realProp("_name", ObjectData::RealPropUnchecked, "Yaf_Controller_Abstract")->toString().toCppString(); std::string view_ext = g_yaf_local_data.get()->view_ext; transform(self_name.begin(), self_name.end(), self_name.begin(), tolower); for (unsigned int i = 0; i < self_name.length(); i++) { if (self_name[i] == '_') { self_name[i] = DEFAULT_SLASH_CHAR; } } std::string action_name = tpl.toCppString(); for (unsigned int i = 0; i < action_name.length(); i++) { if (action_name[i] == '_') { action_name[i] = DEFAULT_SLASH_CHAR; } } std::string path = self_name + DEFAULT_SLASH_STR + action_name + "." + view_ext; Array func = Array::Create(); func.append(_view); func.append(String("render")); Array params = Array::Create(); params.append(String(path.c_str())); if (!parameters.isNull()) { params.append(parameters); } Variant ret = vm_call_user_func(func, params); if (ret.isNull()) { return false; } if (ret.isBoolean() && !ret.toBoolean()) { return false; } return ret; }
bool IniSetting::SetUser(const String& nameString, const String& value) { auto name = nameString.toCppString(); auto it = s_savedDefaults->find(name); if (it == s_savedDefaults->end()) { Get(name, (*s_savedDefaults)[name]); } return ini_set(nameString, value, static_cast<Mode>( PHP_INI_USER | PHP_INI_ALL )); }
static bool ini_set(const String& name, const String& value, IniSetting::Mode mode) { CallbackMap::iterator iter = s_callbacks->find(name.data()); if (iter != s_callbacks->end()) { if ((iter->second.mode & mode) && iter->second.updateCallback) { return iter->second.updateCallback(value.toCppString(), iter->second.p); } } return false; }
bool f_server_get_custom_bool_setting(const String& settingName, bool defaultValue) { bool retVal = false; if (!RuntimeOption::GetServerCustomBoolSetting(settingName.toCppString(), retVal)) { // The value isn't present in the CustomSettings section of config.hdf, // so return the default value instead. retVal = defaultValue; } return retVal; }
Variant IniSetting::FromString(const String& ini, const String& filename, bool process_sections, int scanner_mode) { Lock lock(s_mutex); // ini parser is not thread-safe auto ini_cpp = ini.toCppString(); auto filename_cpp = filename.toCppString(); if (process_sections) { SectionParserCallback::CallbackData data; SectionParserCallback cb; data.arr = Array::Create(); if (zend_parse_ini_string(ini_cpp, filename_cpp, scanner_mode, cb, &data)) { return data.arr; } } else { ParserCallback cb; Variant ret = Array::Create(); if (zend_parse_ini_string(ini_cpp, filename_cpp, scanner_mode, cb, &ret)) { return ret; } } return false; }
void IniSetting::ParserCallback::onVar(std::string &result, const std::string& name) { std::string curval; if (IniSetting::Get(name, curval)) { result = curval; return; } String value = g_context->getenv(name); if (!value.isNull()) { result = value.toCppString(); return; } result.clear(); }
static void mysql_set_conn_attr(MYSQL* mysql, const String& key, const String& value) { if (key.empty()) { raise_warning("MySQL: Invalid connection attribute - empty key"); } else if (value.empty()) { raise_warning( std::string("MySQL: Invalid connection attribute - empty value for ") + key.toCppString()); } else { mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, key.c_str(), value.c_str()); } }
Array IniSetting::GetAll(const String& ext_name, bool details) { Array r = Array::Create(); const Extension* ext = nullptr; if (!ext_name.empty()) { if (ext_name == s_core) { ext = IniSetting::CORE; } else { ext = ExtensionRegistry::get(ext_name); if (!ext) { raise_warning("Unable to find extension '%s'", ext_name.toCppString().c_str()); return r; } } } for (auto& iter: boost::join(s_system_ini_callbacks, *s_user_callbacks)) { if (ext && ext != iter.second.extension) { continue; } auto value = iter.second.getCallback(); // Cast all non-arrays to strings since that is what everything used ot be if (!value.isArray()) { value = value.toString(); } if (details) { Array item = Array::Create(); item.add(s_global_value, value); item.add(s_local_value, value); if (iter.second.mode == PHP_INI_ALL) { item.add( s_access, Variant(PHP_INI_USER | PHP_INI_SYSTEM | PHP_INI_PERDIR) ); } else if (iter.second.mode == PHP_INI_ONLY) { item.add(s_access, Variant(PHP_INI_SYSTEM)); } else { item.add(s_access, Variant(iter.second.mode)); } r.add(String(iter.first), item); } else { r.add(String(iter.first), value); } } return r; }
bool XboxServer::PostMessage(const String& message, const String& host /* = "localhost" */) { if (isLocalHost(host)) { Lock l(s_dispatchMutex); if (!s_dispatcher) { return false; } XboxTransport *job = new XboxTransport(message.toCppString()); job->incRefCount(); // paired with worker's decRefCount() assert(s_dispatcher); s_dispatcher->enqueue(job); return true; } else { // remote string url = "http://"; url += host.data(); url += "/xbox_post_message"; std::vector<std::string> headers; std::string hostStr(host.data()); LibEventHttpClientPtr http = LibEventHttpClient::Get(hostStr, RuntimeOption::XboxServerPort); if (http->send(url, headers, 0, false, message.data(), message.size())) { int code = http->getCode(); if (code > 0) { int len = 0; char *response = http->recv(len); String sresponse(response, len, AttachString); if (code == 200 && same( unserialize_from_string( sresponse, VariableUnserializer::Type::Internal ), true ) ) { return true; } } } } return false; }
Array IniSetting::GetAll(const String& ext_name, bool details) { Array r = Array::Create(); const Extension* ext = nullptr; if (!ext_name.empty()) { if (ext_name == s_core) { ext = IniSetting::CORE; } else { ext = Extension::GetExtension(ext_name); if (!ext) { raise_warning("Unable to find extension '%s'", ext_name.toCppString().c_str()); return r; } } } for (auto& iter: (*s_callbacks)) { if (ext && ext != iter.second.extension) { continue; } if (details) { Array item = Array::Create(); auto value = iter.second.getCallback(iter.second.p); item.add(s_global_value, value); item.add(s_local_value, value); if (iter.second.mode == PHP_INI_ALL) { item.add( s_access, Variant(PHP_INI_USER | PHP_INI_SYSTEM | PHP_INI_PERDIR) ); } else if (iter.second.mode == PHP_INI_ONLY) { item.add(s_access, Variant(PHP_INI_SYSTEM)); } else { item.add(s_access, Variant(iter.second.mode)); } r.add(String(iter.first), item); } else { r.add(String(iter.first), iter.second.getCallback(iter.second.p)); } } return r; }
bool PlainFile::open(const String& filename, const String& mode) { int fd; FILE *f; assert(m_stream == nullptr); assert(getFd() == -1); // For these definded in php fopen but C stream have different modes switch (mode[0]) { case 'x': if (mode.find('+') == -1) { fd = ::open(filename.data(), O_WRONLY|O_CREAT|O_EXCL, 0666); if (fd < 0) return false; f = fdopen(fd, "w"); } else { fd = ::open(filename.data(), O_RDWR|O_CREAT|O_EXCL, 0666); if (fd < 0) return false; f = fdopen(fd, "w+"); } break; case 'c': if (mode.find('+') == -1) { fd = ::open(filename.data(), O_WRONLY|O_CREAT, 0666); if (fd < 0) return false; f = fdopen(fd, "w"); } else { fd = ::open(filename.data(), O_RDWR|O_CREAT, 0666); if (fd < 0) return false; f = fdopen(fd, "w+"); } break; default: f = fopen(filename.data(), mode.data()); } if (!f) { return false; } m_stream = f; setFd(fileno(f)); m_buffer = (char *)malloc(BUFSIZ); setName(filename.toCppString()); if (m_buffer) setbuffer(f, m_buffer, BUFSIZ); return true; }
void CmdVariable::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_frame); { String sdata; thrift.read(sdata); auto error = DebuggerWireHelpers::WireUnserialize(sdata, m_variables); if (error != DebuggerWireHelpers::NoError) { m_variables.reset(); if (error != DebuggerWireHelpers::HitLimit || m_version == 0) { // Unexpected error. Log it. m_wireError = sdata.toCppString(); } } } thrift.read(m_global); if (m_version == 2) { thrift.read(m_formatMaxLen); thrift.read(m_varName); thrift.read(m_filter); } }
void IniSetting::ParserCallback::makeSettingSub(const String& key, const std::string& offset, const std::string& value, Variant& cur_settings) { assert(offset.size() == 1 || (offset.size() >=2 && offset[offset.size()-2] == 0)); auto type = offset.substr(offset.size() - 1); assert(type == ":" || type == "@"); std::vector<std::string> copy_name_parts = split_brackets(value); assert(!copy_name_parts.empty()); Variant* base = &cur_settings; bool skip = false; for (auto& part : copy_name_parts) { if (!base->isArray()) { *base = Array::Create(); } auto lval = &base->toArrRef().lvalAt(String(part)); if (lval->isNull()) { skip = true; } else { base = lval; } } // if skip is true we have something like: // hhvm.env_variables["MYINT"][:] = 3 // hhvm.stats.slot_duration[:] = "hhvm.stats.slot_duration" if (skip) { Logger::Warning("A false recursive setting at key %s with offset %s and " "value %s. Value is literal or pointing to setting that " "does not exist. Skipping!", key.toCppString().c_str(), offset.c_str(), value.c_str()); } else if (offset == ":") { cur_settings.toArrRef().setRef(key, *base); } else if (offset == "@") { cur_settings.toArrRef().set(key, *base); } else { traverseToSet(key, offset, *base, cur_settings, type); } }
bool MemFile::open(const String& filename, const String& mode) { assertx(m_len == -1); // mem files are read-only const char* mode_str = mode.c_str(); if (strchr(mode_str, '+') || strchr(mode_str, 'a') || strchr(mode_str, 'w')) { return false; } int len = INT_MIN; bool compressed = false; char *data = StaticContentCache::TheFileCache->read(filename.c_str(), len, compressed); // -1: PHP file; -2: directory if (len != INT_MIN && len != -1 && len != -2) { assertx(len >= 0); if (compressed) { assertx(RuntimeOption::EnableOnDemandUncompress); data = gzdecode(data, len); if (data == nullptr) { raise_fatal_error("cannot unzip compressed data"); } m_data = data; m_malloced = true; m_len = len; return true; } setName(filename.toCppString()); m_data = data; m_len = len; return true; } if (len != INT_MIN) { Logger::Error("Cannot open a PHP file or a directory as MemFile: %s", filename.c_str()); } return false; }
bool IniSetting::Get(const String& name, String &value) { std::string b; auto ret = Get(name.toCppString(), b); value = b; return ret; }
bool IniSetting::Get(const String& name, Variant& value) { folly::dynamic b = nullptr; auto ret = Get(name.toCppString(), b); value = dynamic_to_variant(b); return ret; }
static void HHVM_METHOD(EncodingDetector, setDeclaredEncoding, const String& declaredEncoding) { FETCH_DET(data, this_); data->setDeclaredEncoding(declaredEncoding.toCppString()); }
static void HHVM_METHOD(EncodingDetector, setText, const String& text) { FETCH_DET(data, this_); data->setText(text.toCppString()); }
bool IniSetting::SetUser(const String& name, const Variant& value) { return SetUser(name.toCppString(), variant_to_dynamic(value), FollyDynamic()); }
bool UrlFile::open(const String& input_url, const String& mode) { String url = input_url; const char* modestr = mode.c_str(); if (strchr(modestr, '+') || strchr(modestr, 'a') || strchr(modestr, 'w')) { std::string msg = "cannot open a url stream for write/append operation: "; msg += url.c_str(); m_error = msg; return false; } HttpClient http(m_timeout, m_maxRedirect); auto ctx = this->getStreamContext(); if (ctx) { http.setStreamContextOptions(ctx->getOptions()); } m_response.clear(); if (!m_proxyHost.empty()) { http.proxy(m_proxyHost, m_proxyPort, m_proxyUsername, m_proxyPassword); } HeaderMap *pHeaders = nullptr; HeaderMap requestHeaders; if (!m_headers.empty()) { pHeaders = &requestHeaders; for (ArrayIter iter(m_headers); iter; ++iter) { requestHeaders[std::string(iter.first().toString().data())]. push_back(iter.second().toString().data()); } } Variant user = f_parse_url(url, k_PHP_URL_USER); if (user.isString()) { Variant pass = f_parse_url(url, k_PHP_URL_PASS); http.auth(user.toString().c_str(), pass.toString().c_str()); url = HHVM_FN(preg_replace)( s_remove_user_pass_pattern, s_remove_user_pass_replace, url, 1 ).toString(); } int code; std::vector<String> responseHeaders; if (m_get) { code = http.get(url.c_str(), m_response, pHeaders, &responseHeaders); } else { code = http.request(m_method, url.c_str(), m_postData.data(), m_postData.size(), m_response, pHeaders, &responseHeaders); } m_responseHeaders.reset(); for (unsigned int i = 0; i < responseHeaders.size(); i++) { m_responseHeaders.append(responseHeaders[i]); } VMRegAnchor vra; ActRec* fp = vmfp(); while (fp->skipFrame()) { fp = g_context->getPrevVMState(fp); } auto id = fp->func()->lookupVarId(s_http_response_header.get()); if (id != kInvalidId) { auto tvTo = frame_local(fp, id); Variant varFrom(m_responseHeaders); const auto tvFrom(varFrom.asTypedValue()); if (tvTo->m_type == KindOfRef) { tvTo = tvTo->m_data.pref->tv(); } tvDup(*tvFrom, *tvTo); } else if ((fp->func()->attrs() & AttrMayUseVV) && fp->hasVarEnv()) { fp->getVarEnv()->set(s_http_response_header.get(), Variant(m_responseHeaders).asTypedValue()); } /* * If code == 0, Curl failed to connect; per PHP5, ignore_errors just means * to not worry if we get an http resonse code that isn't between 200 and 400, * but we shouldn't ignore other errors. * all status codes in the 2xx range are defined by the specification as * successful; * all status codes in the 3xx range are for redirection, and so also should * never fail. */ if ((code >= 200 && code < 400) || (m_ignoreErrors && code != 0)) { setName(url.toCppString()); m_data = const_cast<char*>(m_response.data()); m_len = m_response.size(); return true; } else { m_error = http.getLastError().c_str(); return false; } }