Esempio n. 1
0
Variant SSATmp::getValVariant() const {
  switch (type().toDataType()) {
  case KindOfUninit:
    return uninit_null();
  case KindOfNull:
    return init_null();
  case KindOfBoolean:
    return getValBool();
  case KindOfInt64:
    return getValInt();
  case KindOfDouble:
    return getValDbl();
  case KindOfString:
  case KindOfStaticString:
    return Variant(getValStr());
  case KindOfArray:
    return const_cast<ArrayData*>(getValArr());
  default:
    always_assert(false);
  }
}
Esempio n. 2
0
Variant f_parse_url(const String& url, int component /* = -1 */) {
  Url resource;
  if (!url_parse(resource, url.data(), url.size())) {
    return false;
  }

  if (component > -1) {
    switch (component) {
    case k_PHP_URL_SCHEME:   RETURN_COMPONENT(scheme);   break;
    case k_PHP_URL_HOST:     RETURN_COMPONENT(host);     break;
    case k_PHP_URL_USER:     RETURN_COMPONENT(user);     break;
    case k_PHP_URL_PASS:     RETURN_COMPONENT(pass);     break;
    case k_PHP_URL_PATH:     RETURN_COMPONENT(path);     break;
    case k_PHP_URL_QUERY:    RETURN_COMPONENT(query);    break;
    case k_PHP_URL_FRAGMENT: RETURN_COMPONENT(fragment); break;
    case k_PHP_URL_PORT:
      if (resource.port) {
        return resource.port;
      }
      break;
    default:
      throw_invalid_argument("component: %d", component);
      return false;
    }
    return uninit_null();
  }

  ArrayInit ret(8);
  SET_COMPONENT(scheme);
  SET_COMPONENT(host);
  if (resource.port) {
    ret.set(s_port, (int64_t)resource.port);
  }
  SET_COMPONENT(user);
  SET_COMPONENT(pass);
  SET_COMPONENT(path);
  SET_COMPONENT(query);
  SET_COMPONENT(fragment);
  return ret.create();
}
Esempio n. 3
0
static Variant xml_call_handler(XmlParser *parser, CVarRef handler,
                                CArrRef args) {
  if (parser && handler) {
    Variant retval;
    if (handler.isString()) {
      if (!parser->object.isObject()) {
        retval = invoke(handler.toString().c_str(), args, -1);
      } else {
        retval = parser->object.toObject()->
          o_invoke(handler.toString(), args);
      }
    } else if (handler.isArray() && handler.getArrayData()->size() == 2 &&
               (handler[0].isString() || handler[0].isObject()) &&
               handler[1].isString()) {
      vm_call_user_func(handler, args);
    } else {
      raise_warning("Handler is invalid");
    }
    return retval;
  }
  return uninit_null();
}
TypedValue* fg_php_check_syntax(ActRec* ar) {
  TypedValue rvSpace;
  TypedValue* rv = &rvSpace;
  int32_t count = ar->numArgs();
  TypedValue* args UNUSED = ((TypedValue*)ar) - 1;
  if (count >= 1 && count <= 2) {
    if (IS_STRING_TYPE((args - 0)->m_type)) {
      rv->m_type = KindOfBoolean;
      VRefParamValue defVal1 = uninit_null();
      rv->m_data.num = (fh_php_check_syntax(&args[-0].m_data, (count > 1) ? (args-1) : (TypedValue*)(&defVal1))) ? 1LL : 0LL;
    } else {
      fg1_php_check_syntax(rv, ar, count);
    }
  } else {
    throw_wrong_arguments_nr("php_check_syntax", count, 1, 2, 1);
    rv->m_data.num = 0LL;
    rv->m_type = KindOfNull;
  }
  frame_free_locals_no_this_inl(ar, 2);
  memcpy(&ar->m_r, rv, sizeof(TypedValue));
  return &ar->m_r;
}
Esempio n. 5
0
Variant f_socket_recv(CObjRef socket, VRefParam buf, int len, int flags) {
  if (len <= 0) {
    return false;
  }
  Socket *sock = socket.getTyped<Socket>();

  char *recv_buf = (char *)malloc(len + 1);
  int retval;
  if ((retval = recv(sock->fd(), recv_buf, len, flags)) < 1) {
    free(recv_buf);
    buf = uninit_null();
  } else {
    recv_buf[retval] = '\0';
    buf = String(recv_buf, retval, AttachString);
  }

  if (retval == -1) {
    SOCKET_ERROR(sock, "unable to read from socket", errno);
    return false;
  }
  return retval;
}
TypedValue* fg_is_callable(ActRec* ar) {
  TypedValue rvSpace;
  TypedValue* rv = &rvSpace;
  int32_t count = ar->numArgs();
  TypedValue* args UNUSED = ((TypedValue*)ar) - 1;
  if (count >= 1 && count <= 3) {
    if ((count <= 1 || (args - 1)->m_type == KindOfBoolean)) {
      rv->m_type = KindOfBoolean;
      VRefParamValue defVal2 = uninit_null();
      rv->m_data.num = (fh_is_callable((args-0), (count > 1) ? (bool)(args[-1].m_data.num) : (bool)(false), (count > 2) ? (args-2) : (TypedValue*)(&defVal2))) ? 1LL : 0LL;
    } else {
      fg1_is_callable(rv, ar, count);
    }
  } else {
    throw_wrong_arguments_nr("is_callable", count, 1, 3, 1);
    rv->m_data.num = 0LL;
    rv->m_type = KindOfNull;
  }
  frame_free_locals_no_this_inl(ar, 3);
  memcpy(&ar->m_r, rv, sizeof(TypedValue));
  return &ar->m_r;
}
Esempio n. 7
0
Variant f_array_map(int _argc, CVarRef callback, CVarRef arr1, CArrRef _argv /* = null_array */) {
  Array inputs;
  if (!arr1.isArray()) {
    throw_bad_array_exception();
    return uninit_null();
  }
  inputs.append(arr1);
  if (!_argv.empty()) {
    inputs = inputs.merge(_argv);
  }
  HPHP::VM::CallCtx ctx;
  ctx.func = NULL;
  if (!callback.isNull()) {
    CallerFrame cf;
    ctx.func = vm_decode_function(callback, cf(), false, ctx.this_, ctx.cls,
                                  ctx.invName);
  }
  if (ctx.func == NULL) {
    return ArrayUtil::Map(inputs, map_func, NULL);
  }
  return ArrayUtil::Map(inputs, map_func, &ctx);
}
bool TestExtMemcached::test_Memcached_types() {
  Array list;
  list.add(s_boolean_true, true);
  list.add(s_boolean_false, false);
  list.add(s_string, "just a string");
  list.add(s_string_empty, empty_string);
  list.add(s_integer_positive_integer, 10);
  list.add(s_integer_negative_integer, -10);
  list.add(s_integer_zero_integer, 0);
  list.add(s_float_positive1, 3.912131);
  list.add(s_float_positive2, 1.2131E+52);
  list.add(s_float_negative, -42.123312);
  list.add(s_float_zero, 0.0);
  list.add(s_null, uninit_null());
  list.add(s_array_empty, Array());
  list.add(s_array, CREATE_VECTOR4(1, 2, 3, "foo"));

  CREATE_MEMCACHED();
  for (ArrayIter iter(list); iter; ++iter) {
    VERIFY(memc->t_set(iter.first(), iter.second(), EXPIRATION));
    VS(memc->t_get(iter.first()), iter.second());
  }

  for (ArrayIter iter(list); iter; ++iter) {
    VERIFY(memc->t_delete(iter.first()));
  }

  VERIFY(memc->t_setmulti(list, EXPIRATION));
  Variant res = memc->t_getmulti(list.keys());
  VERIFY(res.isArray());
  Array resArray = res.toArray();
  VERIFY(resArray->size() == list.size());
  for (ArrayIter iter(resArray); iter; ++iter) {
    VS(iter.second(), list[iter.first()]);
  }

  return Count(true);
}
Esempio n. 9
0
Variant f_array_keys(CVarRef input, CVarRef search_value /* = null_variant */,
                     bool strict /* = false */) {
  const auto& cell_input = *input.asCell();
  if (UNLIKELY(!isContainer(cell_input))) {
    goto warn;
  }
  {
    // We treat Sets differently. For Sets, we pretend the values are
    // also the keys (similar to how Set::toArray() behaves).
    bool isSetType =
      cell_input.m_type == KindOfObject &&
      cell_input.m_data.pobj->getCollectionType() == Collection::SetType;
    if (UNLIKELY(isSetType)) {
      return arrayKeysSetHelper(cell_input, search_value, strict);
    }
    ArrayIter iter(cell_input);
    if (LIKELY(!search_value.isInitialized())) {
      PackedArrayInit ai(getContainerSize(cell_input));
      for (; iter; ++iter) {
        ai.append(iter.first());
      }
      return ai.toArray();
    }

    Array ai = Array::attach(HphpArray::MakeReserve(0));
    for (; iter; ++iter) {
      if ((strict && HPHP::same(iter.secondRefPlus(), search_value)) ||
          (!strict && HPHP::equal(iter.secondRefPlus(), search_value))) {
        ai.append(iter.first());
      }
    }
    return ai;
  }
warn:
  raise_warning("array_keys() expects parameter 1 to be an array "
                "or collection");
  return uninit_null();
}
TypedValue * fg1_apc_dec(TypedValue* rv, HPHP::VM::ActRec* ar, int64_t count) {
  TypedValue* args UNUSED = ((TypedValue*)ar) - 1;
  switch (count) {
  default: // count >= 4
    if ((args-3)->m_type != KindOfInt64) {
      tvCastToInt64InPlace(args-3);
    }
  case 3:
  case 2:
    if ((args-1)->m_type != KindOfInt64) {
      tvCastToInt64InPlace(args-1);
    }
  case 1:
    break;
  }
  if (!IS_STRING_TYPE((args-0)->m_type)) {
    tvCastToStringInPlace(args-0);
  }
  VRefParamValue defVal2 = uninit_null();
  fh_apc_dec((rv), (Value*)(args-0), (count > 1) ? (long)(args[-1].m_data.num) : (long)(1), (count > 2) ? (args-2) : (TypedValue*)(&defVal2), (count > 3) ? (long)(args[-3].m_data.num) : (long)(0));
  if (rv->m_type == KindOfUninit) rv->m_type = KindOfNull;
  return rv;
}
Esempio n. 11
0
bool TestExtOpenssl::test_openssl_seal() {
  Variant privkey = f_openssl_pkey_new();
  VERIFY(!privkey.isNull());
  Variant csr = f_openssl_csr_new(uninit_null(), privkey);
  VERIFY(!csr.isNull());
  Variant pubkey = f_openssl_csr_get_public_key(csr);
  VERIFY(!pubkey.isNull());

  String data = "some secret messages";
  Variant sealed;
  Variant ekeys;
  VERIFY(f_openssl_seal(data, ref(sealed), ref(ekeys),
                        CREATE_VECTOR1(pubkey)));
  VERIFY(!sealed.toString().empty());
  VS(ekeys.toArray().size(), 1);
  VERIFY(!ekeys[0].toString().empty());

  Variant open_data;
  VERIFY(f_openssl_open(sealed, ref(open_data), ekeys[0], privkey));
  VS(open_data, data);

  return Count(true);
}
Esempio n. 12
0
TypedValue* fg_xml_parse_into_struct(ActRec* ar) {
  TypedValue rvSpace;
  TypedValue* rv = &rvSpace;
  int32_t count = ar->numArgs();
  TypedValue* args UNUSED = ((TypedValue*)ar) - 1;
  if (count >= 3 && count <= 4) {
    if (IS_STRING_TYPE((args - 1)->m_type) &&
        (args - 0)->m_type == KindOfObject) {
      rv->m_type = KindOfInt64;
      VRefParamValue defVal3 = uninit_null();
      rv->m_data.num = (int64_t)fh_xml_parse_into_struct(&args[-0].m_data, &args[-1].m_data, (args-2), (count > 3) ? (args-3) : (TypedValue*)(&defVal3));
    } else {
      fg1_xml_parse_into_struct(rv, ar, count);
    }
  } else {
    throw_wrong_arguments_nr("xml_parse_into_struct", count, 3, 4, 1);
    rv->m_data.num = 0LL;
    rv->m_type = KindOfNull;
  }
  frame_free_locals_no_this_inl(ar, 4);
  memcpy(&ar->m_r, rv, sizeof(TypedValue));
  return &ar->m_r;
}
Esempio n. 13
0
Variant HHVM_FUNCTION(php_uname, const String& mode /*="" */) {
  struct utsname buf;
  if (uname((struct utsname *)&buf) == -1) {
    return uninit_null();
  }

  if (mode == s_s) {
    return String(buf.sysname, CopyString);
  } else if (mode == s_r) {
    return String(buf.release, CopyString);
  } else if (mode == s_n) {
    return String(buf.nodename, CopyString);
  } else if (mode == s_v) {
    return String(buf.version, CopyString);
  } else if (mode == s_m) {
    return String(buf.machine, CopyString);
  } else { /* assume mode == "a" */
    char tmp_uname[512];
    snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %s %s %s",
             buf.sysname, buf.nodename, buf.release, buf.version,
             buf.machine);
    return String(tmp_uname, CopyString);
  }
}
Esempio n. 14
0
ArrayData* PackedArray::Pop(ArrayData* adIn, Variant& value) {
  assert(checkInvariants(adIn));

  auto const ad = adIn->hasMultipleRefs() ? Copy(adIn) : adIn;

  if (UNLIKELY(ad->m_size == 0)) {
    value = uninit_null();
    ad->m_pos = ArrayData::invalid_index;
    return ad;
  }

  auto const oldSize = ad->m_size;
  auto& tv = packedData(ad)[oldSize - 1];
  value = tvAsCVarRef(&tv);
  if (UNLIKELY(strong_iterators_exist())) {
    adjustMArrayIter(ad, oldSize - 1);
  }
  auto const oldType = tv.m_type;
  auto const oldDatum = tv.m_data.num;
  ad->m_size = oldSize - 1;
  ad->m_pos = oldSize - 1 > 0 ? 0 : ArrayData::invalid_index;
  tvRefcountedDecRefHelper(oldType, oldDatum);
  return ad;
}
Esempio n. 15
0
Variant f_array_column(CVarRef input, CVarRef val_key,
                       CVarRef idx_key /* = null_variant */) {
  /* Be strict about array type */
  getCheckedArrayRet(input, uninit_null());
  Variant val = val_key, idx = idx_key;
  if (!array_column_coerce_key(val, "column") ||
      !array_column_coerce_key(idx, "index")) {
    return false;
  }
  Array ret = Array::Create();
  for(auto it = arr_input.begin(); !it.end(); it.next()) {
    if (!it.second().isArray()) {
      continue;
    }
    Array sub = it.second().toArray();

    Variant elem;
    if (val.isNull()) {
      elem = sub;
    } else if (sub.exists(val)) {
      elem = sub[val];
    } else {
      // skip subarray without named element
      continue;
    }

    if (idx.isNull() || !sub.exists(idx)) {
      ret.append(elem);
    } else if (sub[idx].isObject()) {
      ret.set(sub[idx].toString(), elem);
    } else {
      ret.set(sub[idx], elem);
    }
  }
  return ret;
}
Esempio n. 16
0
void DummySandbox::run() {
  TRACE(2, "DummySandbox::run\n");
  RequestInfo *ti = RequestInfo::s_requestInfo.getNoCheck();
  while (!m_stopped) {
    try {
      CLISession hphpSession;

      DSandboxInfo sandbox = m_proxy->getSandbox();
      std::string msg;
      if (sandbox.valid()) {
        SourceRootInfo sri(sandbox.m_user, sandbox.m_name);
        if (sandbox.m_path.empty()) {
          sandbox.m_path = sri.path();
        }
        if (!sri.sandboxOn()) {
          msg = "Invalid sandbox was specified. "
            "PHP files may not be loaded properly.\n";
        } else {
          auto server = php_global_exchange(s__SERVER, init_null());
          forceToArray(server);
          Array arr = server.toArrRef();
          server.unset();
          php_global_set(s__SERVER, sri.setServerVariables(std::move(arr)));
        }
        Debugger::RegisterSandbox(sandbox);
        g_context->setSandboxId(sandbox.id());

        std::string doc = getStartupDoc(sandbox);
        if (!doc.empty()) {
          char cwd[PATH_MAX];
          getcwd(cwd, sizeof(cwd));
          Logger::Info("Start loading startup doc '%s', pwd = '%s'",
                       doc.c_str(), cwd);
          bool error; std::string errorMsg;
          bool ret = hphp_invoke(g_context.getNoCheck(), doc, false, null_array,
                                 uninit_null(), "", "", error, errorMsg, true,
                                 false, true, RuntimeOption::EvalPreludePath);
          if (!ret || error) {
            msg += "Unable to pre-load " + doc;
            if (!errorMsg.empty()) {
              msg += ": " + errorMsg;
            }
          }
          Logger::Info("Startup doc " + doc + " loaded");
        }
      } else {
        g_context->setSandboxId(m_proxy->getDummyInfo().id());
      }

      if (!DebuggerHook::attach<HphpdHook>(ti)) {
        const char* fail = "Could not attach hphpd to request: another debugger"
                           " is already attached.";
        Logger::Error("%s", fail);
        Debugger::InterruptSessionStarted(nullptr, fail);
        throw DebuggerClientAttachFailureException();
      }
      {
        DebuggerDummyEnv dde;
        // This is really the entire point of having the dummy sandbox. This
        // fires the initial session started interrupt to the client after
        // it first attaches.
        Debugger::InterruptSessionStarted(nullptr, msg.c_str());
      }

      // Blocking until Ctrl-C is issued by end user and DebuggerProxy cannot
      // find a real sandbox thread to handle it.
      {
        Lock lock(this);
        while (!m_stopped && m_signum != CmdSignal::SignalBreak) {
          wait(1);
        }
        if (m_stopped) {
          // stopped by worker thread
          break;
        }
        m_signum = CmdSignal::SignalNone;
      }
    } catch (const DebuggerClientExitException& e) {
      // stopped by the dummy sandbox thread itself
      break;
    } catch (const DebuggerException& e) {
    }
  }
}
Esempio n. 17
0
Variant throw_fatal_unset_static_property(const char *s, const char *prop) {
  raise_error("Attempt to unset static property %s::$%s", s, prop);
  return uninit_null();
}
Esempio n. 18
0
bool TestExtJson::test_json_decode() {
  Array arr = CREATE_MAP1("fbid", 101501853510151001LL);
  VS(f_json_decode(f_json_encode(arr), true), arr);

  VS(f_json_decode("{\"0\":{\"00\":0}}", true),
     CREATE_MAP1("0", CREATE_MAP1("00", 0)));

  VS(f_json_decode("{\"a\":1,\"b\":2.3,\"3\":\"test\"}", true),
     CREATE_MAP3("a", 1, "b", 2.3, 3, "test"));
  VS(f_json_decode("[\"a\",1,true,false,null]", true),
     CREATE_VECTOR5("a", 1, true, false, uninit_null()));

  Object obj = f_json_decode("{\"a\":1,\"b\":2.3,\"3\":\"test\"}");
  Object obj2(SystemLib::AllocStdClassObject());
  obj2->o_set("a", 1);
  obj2->o_set("b", 2.3);
  obj2->o_set("3", "test");
  VS(obj.toArray(), obj2.toArray());

  obj = f_json_decode("[\"a\",1,true,false,null]");
  VS(obj.toArray(), CREATE_VECTOR5("a", 1, true, false, uninit_null()));

  VS(f_json_decode("{z:1}",     true),       uninit_null());
  VS(f_json_decode("{z:1}",     true, k_JSON_FB_LOOSE), CREATE_MAP1("z", 1));
  VS(f_json_decode("{z:\"z\"}", true),       uninit_null());
  VS(f_json_decode("{z:\"z\"}", true, k_JSON_FB_LOOSE), CREATE_MAP1("z", "z"));
  VS(f_json_decode("{'x':1}",   true),       uninit_null());
  VS(f_json_decode("{'x':1}",   true, k_JSON_FB_LOOSE), CREATE_MAP1("x", 1));
  VS(f_json_decode("{y:1,}",    true),       uninit_null());
  VS(f_json_decode("{y:1,}",    true, k_JSON_FB_LOOSE), CREATE_MAP1("y", 1));
  VS(f_json_decode("{,}",       true),       uninit_null());
  VS(f_json_decode("{,}",       true, k_JSON_FB_LOOSE), uninit_null());
  VS(f_json_decode("[1,2,3,]",  true),       uninit_null());
  VS(f_json_decode("[1,2,3,]",  true, k_JSON_FB_LOOSE), CREATE_VECTOR3(1,2,3));
  VS(f_json_decode("[,]",       true),       uninit_null());
  VS(f_json_decode("[,]",       true, k_JSON_FB_LOOSE), uninit_null());
  VS(f_json_decode("[]",        true),       Array::Create());
  VS(f_json_decode("[]",        true, k_JSON_FB_LOOSE), Array::Create());
  VS(f_json_decode("{}",        true),       Array::Create());
  VS(f_json_decode("{}",        true, k_JSON_FB_LOOSE), Array::Create());

  VS(f_json_decode("[{\"a\":\"apple\"},{\"b\":\"banana\"}]", true),
     CREATE_VECTOR2(CREATE_MAP1("a", "apple"), CREATE_MAP1("b", "banana")));

  Variant a = "[{\"a\":[{\"n\":\"1st\"}]},{\"b\":[{\"n\":\"2nd\"}]}]";
  VS(f_json_decode(a, true),
     CREATE_VECTOR2
     (CREATE_MAP1("a", CREATE_VECTOR1(CREATE_MAP1("n", "1st"))),
      CREATE_MAP1("b", CREATE_VECTOR1(CREATE_MAP1("n", "2nd")))));

  return Count(true);
}
Esempio n. 19
0
void DummySandbox::run() {
  TRACE(2, "DummySandbox::run\n");
  ThreadInfo *ti = ThreadInfo::s_threadInfo.getNoCheck();
  Debugger::RegisterThread();
  while (!m_stopped) {
    try {
      CLISession hphpSession;

      DSandboxInfo sandbox = m_proxy->getSandbox();
      string msg;
      if (sandbox.valid()) {
        GlobalVariables *g = get_global_variables();
        SourceRootInfo sri(sandbox.m_user, sandbox.m_name);
        if (sandbox.m_path.empty()) {
          sandbox.m_path = sri.path();
        }
        if (!sri.sandboxOn()) {
          msg = "Invalid sandbox was specified. "
            "PHP files may not be loaded properly.\n";
        } else {
          sri.setServerVariables(g->getRef(s__SERVER));
        }
        Debugger::RegisterSandbox(sandbox);
        g_context->setSandboxId(sandbox.id());

        std::string doc = getStartupDoc(sandbox);
        if (!doc.empty()) {
          char cwd[PATH_MAX];
          getcwd(cwd, sizeof(cwd));
          Logger::Info("Start loading startup doc '%s', pwd = '%s'",
                       doc.c_str(), cwd);
          bool error; string errorMsg;
          bool ret = hphp_invoke(g_context.getNoCheck(), doc, false, null_array,
                                 uninit_null(), "", "", error, errorMsg, true,
                                 false, true);
          if (!ret || error) {
            msg += "Unable to pre-load " + doc;
            if (!errorMsg.empty()) {
              msg += ": " + errorMsg;
            }
          }
          Logger::Info("Startup doc " + doc + " loaded");
        }
      } else {
        g_context->setSandboxId(m_proxy->getDummyInfo().id());
      }

      ti->m_reqInjectionData.setDebugger(true);
      {
        DebuggerDummyEnv dde;
        // This is really the entire point of having the dummy sandbox. This
        // fires the initial session started interrupt to the client after
        // it first attaches.
        Debugger::InterruptSessionStarted(nullptr, msg.c_str());
      }

      // Blocking until Ctrl-C is issued by end user and DebuggerProxy cannot
      // find a real sandbox thread to handle it.
      {
        Lock lock(this);
        while (!m_stopped && m_signum != CmdSignal::SignalBreak) {
          wait(1);
        }
        if (m_stopped) {
          // stopped by worker thread
          break;
        }
        m_signum = CmdSignal::SignalNone;
      }
    } catch (const DebuggerClientExitException &e) {
      // stopped by the dummy sandbox thread itself
      break;
    } catch (const DebuggerException &e) {
    }
  }
}
Esempio n. 20
0
Variant MySQLResult::getField(int64_t field) const {
  if (!m_localized || field < 0 || field >= (int64_t)m_current_row->size()) {
    return uninit_null();
  }
  return (*m_current_row)[field];
}
Esempio n. 21
0
bool RPCRequestHandler::executePHPFunction(Transport *transport,
                                           SourceRootInfo &sourceRootInfo) {
  // reset timeout counter
  ThreadInfo::s_threadInfo->m_reqInjectionData.started = time(0);

  string rpcFunc = transport->getCommand();
  {
    ServerStatsHelper ssh("input");
    RequestURI reqURI(rpcFunc);
    HttpProtocol::PrepareSystemVariables(transport, reqURI, sourceRootInfo);
    SystemGlobals *g = (SystemGlobals*)get_global_variables();
    g->GV(_ENV).set(s_HPHP_RPC, 1);
  }

  bool isFile = rpcFunc.rfind('.') != string::npos;
  string rpcFile;
  bool error = false;

  Array params;
  string sparams = transport->getParam("params");
  if (!sparams.empty()) {
    Variant jparams = f_json_decode(String(sparams), true);
    if (jparams.isArray()) {
      params = jparams.toArray();
    } else {
      error = true;
    }
  } else {
    vector<string> sparams;
    transport->getArrayParam("p", sparams);
    if (!sparams.empty()) {
      for (unsigned int i = 0; i < sparams.size(); i++) {
        Variant jparams = f_json_decode(String(sparams[i]), true);
        if (same(jparams, false)) {
          error = true;
          break;
        }
        params.append(jparams);
      }
    } else {
      // single string parameter, used by xbox to avoid any en/decoding
      int size;
      const void *data = transport->getPostData(size);
      if (data && size) {
        params.append(String((char*)data, size, AttachLiteral));
      }
    }
  }

  if (transport->getIntParam("reset") == 1) {
    m_reset = true;
  }
  int output = transport->getIntParam("output");

  int code;
  if (!error) {
    Variant funcRet;
    string errorMsg = "Internal Server Error";
    string reqInitFunc, reqInitDoc;
    reqInitDoc = transport->getHeader("ReqInitDoc");
    if (reqInitDoc.empty() && m_serverInfo) {
      reqInitFunc = m_serverInfo->getReqInitFunc();
      reqInitDoc = m_serverInfo->getReqInitDoc();
    }

    if (!reqInitDoc.empty()) {
      reqInitDoc = (std::string)canonicalize_path(reqInitDoc, "", 0);
    }
    if (!reqInitDoc.empty()) {
      reqInitDoc = getSourceFilename(reqInitDoc, sourceRootInfo);
    }

    bool runOnce = false;
    bool ret = true;
    if (isFile) {
      rpcFile = rpcFunc;
      rpcFunc.clear();
    } else {
      rpcFile = transport->getParam("include");
      if (rpcFile.empty()) {
        rpcFile = transport->getParam("include_once");
        runOnce = true;
      }
    }
    if (!rpcFile.empty()) {
      // invoking a file through rpc
      bool forbidden = false;
      if (!RuntimeOption::ForbiddenFileExtensions.empty()) {
        const char *ext = rpcFile.c_str() + rpcFile.rfind('.') + 1;
        if (RuntimeOption::ForbiddenFileExtensions.find(ext) !=
            RuntimeOption::ForbiddenFileExtensions.end()) {
          forbidden = true;
        }
      }
      if (!forbidden) {
        rpcFile = (std::string) canonicalize_path(rpcFile, "", 0);
        rpcFile = getSourceFilename(rpcFile, sourceRootInfo);
        ret = hphp_invoke(m_context, rpcFile, false, Array(), uninit_null(),
                          reqInitFunc, reqInitDoc, error, errorMsg, runOnce);
      }
      // no need to do the initialization for a second time
      reqInitFunc.clear();
      reqInitDoc.clear();
    }
    if (ret && !rpcFunc.empty()) {
      ret = hphp_invoke(m_context, rpcFunc, true, params, ref(funcRet),
                        reqInitFunc, reqInitDoc, error, errorMsg);
    }
    if (ret) {
      bool serializeFailed = false;
      String response;
      switch (output) {
        case 0: {
          assert(m_returnEncodeType == Json ||
                 m_returnEncodeType == Serialize);
          try {
            response = (m_returnEncodeType == Json) ? f_json_encode(funcRet)
                                                    : f_serialize(funcRet);
          } catch (...) {
            serializeFailed = true;
          }
          break;
        }
        case 1: response = m_context->obDetachContents(); break;
        case 2:
          response =
            f_json_encode(CREATE_MAP2(s_output, m_context->obDetachContents(),
                                      s_return, f_json_encode(funcRet)));
          break;
        case 3: response = f_serialize(funcRet); break;
      }
      if (serializeFailed) {
        code = 500;
        transport->sendString(
            "Serialization of the return value failed", 500);
        m_reset = true;
      } else {
        transport->sendRaw((void*)response.data(), response.size());
        code = transport->getResponseCode();
      }
    } else if (error) {
      code = 500;
      transport->sendString(errorMsg, 500);
      m_reset = true;
    } else {
      code = 404;
      transport->sendString("Not Found", 404);
    }
  } else {
    code = 400;
    transport->sendString("Bad Request", 400);
  }

  params.reset();
  sourceRootInfo.clear();

  transport->onSendEnd();
  ServerStats::LogPage(isFile ? rpcFile : rpcFunc, code);

  m_context->onShutdownPostSend();
  m_context->obClean(); // in case postsend/cleanup output something
  m_context->restoreSession();
  return !error;
}
Esempio n. 22
0
Variant& lvalBlackHole() {
  auto& bh = get_env_constants()->lvalProxy;
  bh = uninit_null();
  return bh;
}
Esempio n. 23
0
static void json_create_zval(Variant &z, StringBuffer &buf, int type,
                             int64_t options) {
  switch (type) {
    case KindOfBoolean:
      z = (buf.data() && (*buf.data() == 't'));
      return;

    case KindOfInt64: {
      bool bigint = false;
      const char *p = buf.data();
      assert(p);
      if (p == NULL) {
        z = int64_t(0);
        return;
      }

      bool neg = *buf.data() == '-';

      int len = buf.size();
      if (neg) len--;
      if (len >= MAX_LENGTH_OF_LONG - 1) {
        if (len == MAX_LENGTH_OF_LONG - 1) {
          int cmp = strcmp(p + (neg ? 1 : 0), long_min_digits);
          if (!(cmp < 0 || (cmp == 0 && neg))) {
            bigint = true;
          }
        } else {
          bigint = true;
        }
      }

      if (bigint) {
        if (!(options & k_JSON_BIGINT_AS_STRING)) {
          // See KindOfDouble (below)
          z = to_double(buf);
        } else {
          z = copy_and_clear(buf);
        }
      } else {
        z = int64_t(strtoll(buf.data(), nullptr, 10));
      }
      return;
    }

    case KindOfDouble:
      // Use zend_strtod() instead of strtod() here since JSON specifies using
      // a '.' for decimal separators regardless of locale.
      z = to_double(buf);
      return;

    case KindOfString:
      z = copy_and_clear(buf);
      return;

    case KindOfUninit:
    case KindOfNull:
    case KindOfStaticString:
    case KindOfArray:
    case KindOfObject:
    case KindOfResource:
    case KindOfRef:
      z = uninit_null();
      return;

    case KindOfClass:
      break;
  }
  not_reached();
}
Esempio n. 24
0
Variant c_XMLReader::t___destruct() {
  return uninit_null();
}
Esempio n. 25
0
static Variant warn_non_object() {
  raise_notice("Cannot access property on non-object");
  return uninit_null();
}
Esempio n. 26
0
Variant f_json_decode(const String& json, bool assoc /* = false */,
                      CVarRef options /* = 0 */) {

  json_set_last_error_code(json_error_codes::JSON_ERROR_NONE);

  if (json.empty()) {
    return uninit_null();
  }

  int64_t json_options = options.toInt64();
  if (options.isBoolean() && options.toBooleanVal()) {
    json_options = k_JSON_FB_LOOSE;
  }

  const int64_t supported_options =
    k_JSON_FB_LOOSE | k_JSON_FB_COLLECTIONS | k_JSON_FB_STABLE_MAPS;
  int64_t parser_options = json_options & supported_options;
  Variant z;
  if (JSON_parser(z, json.data(), json.size(), assoc, parser_options)) {
    return z;
  }

  if (json.size() == 4) {
    if (!strcasecmp(json.data(), "null")) {
      json_set_last_error_code(json_error_codes::JSON_ERROR_NONE);
      return uninit_null();
    }
    if (!strcasecmp(json.data(), "true")) {
      json_set_last_error_code(json_error_codes::JSON_ERROR_NONE);
      return true;
    }
  } else if (json.size() == 5 && !strcasecmp(json.data(), "false")) {
    json_set_last_error_code(json_error_codes::JSON_ERROR_NONE);
    return false;
  }

  int64_t p;
  double d;
  DataType type = json->isNumericWithVal(p, d, 0);
  if (type == KindOfInt64) {
    json_set_last_error_code(json_error_codes::JSON_ERROR_NONE);
    return p;
  } else if (type == KindOfDouble) {
    json_set_last_error_code(json_error_codes::JSON_ERROR_NONE);
    return d;
  }

  char ch0 = json.charAt(0);
  if (json.size() > 1 && ch0 == '"' && json.charAt(json.size() - 1) == '"') {
    json_set_last_error_code(json_error_codes::JSON_ERROR_NONE);

    // Wrap the string in an array to allow the JSON_parser to handle
    // things like unicode escape sequences, then unwrap to get result
    String wrapped("[");
    wrapped += json + "]";
    // Stick to a normal hhvm array for the wrapper
    const int64_t mask = ~(k_JSON_FB_COLLECTIONS | k_JSON_FB_STABLE_MAPS);
    if (JSON_parser(z, wrapped.data(), wrapped.size(), false,
                    parser_options & mask) && z.isArray()) {
      Array arr = z.toArray();
      if ((arr.size() == 1) && arr.exists(0)) {
        return arr[0];
      }
      // The input string could be something like: "foo","bar"
      // Which will parse inside the [] wrapper, but be invalid
      json_set_last_error_code(json_error_codes::JSON_ERROR_SYNTAX);
    }
  }

  if ((json_options & k_JSON_FB_LOOSE) && json.size() > 1 &&
      ch0 == '\'' && json.charAt(json.size() - 1) == '\'') {
    json_set_last_error_code(json_error_codes::JSON_ERROR_NONE);
    return json.substr(1, json.size() - 2);
  }

  if (ch0 == '{' || ch0 == '[') { /* invalid JSON string */
    json_set_last_error_code(json_error_codes::JSON_ERROR_SYNTAX);
  }

  assert(json_get_last_error_code() != json_error_codes::JSON_ERROR_NONE);
  return uninit_null();
}
Esempio n. 27
0
static Variant HHVM_FUNCTION(SystemLib_assert, const Variant& assertion,
                             const Variant& message = uninit_null()) {
  return impl_assert(assertion, message);
}
Esempio n. 28
0
Variant c_Normalizer::ti_normalize(const String& input,
                                   int64_t form /* = q_Normalizer$$FORM_C */) {
  s_intl_error->m_error.clear();

  int expansion_factor = 1;
  switch(form) {
  case UNORM_NONE:
  case UNORM_NFC:
  case UNORM_NFKC:
    break;
  case UNORM_NFD:
  case UNORM_NFKD:
    expansion_factor = 3;
    break;
  default:
    s_intl_error->m_error.code = U_ILLEGAL_ARGUMENT_ERROR;
    s_intl_error->m_error.custom_error_message =
      "normalizer_normalize: illegal normalization form";
    return uninit_null();
  }

  /* First convert the string to UTF-16. */
  UChar* uinput = NULL; int uinput_len = 0;
  UErrorCode status = U_ZERO_ERROR;
  intl_convert_utf8_to_utf16(&uinput, &uinput_len, input.data(), input.size(),
                             &status);

  if (U_FAILURE(status)) {
    s_intl_error->m_error.code = status;
    s_intl_error->m_error.custom_error_message =
        "Error converting string to UTF-16.";
    free(uinput);
    return uninit_null();
  }

  /* Allocate memory for the destination buffer for normalization */
  int uret_len = uinput_len * expansion_factor;
  UChar *uret_buf = (UChar*)malloc((uret_len + 1) * sizeof(UChar));

  /* normalize */
  int size_needed = unorm_normalize(uinput, uinput_len,
                                    (UNormalizationMode)form, (int32_t) 0,
                                    uret_buf, uret_len, &status);

  /* Bail out if an unexpected error occured.
   * (U_BUFFER_OVERFLOW_ERROR means that *target buffer is not large enough).
   * (U_STRING_NOT_TERMINATED_WARNING usually means that the input string
   * is empty).
   */
  if (U_FAILURE(status) &&
      status != U_BUFFER_OVERFLOW_ERROR &&
      status != U_STRING_NOT_TERMINATED_WARNING) {
    free(uret_buf);
    free(uinput);
    return uninit_null();
  }

  if (size_needed > uret_len) {
    /* realloc does not seem to work properly - memory is corrupted
     * uret_buf =  eurealloc(uret_buf, size_needed + 1); */
    free(uret_buf);
    uret_buf = (UChar*)malloc((size_needed + 1) * sizeof(UChar));
    uret_len = size_needed;

    status = U_ZERO_ERROR;

    /* try normalize again */
    size_needed = unorm_normalize( uinput, uinput_len,
                                   (UNormalizationMode)form, (int32_t) 0,
                                   uret_buf, uret_len, &status);

    /* Bail out if an unexpected error occured. */
    if (U_FAILURE(status)) {
      /* Set error messages. */
      s_intl_error->m_error.code = status;
      s_intl_error->m_error.custom_error_message = "Error normalizing string";
      free(uret_buf);
      free(uinput);
      return uninit_null();
    }
  }

  free(uinput);

  /* the buffer we actually used */
  uret_len = size_needed;

  /* Convert normalized string from UTF-16 to UTF-8. */
  char* ret_buf = NULL; int ret_len = 0;
  intl_convert_utf16_to_utf8(&ret_buf, &ret_len, uret_buf, uret_len, &status);
  free(uret_buf);
  if (U_FAILURE(status)) {
    s_intl_error->m_error.code = status;
    s_intl_error->m_error.custom_error_message =
      "normalizer_normalize: error converting normalized text UTF-8";
    return uninit_null();
  }

  return String(ret_buf, ret_len, AttachString);
}
Esempio n. 29
0
Variant c_Memcache::t___destruct() {
  t_close();
  return uninit_null();
}
Esempio n. 30
0
Variant c_DummyContinuation::t_current() {
  throw_fatal("Tring to use a DummyContinuation");
  return uninit_null();
}