Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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);
}
Пример #4
0
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);
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
  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");
    }
  }
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
bool IniSetting::Get(const String& name, Variant& value) {
  auto cb = get_callback(name.toCppString());
  if (!cb) {
    return false;
  }
  value = cb->getCallback();
  return true;
}
Пример #11
0
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;
}
Пример #12
0
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
  ));
}
Пример #13
0
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;
}
Пример #14
0
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;
}
Пример #15
0
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;
}
Пример #16
0
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();
}
Пример #17
0
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());
  }
}
Пример #18
0
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;
}
Пример #19
0
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;
}
Пример #20
0
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;
}
Пример #21
0
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;
}
Пример #22
0
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);
  }
}
Пример #23
0
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);
  }
}
Пример #24
0
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;
}
Пример #25
0
bool IniSetting::Get(const String& name, String &value) {
  std::string b;
  auto ret = Get(name.toCppString(), b);
  value = b;
  return ret;
}
Пример #26
0
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;
}
Пример #27
0
static void HHVM_METHOD(EncodingDetector, setDeclaredEncoding,
                        const String& declaredEncoding) {
  FETCH_DET(data, this_);
  data->setDeclaredEncoding(declaredEncoding.toCppString());
}
Пример #28
0
static void HHVM_METHOD(EncodingDetector, setText, const String& text) {
  FETCH_DET(data, this_);
  data->setText(text.toCppString());
}
Пример #29
0
bool IniSetting::SetUser(const String& name, const Variant& value) {
    return SetUser(name.toCppString(), variant_to_dynamic(value), FollyDynamic());
}
Пример #30
0
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;
  }
}