bool ini_on_update(const Variant& value, uint32_t& p) { INI_ASSERT_STR(value); auto n = convert_bytes_to_long(str); auto mask = ~0x7FFFFFFFUL; if (((uint64_t)n & mask)) { return false; } p = n; return true; }
bool ini_on_update_non_negative(const std::string& value, void *p) { int64_t v = convert_bytes_to_long(value); if (v < 0) { return false; } if (p) { *((int64_t*)p) = v; } return true; }
bool ini_on_update(const folly::dynamic& value, uint16_t& p) { INI_ASSERT_STR(value); auto n = convert_bytes_to_long(str); auto mask = ~0xFFFFUL; if (((uint64_t)n & mask)) { return false; } p = n; return true; }
bool ini_on_update(const Variant& value, int32_t& p) { INI_ASSERT_STR(value); auto n = convert_bytes_to_long(str); auto maxValue = 0x7FFFFFFFL; if (n > maxValue || n < (- maxValue - 1)) { return false; } p = n; return true; }
bool ini_on_update(const folly::dynamic& value, char& p) { INI_ASSERT_STR(value); auto n = convert_bytes_to_long(str); auto maxValue = 0x7FL; if (n > maxValue || n < (- maxValue - 1)) { return false; } p = n; return true; }
bool ini_on_update_int(const std::string& value, void *p) { if (p) { auto n = convert_bytes_to_long(value); auto maxValue = 0x7FFFFFFFL; if (n > maxValue || n < (- maxValue - 1)) { return false; } *((int32_t*)p) = n; } return true; }
bool ini_on_update_uint(const std::string& value, void *p) { if (p) { auto n = convert_bytes_to_long(value); auto mask = ~0x7FFFFFFFUL; if (((uint64_t)n & mask)) { return false; } *((uint32_t*)p) = n; } return true; }
bool ini_on_update_long(const std::string& value, void *p) { if (p) { *((int64_t*)p) = convert_bytes_to_long(value); } return true; }
bool ini_on_update(const Variant& value, uint64_t& p) { INI_ASSERT_STR(value); p = convert_bytes_to_long(str); return true; }
bool ini_on_update(const folly::dynamic& value, uint64_t& p) { INI_ASSERT_STR(value); p = convert_bytes_to_long(str); return true; }
void RequestInjectionData::threadInit() { // phpinfo { auto setAndGetWall = IniSetting::SetAndGet<int64_t>( [this](const int64_t &limit) { setTimeout(limit); return true; }, [this] { return getTimeout(); } ); auto setAndGetCPU = IniSetting::SetAndGet<int64_t>( [this](const int64_t &limit) { setCPUTimeout(limit); return true; }, [this] { return getCPUTimeout(); } ); auto setAndGet = RuntimeOption::TimeoutsUseWallTime ? setAndGetWall : setAndGetCPU; IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "max_execution_time", setAndGet); IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "maximum_execution_time", setAndGet); IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "hhvm.max_wall_time", setAndGetWall); IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "hhvm.max_cpu_time", setAndGetCPU); } // Resource Limits IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "memory_limit", IniSetting::SetAndGet<std::string>( [this](const std::string& value) { int64_t newInt = strtoll(value.c_str(), nullptr, 10); if (newInt <= 0) { newInt = std::numeric_limits<int64_t>::max(); m_maxMemory = std::to_string(newInt); } else { m_maxMemory = value; newInt = convert_bytes_to_long(value); if (newInt <= 0) { newInt = std::numeric_limits<int64_t>::max(); } } MM().getStatsNoRefresh().maxBytes = newInt; return true; }, nullptr ), &m_maxMemory); // Data Handling IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "arg_separator.output", "&", &m_argSeparatorOutput); IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "arg_separator.input", "&", &m_argSeparatorInput); IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "variables_order", "EGPCS", &m_variablesOrder); IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "request_order", "", &m_requestOrder); IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "default_charset", RuntimeOption::DefaultCharsetName.c_str(), &m_defaultCharset); IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "default_mimetype", "text/html", &m_defaultMimeType); // Paths and Directories IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "include_path", getDefaultIncludePath().c_str(), IniSetting::SetAndGet<std::string>( [this](const std::string& value) { m_include_paths.clear(); int pos = value.find(':'); if (pos < 0) { m_include_paths.push_back(value); } else { int pos0 = 0; do { // Check for stream wrapper if (value.length() > pos + 2 && value[pos + 1] == '/' && value[pos + 2] == '/') { // .:// or ..:// is not stream wrapper if (((pos - pos0) >= 1 && value[pos - 1] != '.') || ((pos - pos0) >= 2 && value[pos - 2] != '.') || (pos - pos0) > 2) { pos += 3; continue; } } m_include_paths.push_back( value.substr(pos0, pos - pos0)); pos++; pos0 = pos; } while ((pos = value.find(':', pos)) >= 0); if (pos0 <= value.length()) { m_include_paths.push_back( value.substr(pos0)); } } return true; }, [this]() { std::string ret; bool first = true; for (auto &path : m_include_paths) { if (first) { first = false; } else { ret += ":"; } ret += path; } return ret; } )); // Paths and Directories m_allowedDirectories = RuntimeOption::AllowedDirectories; m_safeFileAccess = RuntimeOption::SafeFileAccess; IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "open_basedir", IniSetting::SetAndGet<std::string>( [this](const std::string& value) { auto boom = HHVM_FN(explode)(";", value).toCArrRef(); std::vector<std::string> directories; directories.reserve(boom.size()); for (ArrayIter iter(boom); iter; ++iter) { const auto& path = iter.second().toString(); // Canonicalise the path if (!path.empty() && File::TranslatePathKeepRelative(path).empty()) { return false; } if (path.equal(s_dot)) { auto cwd = g_context->getCwd().toCppString(); directories.push_back(cwd); } else { directories.push_back(path.toCppString()); } } m_allowedDirectories = directories; m_safeFileAccess = !boom.empty(); return true; }, [this]() -> std::string { if (!hasSafeFileAccess()) { return ""; } std::string out; for (auto& directory: getAllowedDirectories()) { if (!directory.empty()) { out += directory + ";"; } } // Remove the trailing ; if (!out.empty()) { out.erase(std::end(out) - 1, std::end(out)); } return out; } )); // Errors and Logging Configuration Options IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "error_reporting", std::to_string(RuntimeOption::RuntimeErrorReportingLevel) .c_str(), &m_errorReportingLevel); IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "track_errors", "0", &m_trackErrors); IniSetting::Bind( IniSetting::CORE, IniSetting::PHP_INI_ALL, "html_errors", IniSetting::SetAndGet<bool>( [&] (const bool& on) { m_htmlErrors = on; return true; }, [&] () { return m_htmlErrors; } ), &m_htmlErrors ); IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "log_errors", IniSetting::SetAndGet<bool>( [this](const bool& on) { if (m_logErrors != on) { if (on) { if (!m_errorLog.empty()) { FILE *output = fopen(m_errorLog.data(), "a"); if (output) { Logger::SetNewOutput(output); } } } else { Logger::SetNewOutput(nullptr); } } return true; }, nullptr ), &m_logErrors); IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "error_log", IniSetting::SetAndGet<std::string>( [this](const std::string& value) { if (m_logErrors && !m_errorLog.empty()) { FILE *output = fopen(m_errorLog.data(), "a"); if (output) { Logger::SetNewOutput(output); } } return true; }, nullptr ), &m_errorLog); // Filesystem and Streams Configuration Options IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "user_agent", "", &m_userAgent); IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "default_socket_timeout", std::to_string(RuntimeOption::SocketDefaultTimeout).c_str(), &m_socketDefaultTimeout); // Response handling. // TODO(T5601927): output_compression supports int values where the value // represents the output buffer size. Also need to add a // zlib.output_handler ini setting as well. // http://docs.hhvm.com/zlib.configuration.php IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "zlib.output_compression", &m_gzipCompression); IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, "zlib.output_compression_level", &m_gzipCompressionLevel); }