bool TestExtVariable::test_unserialize() {
  {
    // this was crashing
    f_unserialize(StringUtil::HexDecode("53203a20224c612072756f74612067697261207065722074757474692220204d203a20227365636f6e646f206d6520736920c3a820696e6361737472617461206461207175616c6368652070617274652122"));
  }
  {
    Variant v = f_unserialize("O:8:\"stdClass\":1:{s:4:\"name\";s:5:\"value\";}");
    VERIFY(v.is(KindOfObject));
    Object obj = v.toObject();
    VS(obj->o_getClassName(), "stdClass");
    VS(obj.o_get("name"), "value");
  }
  {
    Variant v = f_unserialize(String("O:8:\"stdClass\":1:{s:7:\"\0*\0name\";s:5:\"value\";}", 45, AttachLiteral));
    VERIFY(v.is(KindOfObject));
    Object obj = v.toObject();
    VS(obj->o_getClassName(), "stdClass");
    VS(obj.o_get("name"), "value");
  }
  {
    Variant v1 = CREATE_MAP3("a","apple","b",2,"c",CREATE_VECTOR3(1,"y",3));
    Variant v2 = f_unserialize("a:3:{s:1:\"a\";s:5:\"apple\";s:1:\"b\";i:2;s:1:\"c\";a:3:{i:0;i:1;i:1;s:1:\"y\";i:2;i:3;}}");
    VS(v1, v2);
  }
  return Count(true);
}
Esempio n. 2
0
void UnitRepoProxy::GetUnitArraysStmt
                  ::get(UnitEmitter& ue) {
  RepoTxn txn(m_repo);
  if (!prepared()) {
    std::stringstream ssSelect;
    ssSelect << "SELECT arrayId,array FROM "
             << m_repo.table(m_repoId, "UnitArray")
             << " WHERE unitSn == @unitSn ORDER BY arrayId ASC;";
    txn.prepare(*this, ssSelect.str());
  }
  RepoTxnQuery query(txn, *this);
  query.bindInt64("@unitSn", ue.sn());
  do {
    query.step();
    if (query.row()) {
      Id arrayId;        /**/ query.getId(0, arrayId);
      StringData* array; /**/ query.getStaticString(1, array);
      String s(array);
      Variant v = f_unserialize(s);
      Id id UNUSED = ue.mergeArray(v.asArrRef().get(), array);
      ASSERT(id == arrayId);
    }
  } while (!query.done());
  txn.commit();
}
Esempio n. 3
0
Variant f_call_user_func_rpc(int _argc, CStrRef host, int port, CStrRef auth,
                             int timeout, CVarRef function,
                             CArrRef _argv /* = null_array */) {
  string shost = host.data();
  if (!RuntimeOption::DebuggerRpcHostDomain.empty()) {
    unsigned int pos = shost.find(RuntimeOption::DebuggerRpcHostDomain);
    if (pos == string::npos ||
        pos != shost.length() - RuntimeOption::DebuggerRpcHostDomain.size()) {
      shost += RuntimeOption::DebuggerRpcHostDomain;
    }
  }

  string url = "http://";
  url += shost;
  url += ":";
  url += lexical_cast<string>(port);
  url += "/call_user_func_serialized?auth=";
  url += auth.data();

  Array blob = CREATE_MAP2("func", function, "args", _argv);
  String message = f_serialize(blob);

  vector<string> headers;
  LibEventHttpClientPtr http = LibEventHttpClient::Get(shost, port);
  if (!http->send(url, headers, timeout < 0 ? 0 : timeout, false,
                  message.data(), message.size())) {
    raise_error("Unable to send RPC request");
    return false;
  }

  int code = http->getCode();
  if (code <= 0) {
    raise_error("Server timed out or unable to find specified URL: %s",
                url.c_str());
    return false;
  }

  int len = 0;
  char *response = http->recv(len);
  String sresponse(response, len, AttachString);
  if (code != 200) {
    raise_error("Internal server error: %d %s", code,
                HttpProtocol::GetReasonString(code));
    return false;
  }

  // This double decoding can be avoided by modifying RPC server to directly
  // take PHP serialization format.
  Variant res = f_unserialize(f_json_decode(sresponse));
  if (!res.isArray()) {
    raise_error("Internal protocol error");
    return false;
  }

  if (res.toArray().exists("exception")) {
    throw res["exception"];
  }
  return res["ret"];
}
Esempio n. 4
0
bool TestCppBase::TestObject() {
  {
    String s = "O:1:\"B\":1:{s:3:\"obj\";O:1:\"A\":1:{s:1:\"a\";i:10;}}";
    VS(f_serialize(f_unserialize(s)), "O:22:\"__PHP_Incomplete_Class\":2:{s:27:\"__PHP_Incomplete_Class_Name\";s:1:\"B\";s:3:\"obj\";O:22:\"__PHP_Incomplete_Class\":2:{s:27:\"__PHP_Incomplete_Class_Name\";s:1:\"A\";s:1:\"a\";i:10;}}");
  }
  VERIFY(!equal(Object(new TestResource()), Object(new TestResource()) ));
  return Count(true);
}
Esempio n. 5
0
static void set_function_info(Array &ret, const ClassInfo::MethodInfo *info,
                              const char *classname) {
  // return type
  ret.set("ref", (bool)(info->attribute & ClassInfo::IsReference));

  // doc comments
  set_doc_comment(ret, info->docComment);

  // parameters
  {
    Array arr = Array::Create();
    for (unsigned int i = 0; i < info->parameters.size(); i++) {
      Array param = Array::Create();
      const ClassInfo::ParameterInfo *p = info->parameters[i];
      param.set("index", (int)i);
      param.set("name", p->name);
      param.set("type", p->type);
      if (classname) {
        param.set("class", classname);
      }
      if (p->type && *p->type) {
        param.set("nullable", false);
      } else {
        param.set("nullable", true);
      }
      if (p->value && *p->value) {
        const char *defText = p->valueText;
        if (defText == NULL) defText = "";

        ASSERT(p->attribute & ClassInfo::IsOptional);
        if (*p->value == '\x01') {
          Object v(SystemLib::AllocStdClassObject());
          v.o_set("msg", String("unable to eval ") + defText);
          param.set("default", v);
        } else {
          param.set("default", f_unserialize(p->value));
        }
        param.set("defaultText", defText);
      } else {
        ASSERT((p->attribute & ClassInfo::IsOptional) == 0);
      }
      param.set("ref", (bool)(p->attribute & ClassInfo::IsReference));
      arr.append(param);
    }
    ret.set("params", arr);
  }

  // static variables
  {
    Array arr = Array::Create();
    for (unsigned int i = 0; i < info->staticVariables.size(); i++) {
      const ClassInfo::ConstantInfo *p = info->staticVariables[i];
      ASSERT(p->valueText && *p->valueText);
      arr.set(p->name, p->valueText);
    }
    ret.set("static_variables", arr);
  }
}
Esempio n. 6
0
String f_call_user_func_serialized(CStrRef input) {
  Variant out;
  try {
    Variant in = f_unserialize(input);
    out.set("ret", f_call_user_func_array(in["func"], in["args"]));
  } catch (Object &e) {
    out.set("exception", e);
  }
  return f_serialize(out);
}
bool TestExtFile::test_file_get_contents() {
  Variant f = f_fopen("test/test_ext_file.tmp", "w");
  f_fputs(f, "testing file_get_contents");
  f_fclose(f);

  VS(f_file_get_contents("test/test_ext_file.tmp"),
     "testing file_get_contents");

  VS(f_unserialize(f_file_get_contents("compress.zlib://test/test_zlib_file")),
     CREATE_VECTOR1("rblock:216105"));
  return Count(true);
}
Esempio n. 8
0
static void set_function_info(Array &ret, const ClassInfo::MethodInfo *info,
                              const char *classname) {
  // return type
  ret.set("ref", (bool)(info->attribute & ClassInfo::IsReference));

  const char *dc = info->docComment;
  if (dc) {
    ret.set("doc", dc);
  } else {
    ret.set("doc", false);
  }

  // parameters
  {
    Array arr = Array::Create();
    for (unsigned int i = 0; i < info->parameters.size(); i++) {
      Array param = Array::Create();
      const ClassInfo::ParameterInfo *p = info->parameters[i];
      param.set("index", (int)i);
      param.set("name", p->name);
      param.set("type", p->type);
      if (classname) {
        param.set("class", classname);
      }
      if (p->type && *p->type) {
        param.set("nullable", false);
      } else {
        param.set("nullable", true);
      }
      if (p->value && *p->value) {
        ASSERT(p->attribute & ClassInfo::IsOptional);
        param.set("default", f_unserialize(p->value));
      } else {
        ASSERT((p->attribute & ClassInfo::IsOptional) == 0);
      }
      param.set("ref", (bool)(p->attribute & ClassInfo::IsReference));
      arr.append(param);
    }
    ret.set("params", arr);
  }

  // static variables
  {
    Array arr = Array::Create();
    for (unsigned int i = 0; i < info->staticVariables.size(); i++) {
      const ClassInfo::ConstantInfo *p = info->staticVariables[i];
      ASSERT(p->valueText && *p->valueText);
      arr.set(p->name, p->valueText);
    }
    ret.set("static_variables", arr);
  }
}
Esempio n. 9
0
bool TestExtVariable::test_unserialize() {
  {
    Variant v = f_unserialize("O:8:\"stdClass\":1:{s:4:\"name\";s:5:\"value\";}");
    VERIFY(v.is(KindOfObject));
    Object obj = v.toObject();
    VS(obj->o_getClassName(), "stdClass");
    VS(obj.o_get("name"), "value");
  }
  {
    Variant v = f_unserialize(String("O:8:\"stdClass\":1:{s:7:\"\0*\0name\";s:5:\"value\";}", 45, AttachLiteral));
    VERIFY(v.is(KindOfObject));
    Object obj = v.toObject();
    VS(obj->o_getClassName(), "stdClass");
    VS(obj.o_get("name"), "value");
  }
  {
    Variant v1 = CREATE_MAP3("a","apple","b",2,"c",CREATE_VECTOR3(1,"y",3));
    Variant v2 = f_unserialize("a:3:{s:1:\"a\";s:5:\"apple\";s:1:\"b\";i:2;s:1:\"c\";a:3:{i:0;i:1;i:1;s:1:\"y\";i:2;i:3;}}");
    VS(v1, v2);
  }
  return Count(true);
}
Esempio n. 10
0
void ArrayUtil::InitScalarArrays(Array arrs[], int nArrs,
                                 const char *scalarArrayData,
                                 int scalarArrayDataSize) {
  int len = scalarArrayDataSize;
  char *uncompressed = gzdecode(scalarArrayData, len);
  if (uncompressed == NULL) {
    throw Exception("Bad scalarArrayData %p", scalarArrayData);
  }
  String s = String(uncompressed, len, AttachString);
  Variant v =  f_unserialize(s);
  ASSERT(v.isArray());
  Array scalarArrays =  v;
  ASSERT(scalarArrays.size() == nArrs);
  for (int i = 0; i < nArrs; i++) {
    arrs[i] = scalarArrays[i];
    arrs[i].setStatic();
  }
}
Esempio n. 11
0
Variant static memcache_fetch_from_storage(const char *payload,
                                           size_t payload_len,
                                           uint32_t flags) {
  Variant ret = null;

  if (flags & MMC_COMPRESSED) {
    raise_warning("Unable to handle compressed values yet");
    return null;
  }

  if (flags & MMC_SERIALIZED) {
    ret = f_unserialize(String(payload, payload_len, AttachLiteral));
    // raise_notice("unable to unserialize data");
  } else {
    ret = String(payload, payload_len, CopyString);
  }

  return ret;
}
Esempio n. 12
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 = f_unserialize(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;
  }
}
Esempio n. 13
0
/**
 * PHP has "EGPCS" processing order of these global variables, and this
 * order is important in preparing $_REQUEST that needs to know which to
 * overwrite what when name happens to be the same.
 */
void HttpProtocol::PrepareSystemVariables(Transport *transport,
                                          const RequestURI &r,
                                          const SourceRootInfo &sri) {
  SystemGlobals *g = (SystemGlobals*)get_global_variables();
  const VirtualHost *vhost = VirtualHost::GetCurrent();

  // reset global symbols to nulls or empty arrays
  pm_php$globals$symbols_php();

  Variant &server = g->GV(_SERVER);
  server.set("REQUEST_START_TIME", time(NULL));

  // $_ENV
  process_env_variables(g->GV(_ENV));
  g->GV(_ENV).set("HPHP", 1);
  g->GV(_ENV).set("HPHP_SERVER", 1);
#ifdef HOTPROFILER
  g->GV(_ENV).set("HPHP_HOTPROFILER", 1);
#endif

  Variant &request = g->GV(_REQUEST);

  // $_GET and $_REQUEST
  if (!r.queryString().empty()) {
    DecodeParameters(g->GV(_GET), r.queryString().data(),
                     r.queryString().size());
    CopyParams(request, g->GV(_GET));
  }

  string contentType = transport->getHeader("Content-Type");
  string contentLength = transport->getHeader("Content-Length");
  // $_POST and $_REQUEST
  if (transport->getMethod() == Transport::POST) {
    bool needDelete = false;
    int size = 0;
    const void *data = transport->getPostData(size);
    if (data && size) {
      ASSERT(((char*)data)[size] == 0); // we need a NULL terminated string
      string boundary;
      int content_length = atoi(contentLength.c_str());
      bool rfc1867Post = IsRfc1867(contentType, boundary);
      string files;
      if (rfc1867Post) {
        if (content_length > VirtualHost::GetMaxPostSize()) {
          // $_POST and $_FILES are empty
          Logger::Warning("POST Content-Length of %d bytes exceeds "
                          "the limit of %lld bytes",
                          content_length, VirtualHost::GetMaxPostSize());
          needDelete = read_all_post_data(transport, data, size);
        } else {
          if (transport->hasMorePostData()) {
            needDelete = true;
            data = Util::buffer_duplicate(data, size);
          }
          DecodeRfc1867(transport, g->GV(_POST), g->GV(_FILES),
                        content_length, data, size, boundary);
        }
        ASSERT(!transport->getFiles(files));
      } else {
        needDelete = read_all_post_data(transport, data, size);

        bool decodeData = strncasecmp(contentType.c_str(),
                                       DEFAULT_POST_CONTENT_TYPE,
                                       sizeof(DEFAULT_POST_CONTENT_TYPE)-1) == 0;
        // Always decode data for now. (macvicar)
        decodeData = true;

        if (decodeData) {
          DecodeParameters(g->GV(_POST), (const char*)data, size, true);
        }

        bool ret = transport->getFiles(files);
        if (ret) {
          g->GV(_FILES) = f_unserialize(files);
        }
      }
      CopyParams(request, g->GV(_POST));
      if (needDelete) {
        if (RuntimeOption::AlwaysPopulateRawPostData) {
          g->GV(HTTP_RAW_POST_DATA) = String((char*)data, size, AttachString);
        } else {
          free((void *)data);
        }
      } else {
        // For literal we disregard RuntimeOption::AlwaysPopulateRawPostData
        g->GV(HTTP_RAW_POST_DATA) = String((char*)data, size, AttachLiteral);
      }
    }
  }

  // $_COOKIE
  string cookie_data = transport->getHeader("Cookie");
  if (!cookie_data.empty()) {
    StringBuffer sb;
    sb.append(cookie_data);
    DecodeCookies(g->GV(_COOKIE), (char*)sb.data());
    CopyParams(request, g->GV(_COOKIE));
  }

  // $_SERVER

  // HTTP_ headers -- we don't exclude headers we handle elsewhere (e.g.,
  // Content-Type, Authorization), since the CGI "spec" merely says the server
  // "may" exclude them; this is not what APE does, but it's harmless.
  HeaderMap headers;
  transport->getHeaders(headers);
  for (HeaderMap::const_iterator iter = headers.begin();
       iter != headers.end(); ++iter) {
    const vector<string> &values = iter->second;
    for (unsigned int i = 0; i < values.size(); i++) {
      String key = "HTTP_";
      key += StringUtil::ToUpper(iter->first).replace("-", "_");
      server.set(key, String(values[i]));
    }
  }
  string host = transport->getHeader("Host");
  String hostName(VirtualHost::GetCurrent()->serverName(host));
  string hostHeader(host);
  if (hostHeader.empty()) {
    server.set("HTTP_HOST", hostName);
    StackTraceNoHeap::AddExtraLogging("Server", hostName.data());
  } else {
    StackTraceNoHeap::AddExtraLogging("Server", hostHeader.c_str());
  }
  if (hostName.empty() || RuntimeOption::ForceServerNameToHeader) {
    hostName = hostHeader;
    // _SERVER['SERVER_NAME'] shouldn't contain the port number
    int colonPos = hostName.find(':');
    if (colonPos != String::npos) {
      hostName = hostName.substr(0, colonPos);
    }
  }

  // APE sets CONTENT_TYPE and CONTENT_LENGTH without HTTP_
  if (!contentType.empty()) {
    server.set("CONTENT_TYPE", String(contentType));
  }
  if (!contentLength.empty()) {
    server.set("CONTENT_LENGTH", String(contentLength));
  }

  // APE processes Authorization: Basic into PHP_AUTH_USER and PHP_AUTH_PW
  string authorization = transport->getHeader("Authorization");
  if (!authorization.empty()) {
    if (strncmp(authorization.c_str(), "Basic ", 6) == 0) {
      // it's safe to pass this as a string literal since authorization
      // outlives decodedAuth; this saves us a superfluous copy.
      String decodedAuth =
        StringUtil::Base64Decode(String(authorization.c_str() + 6));
      int colonPos = decodedAuth.find(':');
      if (colonPos != String::npos) {
        server.set("PHP_AUTH_USER", decodedAuth.substr(0, colonPos));
        server.set("PHP_AUTH_PW", decodedAuth.substr(colonPos + 1));
      }
    }
  }

  server.set("REQUEST_URI", String(transport->getUrl(), CopyString));
  server.set("SCRIPT_URL", r.originalURL());
  String prefix(transport->isSSL() ? "https://" : "http://");
  String port_suffix("");

  // Need to append port
  if (!transport->isSSL() && RuntimeOption::ServerPort != 80) {
    port_suffix = ":" + RuntimeOption::ServerPort;
  }
  server.set("SCRIPT_URI", String(prefix +
                                  (hostHeader.empty() ?
                                    hostName + port_suffix : hostHeader)
                                  + r.originalURL()));

  if (r.rewritten()) {
    // when URL is rewritten, PHP decided to put original URL as SCRIPT_NAME
    String name = r.originalURL();
    if (!r.pathInfo().empty()) {
      int pos = name.find(r.pathInfo());
      if (pos >= 0) {
        name = name.substr(0, pos);
      }
    }
    if (r.defaultDoc()) {
      if (!name.empty() && name[name.length() - 1] != '/') {
        name += "/";
      }
      name += String(RuntimeOption::DefaultDocument);
    }
    server.set("SCRIPT_NAME", name);
  } else {
    server.set("SCRIPT_NAME", r.resolvedURL());
  }
  if (!r.rewritten() && r.pathInfo().empty()) {
    server.set("PHP_SELF", r.resolvedURL());
  } else {
    // when URL is rewritten, or pathinfo is not empty, use original URL
    server.set("PHP_SELF", r.originalURL());
  }

  server.set("SCRIPT_FILENAME", r.absolutePath());
  if (r.pathInfo().empty()) {
    server.set("PATH_TRANSLATED", r.absolutePath());
  } else {
    server.set("PATH_TRANSLATED",
               String(vhost->getDocumentRoot() + r.pathInfo().data()));
    server.set("PATH_INFO", r.pathInfo());
  }

  server.set("argv", r.queryString());
  server.set("argc", 0);
  server.set("GATEWAY_INTERFACE", "CGI/1.1");
  server.set("SERVER_ADDR", String(RuntimeOption::ServerPrimaryIP));
  server.set("SERVER_NAME", hostName);
  server.set("SERVER_PORT", RuntimeOption::ServerPort);
  server.set("SERVER_SOFTWARE", "HPHP");
  server.set("SERVER_PROTOCOL", "HTTP/" + transport->getHTTPVersion());
  server.set("SERVER_ADMIN", "");
  server.set("SERVER_SIGNATURE", "");
  switch (transport->getMethod()) {
  case Transport::GET:  server.set("REQUEST_METHOD", "GET");  break;
  case Transport::HEAD: server.set("REQUEST_METHOD", "HEAD"); break;
  case Transport::POST:
    if (transport->getExtendedMethod() == NULL) {
      server.set("REQUEST_METHOD", "POST");
    } else {
      server.set("REQUEST_METHOD", transport->getExtendedMethod());
    }
    break;
  default:              server.set("REQUEST_METHOD", "");     break;
  }
  server.set("HTTPS", transport->isSSL() ? "1" : "");
  server.set("REQUEST_TIME", time(NULL));
  server.set("QUERY_STRING", r.queryString());

  server.set("REMOTE_ADDR", String(transport->getRemoteHost(), CopyString));
  server.set("REMOTE_HOST", ""); // I don't think we need to nslookup
  server.set("REMOTE_PORT", 0);  // TODO: quite useless

  server.set("DOCUMENT_ROOT", String(vhost->getDocumentRoot()));

  for (map<string, string>::const_iterator iter =
         RuntimeOption::ServerVariables.begin();
       iter != RuntimeOption::ServerVariables.end(); ++iter) {
      server.set(String(iter->first), String(iter->second));
  }
  const map<string, string> &vServerVars = vhost->getServerVars();
  for (map<string, string>::const_iterator iter =
         vServerVars.begin();
       iter != vServerVars.end(); ++iter) {
    server.set(String(iter->first), String(iter->second));
  }
  sri.setServerVariables(server);

  const char *threadType = transport->getThreadTypeName();
  server.set("THREAD_TYPE", threadType);
  StackTraceNoHeap::AddExtraLogging("ThreadType", threadType);

#ifdef TAINTED
  taint_array_variant(g->GV(_GET), "$_GET");
  taint_array_variant(g->GV(_POST), "$_POST");
  taint_array_variant(g->GV(_SERVER), "$_SERVER");
  taint_array_variant(g->GV(_COOKIE), "$_COOKIE");
#endif
}
Esempio n. 14
0
void PDOConnection::persistentRestore() {
  if (!serialized_def_stmt_ctor_args.empty()) {
    def_stmt_ctor_args = f_unserialize(serialized_def_stmt_ctor_args);
  }
}