Example #1
0
Variant HHVM_FUNCTION(serialize_memoize_param, const Variant& param) {
  // Memoize throws in the emitter if any function parameters are references, so
  // we can just assert that the param is cell here
  const auto& cell_param = *tvAssertCell(param.asTypedValue());
  auto type = param.getType();

  if (type == KindOfInt64) {
    return param;
  } else if (type == KindOfUninit || type == KindOfNull) {
    return s_empty;
  } else if (type == KindOfBoolean) {
    return param.asBooleanVal() ? s_true : s_false;
  } else if (type == KindOfString) {
    auto str = param.asCStrRef();
    if (str.empty()) {
      return s_emptyStr;
    } else if (str.charAt(0) > '9') {
      // If it doesn't start with a number, then we know it can never collide
      // with an int or any of our constants, so it's fine as is
      return param;
    }
  } else if (isContainer(cell_param) && getContainerSize(cell_param) == 0) {
    return s_emptyArr;
  }

  return fb_compact_serialize(param, FBCompactSerializeBehavior::MemoizeParam);
}
string& SourceRootInfo::initPhpRoot() {
  SystemGlobals *g = (SystemGlobals*)get_global_variables();
  Variant &server = g->GV(_SERVER);
  Variant v = server.rvalAt("PHP_ROOT");
  if (v.isString()) {
    *s_phproot.getCheck() = string(v.asCStrRef().data()) + string("/");
  } else {
    // Our best guess at the source root.
    *s_phproot.getCheck() = GetCurrentSourceRoot();
  }
  return *s_phproot.getCheck();
}
Example #3
0
Variant HHVM_FUNCTION(mcrypt_get_block_size, const String& cipher,
                                    const Variant& module /* = null_string */) {
  MCRYPT td = mcrypt_module_open((char*)cipher.data(),
                                 (char*)MCG(algorithms_dir).data(),
                                 (char*)module.asCStrRef().data(),
                                 (char*)MCG(modes_dir).data());
  if (td == MCRYPT_FAILED) {
    MCRYPT_OPEN_MODULE_FAILED("mcrypt_get_block_size");
    return false;
  }

  int64_t ret = mcrypt_enc_get_block_size(td);
  mcrypt_module_close(td);
  return ret;
}
Example #4
0
bool f_stream_is_local(const Variant& stream_or_url) {
  if (stream_or_url.isString()) {
    auto wrapper = Stream::getWrapperFromURI(stream_or_url.asCStrRef());
    return wrapper->m_isLocal;

  } else if (stream_or_url.isResource()) {
    File* file = dynamic_cast<File*>(stream_or_url.asCResRef().get());
    if (!file) {
      raise_warning("supplied resource is not a valid stream resource");
      return false;
    }
    return file->m_isLocal;
  }
  // Zend returns true for random data types...
  return true;
}
Example #5
0
void HHVM_METHOD(ZMQCert, __construct, const Variant& filename) {
  auto cert = Native::data<ZMQCert>(this_);

  if (filename.isNull()) {
    cert->zcert = zcert_new();

    if (!cert->zcert) {
      throwExceptionClass(s_ZMQCertExceptionClass, "Failed to create the underlying zcert object. Is libsodium installed?", PHP_ZMQ_INTERNAL_ERROR);
    }
  } else {
    cert->zcert = zcert_load(filename.asCStrRef().c_str());

    if (!cert->zcert) {
      throwExceptionClassFmt(s_ZMQCertExceptionClass, "Failed to load the certificate from {}", filename.asCStrRef());
    }
  }
}
Example #6
0
int libxml_streams_IO_read(void* context, char* buffer, int len) {
  ITRACE(1, "libxml_IO_read({}, {}, {})\n", context, (void*)buffer, len);
  Trace::Indent _i;

  Resource stream(static_cast<ResourceData*>(context));
  assert(len >= 0);
  Variant ret = HHVM_FN(fread)(stream, len);
  if (ret.isString()) {
    const String& str = ret.asCStrRef();
    if (str.size() <= len) {
      std::memcpy(buffer, str.data(), str.size());
      return str.size();
    }
  }

  return -1;
}
Example #7
0
void RepoQuery::getTypedValue(int iCol, TypedValue& tv) {
  const void* blob;
  size_t size;
  getBlob(iCol, blob, size);
  tvWriteUninit(&tv);
  if (size > 0) {
    String s = String((const char*)blob, size, CopyString);
    Variant v = unserialize_from_string(s);
    if (v.isString()) {
      v = String(StringData::GetStaticString(v.asCStrRef().get()));
    } else if (v.isArray()) {
      v = Array(ArrayData::GetScalarArray(v.asCArrRef().get()));
    } else {
      // Serialized variants and objects shouldn't ever make it into the repo.
      assert(!IS_REFCOUNTED_TYPE(v.getType()));
    }
    tvAsVariant(&tv) = v;
  }
}
Example #8
0
Variant HHVM_FUNCTION(bzopen, const Variant& filename, const String& mode) {
  if (mode != s_r && mode != s_w) {
    raise_warning(
      "'%s' is not a valid mode for bzopen(). "
      "Only 'w' and 'r' are supported.",
      mode.data()
    );
    return false;
  }

  BZ2File *bz;
  if (filename.isString()) {
    if (filename.asCStrRef().empty()) {
      raise_warning("filename cannot be empty");
      return false;
    }
    bz = newres<BZ2File>();
    bool ret = bz->open(File::TranslatePath(filename.toString()), mode);
    if (!ret) {
      raise_warning("%s", folly::errnoStr(errno).c_str());
      return false;
    }
  } else {
    if (!filename.isResource()) {
      raise_warning("first parameter has to be string or file-resource");
      return false;
    }
    PlainFile* f = filename.toResource().getTyped<PlainFile>();
    if (!f) {
      return false;
    }

    std::string stream_mode = f->getMode();
    int stream_mode_len = stream_mode.length();

    if (stream_mode_len != 1 &&
        !(stream_mode_len == 2 &&
          stream_mode.find('b') != std::string::npos)) {
      raise_warning("cannot use stream opened in mode '%s'",
                    stream_mode.c_str());
      return false;
    } else if (stream_mode_len == 1 &&
        stream_mode[0] != 'r' && stream_mode[0] != 'w' &&
        stream_mode[0] != 'a' && stream_mode[0] != 'x') {
      raise_warning("cannot use stream opened in mode '%s'",
                    stream_mode.c_str());
      return false;
    }

    const char rw_mode = stream_mode[0];
    if (mode == s_r && rw_mode != 'r') {
      raise_warning("cannot write to a stream opened in read only mode");
      return false;
    } else if (mode == s_w && rw_mode != 'w' && rw_mode != 'a' &&
               rw_mode != 'x') {
      raise_warning("cannot read from a stream opened in write only mode");
      return false;
    }

    bz = newres<BZ2File>(f);
  }
  Resource handle(bz);
  return handle;
}
Example #9
0
Variant HHVM_FUNCTION(proc_open,
                      const String& cmd,
                      const Array& descriptorspec,
                      VRefParam pipesParam,
                      const Variant& cwd /* = uninit_variant */,
                      const Variant& env /* = uninit_variant */,
                      const Variant& other_options /* = uninit_variant */) {
  if (RuntimeOption::WhitelistExec && !check_cmd(cmd.data())) {
    return false;
  }
  if (cmd.size() != strlen(cmd.c_str())) {
    raise_warning("NULL byte detected. Possible attack");
    return false;
  }
  Variant pipes(pipesParam, Variant::WithRefBind{});

  std::vector<DescriptorItem> items;

  std::string scwd = "";
  if (!cwd.isNull() && cwd.isString() && !cwd.asCStrRef().empty()) {
    scwd = cwd.asCStrRef().c_str();
  } else if (!g_context->getCwd().empty()) {
    scwd = g_context->getCwd().c_str();
  }

  Array enva;

  if (env.isNull()) {
    if (is_cli_mode()) {
      enva = cli_env();
    } else {
      // Build out an environment that conceptually matches what we'd
      // see if we were to iterate the environment and call getenv()
      // for each name.

      // Env vars defined in the hdf file go in first
      for (const auto& envvar : RuntimeOption::EnvVariables) {
        enva.set(String(envvar.first), String(envvar.second));
      }

      // global environment overrides the hdf
      for (char **env = environ; env && *env; env++) {
        char *p = strchr(*env, '=');
        if (p) {
          String name(*env, p - *env, CopyString);
          String val(p + 1, CopyString);
          enva.set(name, val);
        }
      }
    }

    // and then any putenv() changes take precedence
    for (ArrayIter iter(g_context->getEnvs()); iter; ++iter) {
      enva.set(iter.first(), iter.second());
    }
  } else {
    enva = env.toArray();
  }


#ifdef _WIN32
  PROCESS_INFORMATION pi;
  HANDLE childHandle;
  STARTUPINFO si;
  BOOL newprocok;
  SECURITY_ATTRIBUTES security;
  DWORD dwCreateFlags = 0;
  char *command_with_cmd;
  UINT old_error_mode;
  char cur_cwd[MAXPATHLEN];
  bool suppress_errors = false;
  bool bypass_shell = false;

  if (!other_options.isNull() && other_options.isArray()) {
    auto arr = other_options.asCArrRef();
    if (arr.exists(String("suppress_errors", CopyString), true)) {
      auto v = arr[String("suppress_errors", CopyString)];
      if ((v.isBoolean() && v.asBooleanVal()) ||
          (v.isInteger() && v.asInt64Val())) {
        suppress_errors = true;
      }
    }

    if (arr.exists(String("bypass_shell", CopyString), true)) {
      auto v = arr[String("bypass_shell", CopyString)];
      if ((v.isBoolean() && v.asBooleanVal()) ||
          (v.isInteger() && v.asInt64Val())) {
        bypass_shell = true;
      }
    }
  }

  /* we use this to allow the child to inherit handles */
  memset(&security, 0, sizeof(security));
  security.nLength = sizeof(security);
  security.bInheritHandle = true;
  security.lpSecurityDescriptor = nullptr;

  memset(&si, 0, sizeof(si));
  si.cb = sizeof(si);
  si.dwFlags = STARTF_USESTDHANDLES;

  si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
  si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  si.hStdError = GetStdHandle(STD_ERROR_HANDLE);

  if (!pre_proc_open(descriptorspec, items)) return false;
  /* redirect stdin/stdout/stderr if requested */
  for (size_t i = 0; i < items.size(); i++) {
    switch (items[i].index) {
      case 0:
        si.hStdInput = items[i].childend;
        break;
      case 1:
        si.hStdOutput = items[i].childend;
        break;
      case 2:
        si.hStdError = items[i].childend;
        break;
    }
  }


  memset(&pi, 0, sizeof(pi));

  if (suppress_errors) {
    old_error_mode = SetErrorMode(
      SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
  }

  dwCreateFlags = NORMAL_PRIORITY_CLASS;
  if (!RuntimeOption::ServerExecutionMode()) {
    dwCreateFlags |= CREATE_NO_WINDOW;
  }

  char *envp = build_envp(enva);
  if (bypass_shell) {
    newprocok = CreateProcess(
      nullptr,
      strdup(cmd.c_str()),
      &security,
      &security,
      TRUE,
      dwCreateFlags,
      envp,
      scwd.c_str(),
      &si,
      &pi);
  } else {
    std::string command_with = "cmd.exe /c ";
    command_with += cmd.toCppString();

    newprocok = CreateProcess(
      nullptr,
      strdup(command_with.c_str()),
      &security,
      &security,
      TRUE,
      dwCreateFlags,
      envp,
      scwd.c_str(),
      &si,
      &pi);
  }
  free(envp);

  if (suppress_errors) {
    SetErrorMode(old_error_mode);
  }

  if (newprocok == FALSE) {
    DWORD dw = GetLastError();
    char* msg;
    FormatMessageA(
      FORMAT_MESSAGE_ALLOCATE_BUFFER
        | FORMAT_MESSAGE_FROM_SYSTEM
        | FORMAT_MESSAGE_IGNORE_INSERTS,
      nullptr,
      dw,
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPSTR)&msg,
      0,
      nullptr);

    /* clean up all the descriptors */
    for (size_t i = 0; i < items.size(); i++) {
      CloseHandle(items[i].childend);
      if (items[i].parentend) {
        CloseHandle(items[i].parentend);
      }
    }
    raise_warning("CreateProcess failed, error code - %u: %s", dw, msg);
    LocalFree(msg);
    return false;
  }

  childHandle = pi.hProcess;
  DWORD child = pi.dwProcessId;
  CloseHandle(pi.hThread);
  return post_proc_open(cmd, pipes, enva, items, (pid_t)child, childHandle);
#else
  pid_t child;

  if (LightProcess::Available()) {
    // light process available
    // there is no need to do any locking, because the forking is delegated
    // to the light process
    if (!pre_proc_open(descriptorspec, items)) return false;
    const int item_size = items.size();
    std::vector<int> created;
    created.reserve(item_size);
    std::vector<int> intended;
    intended.reserve(item_size);
    for (int i = 0; i < item_size; i++) {
      const auto& item = items[i];
      created.push_back(item.childend);
      intended.push_back(item.index);
    }

    std::vector<std::string> envs;
    for (ArrayIter iter(enva); iter; ++iter) {
      StringBuffer nvpair;
      nvpair.append(iter.first().toString());
      nvpair.append('=');
      nvpair.append(iter.second().toString());
      std::string tmp = nvpair.detach().c_str();
      if (tmp.find('\n') == std::string::npos) {
        envs.push_back(tmp);
      }
    }

    child = LightProcess::proc_open(cmd.c_str(), created, intended,
                                    scwd.c_str(), envs);
    assert(child);
    return post_proc_open(cmd, pipes, enva, items, child);
  } else {
    /* the unix way */
    Lock lock(DescriptorItem::s_mutex);
    if (!pre_proc_open(descriptorspec, items)) return false;
    child = fork();
    if (child) {
      // the parent process
      return post_proc_open(cmd, pipes, enva, items, child);
    }
  }

  assert(child == 0);
  /* this is the child process */

  /* close those descriptors that we just opened for the parent stuff,
   * dup new descriptors into required descriptors and close the original
   * cruft */
  for (auto& item : items) {
    item.dupChild();
  }
  if (scwd.length() > 0 && chdir(scwd.c_str())) {
    // chdir failed, the working directory remains unchanged
  }
  std::vector<String> senvs; // holding those char *
  char **envp = build_envp(enva, senvs);
  execle("/bin/sh", "sh", "-c", cmd.data(), nullptr, envp);
  free(envp);
  _exit(127);
#endif
}
Example #10
0
void ZMQSocketData::set(ZMQSocketData* sock, int64_t type, const Variant& persistentId) {
  if (sock->ctx->is_persistent && !persistentId.isNull()) {
    s_persistent_socket_list[std::pair<int64_t, const char*>(type, persistentId.asCStrRef().c_str())] = sock;
  }
}