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; }
static void mysql_set_conn_attrs( std::shared_ptr<MySQL> mySQL, const Array* conn_attrs) { assertx(mySQL != nullptr && mySQL->get() != nullptr); for (auto itr = conn_attrs->begin(); !itr.end(); itr.next()) { const auto& key = itr.first(); const auto& value = itr.secondRef(); if (!key.isString()) { raise_warning( "MySQL: Invalid connection attribute - key is not a string"); } else if (!value.isString()) { raise_warning( std::string("MySQL: Invalid connection attribute - " "value is not a string for key '") + key.asCStrRef().toCppString() + "'"); } else { mysql_set_conn_attr(mySQL->get(), key.asCStrRef(), value.asCStrRef()); } } }