Пример #1
0
Variant APCHandle::toLocal() const {
  switch (m_kind) {
    case APCKind::Uninit:
    case APCKind::Null:
      return init_null(); // shortcut.. no point to forward
    case APCKind::Bool:
      return APCTypedValue::fromHandle(this)->getBoolean();
    case APCKind::Int:
      return APCTypedValue::fromHandle(this)->getInt64();
    case APCKind::Double:
      return APCTypedValue::fromHandle(this)->getDouble();
    case APCKind::StaticString:
    case APCKind::UncountedString:
      return Variant{APCTypedValue::fromHandle(this)->getStringData(),
                     Variant::PersistentStrInit{}};
    case APCKind::SharedString:
      return Variant::attach(
        StringData::MakeProxy(APCString::fromHandle(this))
      );
    case APCKind::StaticArray:
    case APCKind::UncountedArray:
      return Variant{APCTypedValue::fromHandle(this)->getArrayData(),
                     Variant::PersistentArrInit{}};
    case APCKind::SerializedArray: {
      auto const serArr = APCString::fromHandle(this)->getStringData();
      return apc_unserialize(serArr->data(), serArr->size());
    }
    case APCKind::SharedArray:
    case APCKind::SharedPackedArray:
      return Variant::attach(
        APCLocalArray::Make(APCArray::fromHandle(this))->asArrayData()
      );
    case APCKind::SerializedObject: {
      auto const serObj = APCString::fromHandle(this)->getStringData();
      return apc_unserialize(serObj->data(), serObj->size());
    }
    case APCKind::SharedCollection:
      return APCCollection::fromHandle(this)->createObject();
    case APCKind::SharedObject:
      return APCObject::MakeLocalObject(this);
  }
  not_reached();
}
Пример #2
0
static Variant HHVM_FUNCTION(bcmod, const String& left, const String& right) {
  bc_num first, second, result;
  bc_init_num(&first);
  bc_init_num(&second);
  bc_init_num(&result);
  SCOPE_EXIT {
    bc_free_num(&first);
    bc_free_num(&second);
    bc_free_num(&result);
  };
  php_str2num(&first, (char*)left.data());
  php_str2num(&second, (char*)right.data());
  if (bc_modulo(first, second, &result, 0) == -1) {
    raise_warning("Division by zero");
    return init_null();
  }
  String ret(bc_num2str(result), AttachString);
  return ret;
}
Пример #3
0
static Variant HHVM_FUNCTION(assert, const Variant& assertion) {
  if (!s_option_data->assertActive) return true;

  CallerFrame cf;
  Offset callerOffset;
  auto const fp = cf(&callerOffset);

  auto const passed = [&]() -> bool {
    if (assertion.isString()) {
      if (RuntimeOption::EvalAuthoritativeMode) {
        // We could support this with compile-time string literals,
        // but it's not yet implemented.
        throw NotSupportedException(__func__,
          "assert with strings argument in RepoAuthoritative mode");
      }
      return eval_for_assert(fp, assertion.toString()).toBoolean();
    }
    return assertion.toBoolean();
  }();
  if (passed) return true;

  if (!s_option_data->assertCallback.isNull()) {
    auto const unit = fp->m_func->unit();

    PackedArrayInit ai(3);
    ai.append(String(const_cast<StringData*>(unit->filepath())));
    ai.append(Variant(unit->getLineNumber(callerOffset)));
    ai.append(assertion.isString() ? assertion : empty_string_variant_ref);
    f_call_user_func(1, s_option_data->assertCallback, ai.toArray());
  }

  if (s_option_data->assertWarning) {
    auto const str = !assertion.isString()
      ? String("Assertion failed")
      : concat3("Assertion \"", assertion.toString(), "\" failed");
    raise_warning("%s", str.data());
  }
  if (s_option_data->assertBail) {
    throw Assertion();
  }

  return init_null();
}
Пример #4
0
  XDEBUG_NOTIMPLEMENTED

static Variant HHVM_FUNCTION(xdebug_stop_trace) {
  if (!XDEBUG_GLOBAL(ProfilerAttached)) {
    return false;
  }

  auto profiler = xdebug_profiler();
  if (!profiler->isTracing()) {
    return false;
  }

  // End with xdebug_stop_trace()
  profiler->endFrame(init_null().asTypedValue(), nullptr, false);
  auto filename = profiler->getTracingFilename();
  profiler->disableTracing();
  detach_xdebug_profiler_if_needed();
  return filename;
}
Пример #5
0
Variant HHVM_STATIC_METHOD(IntlChar, charName,
                           const Variant& arg, int64_t choice) {
  GETCP(arg, cp);

  UErrorCode error = U_ZERO_ERROR;
  int32_t buffer_len = u_charName(cp, (UCharNameChoice)choice,
                                  nullptr, 0, &error);

  String buffer(buffer_len, ReserveString);
  error = U_ZERO_ERROR;
  buffer_len = u_charName(cp, (UCharNameChoice)choice,
                          buffer.bufferSlice().ptr, buffer_len + 1, &error);
  if (U_FAILURE(error)) {
    s_intl_error->setError(error, "Failure getting character name");
    return init_null();
  }
  buffer.setSize(buffer_len);
  return buffer;
}
Пример #6
0
static Variant preg_replace_callback_array_impl(
  const Variant& patterns_and_callbacks,
  const Array& subjects,
  int limit,
  VRefParam count) {

  Array ret = Array::Create();
  auto key = 0;
  auto total_replacement_count = 0;
  for (ArrayIter s_iter(subjects); s_iter; ++s_iter) {
    assert(s_iter.second().isString());
    auto subj = s_iter.second();
    for (ArrayIter pc_iter(patterns_and_callbacks.toArray());
                           pc_iter; ++pc_iter) {
      Variant pattern(pc_iter.first());
      assert(pattern.isString());
      Variant callback(pc_iter.second());
      subj = HHVM_FN(preg_replace_callback)(pattern, callback, subj, limit,
                                            count);
      // If we got an error on the replacement, the subject will be null,
      // and then we will return null.
      if (subj.isNull()) {
        return init_null();
      }

      if (count.isReferenced()) {
        total_replacement_count += count.toInt64();
      }
    }
    ret.add(key++, subj);
  }

  // If count was passed in as an explicit reference, we will assign it to our
  // total replacement count; otherwise, count will just remained unassigned
  count.assignIfRef(total_replacement_count);

  // If there were no replacements (i.e., matches) return original subject(s)
  if (ret.empty()) {
    return subjects;
  }
  return ret;
}
Пример #7
0
Variant HHVM_FUNCTION(parse_url, const String& url,
                                 int64_t 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:
      raise_warning(
        "parse_url(): Invalid URL component identifier %" PRId64, component);
      return false;
    }
    return init_null();
  }

  ArrayInit ret(resource.port ? 8 : 7, ArrayInit::Map{});
  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.toVariant();
}
Пример #8
0
Variant c_XMLReader::string_func_string_arg(String value, xmlreader_read_one_char_t internal_function) {

  if (value.empty()) {
    raise_warning("Argument cannot be an empty string");
    return false;
  }

  char *retchar = NULL;
  if (m_ptr) {
    retchar = (char *)internal_function(m_ptr, (const unsigned char *)value.data());
  }

  if (retchar) {
    String ret((const char*)retchar, CopyString);
    xmlFree(retchar);
    return ret;
  } else {
    return init_null();
  }
}
Пример #9
0
Object APCObject::createObject() const {
  Object obj;

  const Class* klass;
  if (auto const c = m_cls.left()) {
    klass = c;
  } else {
    klass = Unit::loadClass(m_cls.right());
    if (!klass) {
      Logger::Error("APCObject::getObject(): Cannot find class %s",
                    m_cls.right()->data());
      return obj;
    }
  }
  obj = ObjectData::newInstance(const_cast<Class*>(klass));
  obj.get()->clearNoDestruct();

  auto prop = props();
  auto const propEnd = prop + m_propCount;
  for (; prop != propEnd; ++prop) {
    auto const key = prop->name;

    const Class* ctx = nullptr;
    if (prop->ctx.isNull()) {
      ctx = klass;
    } else {
      if (auto const cls = prop->ctx.left()) {
        ctx = cls;
      } else {
        ctx = Unit::lookupClass(prop->ctx.right());
        if (!ctx) continue;
      }
    }

    auto val = prop->val ? prop->val->toLocal() : init_null();
    obj->setProp(const_cast<Class*>(ctx), key, val.asTypedValue(), false);
  }

  obj->invokeWakeup();
  return obj;
}
Пример #10
0
static Variant xml_call_handler(const req::ptr<XmlParser>& parser,
                                const Variant& handler,
                                const Array& args) {
  if (parser && handler.toBoolean()) {
    Variant retval;
    if (handler.isString() && !name_contains_class(handler.toString())) {
      if (!parser->object.isObject()) {
        retval = invoke(handler.toString().c_str(), args, -1);
      } else {
        retval = parser->object.toObject()->
          o_invoke(handler.toString(), args);
      }
    } else if (is_callable(handler)) {
      vm_call_user_func(handler, args);
    } else {
      raise_warning("Handler is invalid");
    }
    return retval;
  }
  return init_null();
}
Пример #11
0
Variant c_XMLReader::t_getattributens(const String& name, const String& namespaceURI) {
  if (name.empty() || namespaceURI.empty()) {
    raise_warning("Attribute Name and Namespace URI cannot be empty");
    return false;
  }

  char *retchar = NULL;
  if (m_ptr) {
    retchar = (char *)xmlTextReaderGetAttributeNs(m_ptr,
                                                  (xmlChar *)name.data(),
                                                  (xmlChar *)namespaceURI.data());
  }

  if (retchar) {
    String ret((const char*)retchar, CopyString);
    xmlFree(retchar);
    return ret;
  } else {
    return init_null();
  }
}
Пример #12
0
static Variant HHVM_FUNCTION(bcdiv, const String& left, const String& right,
               int64_t scale /* = -1 */) {
  if (scale < 0) scale = BCG(bc_precision);
  bc_num first, second, result;
  bc_init_num(&first);
  bc_init_num(&second);
  bc_init_num(&result);
  SCOPE_EXIT {
    bc_free_num(&first);
    bc_free_num(&second);
    bc_free_num(&result);
  };
  php_str2num(&first, (char*)left.data());
  php_str2num(&second, (char*)right.data());
  if (bc_divide(first, second, &result, scale) == -1) {
    raise_warning("Division by zero");
    return init_null();
  }
  String ret(bc_num2str(result), AttachString);
  return ret;
}
Пример #13
0
Variant SSATmp::variantVal() const {
  switch (type().toDataType()) {
  case KindOfUninit:
  case KindOfNull:
    // Upon return both will converted to KindOfNull anyway.
    return init_null();
  case KindOfBoolean:
    return boolVal();
  case KindOfInt64:
    return intVal();
  case KindOfDouble:
    return dblVal();
  case KindOfString:
  case KindOfStaticString:
    return Variant(const_cast<StringData*>(strVal()));
  case KindOfArray:
    return const_cast<ArrayData*>(arrVal());
  default:
    always_assert(false);
  }
}
Пример #14
0
Variant SSATmp::getValVariant() const {
  switch (m_inst->typeParam().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);
  }
}
Пример #15
0
void XDebugServer::onRequestInit() {
  if (!XDEBUG_GLOBAL(RemoteEnable)) {
    return;
  }

  // TODO(#4489053) Enable this when debugger internals have been refactored
  // Need to turn on debugging regardless of the remote mode in order to
  // capture exceptions/errors
  // ThreadInfo *ti = ThreadInfo::s_threadInfo.getNoCheck();
  // ti->m_reqInjectionData.setDebugger(true);

  // Grab $_GET, $_COOKIE, and the transport
  const ArrayData* globals = get_global_variables()->asArrayData();
  Array get = globals->get(s_GET).toArray();
  Array cookie = globals->get(s_COOKIE).toArray();
  Transport* transport = g_context->getTransport();

  // Need to check $_GET[XDEBUG_SESSION_STOP]. If set, delete the session
  // cookie
  const Variant sess_stop_var = get[s_SESSION_STOP];
  if (!sess_stop_var.isNull()) {
    cookie.set(s_SESSION, init_null());
    if (transport != nullptr) {
      transport->setCookie(s_SESSION, empty_string());
    }
  }

  // Need to check $_GET[XDEBUG_SESSION_START]. If set, store the session
  // cookie with $_GET[XDEBUG_SESSION_START] as the value
  const Variant sess_start_var = get[s_SESSION_START];
  if (sess_start_var.isString()) {
    String sess_start = sess_start_var.toString();
    cookie.set(s_SESSION,  sess_start);
    if (transport != nullptr) {
      transport->setCookie(s_SESSION,
                           sess_start,
                           XDEBUG_GLOBAL(RemoteCookieExpireTime));
    }
  }
}
Пример #16
0
Variant HHVM_METHOD(SQLite3, querysingle,
                    const String& sql,
                    bool entire_row /* = false */) {
  auto *data = Native::data<SQLite3>(this_);
  SYNC_VM_REGS_SCOPED();
  data->validate();
  if (!sql.empty()) {
    Variant stmt = HHVM_MN(SQLite3, prepare)(this_, sql);
    if (!same(stmt, false)) {
      Object obj_stmt = stmt.toObject();
      assert(obj_stmt.instanceof(SQLite3Stmt::getClass()));
      sqlite3_stmt *pstmt =
        Native::data<SQLite3Stmt>(obj_stmt)->m_raw_stmt;
      switch (sqlite3_step(pstmt)) {
      case SQLITE_ROW: /* Valid Row */
        if (entire_row) {
          Array ret = Array::Create();
          for (int i = 0; i < sqlite3_data_count(pstmt); i++) {
            ret.set(String((char*)sqlite3_column_name(pstmt, i), CopyString),
                    get_column_value(pstmt, i));
          }
          return ret;
        }
        return get_column_value(pstmt, 0);
      case SQLITE_DONE: /* Valid but no results */
        if (entire_row) {
          return empty_array();
        } else {
          return init_null();
        }
      default:
        raise_warning("Unable to execute statement: %s",
                      sqlite3_errmsg(data->m_raw_db));
      }
    }
  }
  return false;
}
Пример #17
0
Variant ArrayUtil::RandomKeys(const Array& input, int num_req /* = 1 */) {
  int count = input.size();
  if (num_req <= 0 || num_req > count) {
    raise_warning("Second argument has to be between 1 and the "
                  "number of elements in the array");
    return init_null();
  }

  if (num_req == 1) {
    // Iterating through the counter is correct but a bit inefficient
    // compared to being able to access the right offset into array data,
    // but necessary for this code to be agnostic to the array's internal
    // representation.  Assuming uniform distribution, we'll expect to
    // iterate through half of the array's data.
    ssize_t index = f_rand(0, count-1);
    ssize_t pos = input->iter_begin();
    while (index--) {
      pos = input->iter_advance(pos);
    }
    return input->getKey(pos);
  }

  std::vector<ssize_t> indices;
  indices.reserve(count);
  auto pos_limit = input->iter_end();
  for (ssize_t pos = input->iter_begin(); pos != pos_limit;
       pos = input->iter_advance(pos)) {
    indices.push_back(pos);
  }
  php_array_data_shuffle(indices);

  PackedArrayInit ret(num_req);
  for (int i = 0; i < num_req; i++) {
    ssize_t pos = indices[i];
    ret.append(input->getKey(pos));
  }
  return ret.toVariant();
}
Пример #18
0
static Variant xml_call_handler(XmlParser *parser, const Variant& handler,
                                const Array& args) {
  if (parser && handler.toBoolean()) {
    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.toCArrRef()[0].isString() ||
                handler.toCArrRef()[0].isObject()) &&
               handler.toCArrRef()[1].isString()) {
      vm_call_user_func(handler, args);
    } else {
      raise_warning("Handler is invalid");
    }
    return retval;
  }
  return init_null();
}
Пример #19
0
static Variant dynamic_to_variant(const folly::dynamic& v) {
  switch (v.type()) {
    case folly::dynamic::Type::NULLT:
      return init_null();
    case folly::dynamic::Type::BOOL:
      return v.asBool();
    case folly::dynamic::Type::DOUBLE:
      return v.asDouble();
    case folly::dynamic::Type::INT64:
      return v.asInt();
    case folly::dynamic::Type::STRING:
      return v.data();
    case folly::dynamic::Type::ARRAY:
    case folly::dynamic::Type::OBJECT:
      ArrayInit ret(v.size(), ArrayInit::Mixed{});
      for (auto& item : v.items()) {
        ret.add(dynamic_to_variant(item.first),
                dynamic_to_variant(item.second));
      }
      return ret.toArray();
  }
  not_reached();
}
Пример #20
0
Variant HHVM_FUNCTION(php_uname, const String& mode /*="" */) {
  struct utsname buf;
  if (uname((struct utsname *)&buf) == -1) {
    return init_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);
  }
}
Пример #21
0
Variant c_Closure::t___unset(Variant name) {
  raise_recoverable_error("Closure object cannot have properties");
  return init_null();
}
Пример #22
0
static const Variant get_breakpoint_message(const BreakInfo& bi) {
  // In php5 xdebug, only messages have a string. But this could be extended to
  // be more useful.
  return type == BreakType::EXCEPTION ?
    Variant(bi.message->data()) : init_null();
}
Пример #23
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) {
    }
  }
}
Пример #24
0
Variant binary_deserialize(int8_t thrift_typeID, PHPInputTransport& transport,
                           const Array& fieldspec) {
  Variant ret;
  switch (thrift_typeID) {
    case T_STOP:
    case T_VOID:
      return init_null();
    case T_STRUCT: {
      Variant val;
      if ((val = fieldspec.rvalAt(PHPTransport::s_class)).isNull()) {
        throw_tprotocolexception("no class type in spec", INVALID_DATA);
        skip_element(T_STRUCT, transport);
        return init_null();
      }
      String structType = val.toString();
      ret = createObject(structType);
      if (ret.isNull()) {
        // unable to create class entry
        skip_element(T_STRUCT, transport);
        return init_null();
      }
      Variant spec = HHVM_FN(hphp_get_static_property)(structType, s_TSPEC,
                                                                   false);
      if (!spec.is(KindOfArray)) {
        char errbuf[128];
        snprintf(errbuf, 128, "spec for %s is wrong type: %d\n",
                 structType.data(), ret.getType());
        throw_tprotocolexception(String(errbuf, CopyString), INVALID_DATA);
        return init_null();
      }
      binary_deserialize_spec(ret.toObject(), transport, spec.toArray());
      return ret;
    } break;
    case T_BOOL: {
      uint8_t c;
      transport.readBytes(&c, 1);
      return c != 0;
    }
  //case T_I08: // same numeric value as T_BYTE
    case T_BYTE: {
      uint8_t c;
      transport.readBytes(&c, 1);
      return Variant((int8_t)c);
    }
    case T_I16: {
      uint16_t c;
      transport.readBytes(&c, 2);
      return Variant((int16_t)ntohs(c));
    }
    case T_I32: {
      uint32_t c;
      transport.readBytes(&c, 4);
      return Variant((int32_t)ntohl(c));
    }
    case T_U64:
    case T_I64: {
      uint64_t c;
      transport.readBytes(&c, 8);
      return Variant((int64_t)ntohll(c));
    }
    case T_DOUBLE: {
      union {
        uint64_t c;
        double d;
      } a;
      transport.readBytes(&(a.c), 8);
      a.c = ntohll(a.c);
      return a.d;
    }
    case T_FLOAT: {
      union {
        uint32_t c;
        float d;
      } a;
      transport.readBytes(&(a.c), 4);
      a.c = ntohl(a.c);
      return a.d;
    }
    //case T_UTF7: // aliases T_STRING
    case T_UTF8:
    case T_UTF16:
    case T_STRING: {
      uint32_t size = transport.readU32();
      if (size && (size + 1)) {
        String s = String(size, ReserveString);
        char* strbuf = s.mutableData();
        transport.readBytes(strbuf, size);
        s.setSize(size);
        return s;
      } else {
        return empty_string_variant();
      }
    }
    case T_MAP: { // array of key -> value
      uint8_t types[2];
      transport.readBytes(types, 2);
      uint32_t size = transport.readU32();

      Array keyspec = fieldspec.rvalAt(PHPTransport::s_key,
                                       AccessFlags::Error_Key).toArray();
      Array valspec = fieldspec.rvalAt(PHPTransport::s_val,
                                       AccessFlags::Error_Key).toArray();
      String format = fieldspec.rvalAt(PHPTransport::s_format,
                                       AccessFlags::None).toString();
      if (format.equal(PHPTransport::s_collection)) {
        ret = newobj<c_Map>();
        for (uint32_t s = 0; s < size; ++s) {
          Variant key = binary_deserialize(types[0], transport, keyspec);
          Variant value = binary_deserialize(types[1], transport, valspec);
          collectionSet(ret.getObjectData(), key.asCell(), value.asCell());
        }
      } else {
        ret = Array::Create();
        for (uint32_t s = 0; s < size; ++s) {
          Variant key = binary_deserialize(types[0], transport, keyspec);
          Variant value = binary_deserialize(types[1], transport, valspec);
          ret.toArrRef().set(key, value);
        }
      }
      return ret; // return_value already populated
    }
    case T_LIST: { // array with autogenerated numeric keys
      int8_t type = transport.readI8();
      uint32_t size = transport.readU32();
      Variant elemvar = fieldspec.rvalAt(PHPTransport::s_elem,
                                         AccessFlags::Error_Key);
      Array elemspec = elemvar.toArray();
      String format = fieldspec.rvalAt(PHPTransport::s_format,
                                       AccessFlags::None).toString();

      if (format.equal(PHPTransport::s_collection)) {
        auto const pvec = newobj<c_Vector>();
        ret = pvec;
        for (uint32_t s = 0; s < size; ++s) {
          Variant value = binary_deserialize(type, transport, elemspec);
          pvec->t_add(value);
        }
      } else {
        PackedArrayInit pai(size);
        for (auto s = uint32_t{0}; s < size; ++s) {
          pai.append(binary_deserialize(type, transport, elemspec));
        }
        ret = pai.toArray();
      }

      return ret;
    }
    case T_SET: { // array of key -> TRUE
      uint8_t type;
      uint32_t size;
      transport.readBytes(&type, 1);
      transport.readBytes(&size, 4);
      size = ntohl(size);
      Variant elemvar = fieldspec.rvalAt(PHPTransport::s_elem,
                                         AccessFlags::Error_Key);
      Array elemspec = elemvar.toArray();
      String format = fieldspec.rvalAt(PHPTransport::s_format,
                                       AccessFlags::None).toString();
      if (format.equal(PHPTransport::s_collection)) {
        auto set_ret = makeSmartPtr<c_Set>();

        for (uint32_t s = 0; s < size; ++s) {
          Variant key = binary_deserialize(type, transport, elemspec);

          if (key.isInteger()) {
            set_ret->t_add(key);
          } else {
            set_ret->t_add(key.toString());
          }
        }

        ret = Variant(std::move(set_ret));
      } else {
        ArrayInit init(size, ArrayInit::Mixed{});
        for (uint32_t s = 0; s < size; ++s) {
          Variant key = binary_deserialize(type, transport, elemspec);
          if (key.isInteger()) {
            init.set(key, true);
          } else {
            init.setKeyUnconverted(key, true);
          }
        }
        ret = init.toArray();
      }
      return ret;
    }
  };

  char errbuf[128];
  sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID);
  throw_tprotocolexception(String(errbuf, CopyString), INVALID_DATA);
  return init_null();
}
Пример #25
0
Variant HHVM_FUNCTION(php_uname, const String& mode /*="" */) {
#ifdef _WIN32
  if (mode == s_s) {
    return s_Windows_NT;
  } else if (mode == s_r) {
    DWORD dwVersion = GetVersion();
    DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
    DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
    return folly::sformat("{}.{}", dwMajorVersion, dwMinorVersion);
  } else if (mode == s_n) {
    DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
    char ComputerName[MAX_COMPUTERNAME_LENGTH + 1];

    GetComputerName(ComputerName, &dwSize);
    return String(ComputerName, dwSize, CopyString);
  } else if (mode == s_v) {
    DWORD dwVersion = GetVersion();
    auto dwBuild = (DWORD)(HIWORD(dwVersion));
    auto winVer = php_get_windows_name();
    if (!winVer.hasValue()) {
      return folly::sformat("build {}", dwBuild);
    }
    return folly::sformat("build {} ({})", dwBuild, winVer.value());
  } else if (mode == s_m) {
    return php_get_windows_cpu();
  } else {
    auto winVer = php_get_windows_name();

    DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
    char ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
    GetComputerName(ComputerName, &dwSize);

    DWORD dwVersion = GetVersion();
    DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
    DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
    DWORD dwBuild = (DWORD)(HIWORD(dwVersion));

    if (dwMajorVersion == 6 && dwMinorVersion == 2 && winVer.hasValue()) {
      if (strncmp(winVer.value().c_str(), "Windows 8.1", 11) == 0 ||
          strncmp(winVer.value().c_str(), "Windows Server 2012 R2", 22) == 0) {
        dwMinorVersion = 3;
      }
    }

    return folly::sformat("Windows NT {} {}.{} build {} ({}) {}",
      ComputerName,
      dwMajorVersion,
      dwMinorVersion,
      dwBuild,
      winVer.hasValue() ? winVer.value().c_str() : "unknown",
      php_get_windows_cpu()
    );
  }
#else
  struct utsname buf;
  if (uname((struct utsname *)&buf) == -1) {
    return init_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);
  }
#endif
}
Пример #26
0
Variant c_Closure::t___set(Variant member, Variant value) {
  raise_recoverable_error("Closure object cannot have properties");
  return init_null();
}
Пример #27
0
static Variant get_breakpoint_message(const BreakInfo& bi) {
  if (auto eb = boost::get<ExnBreak>(&bi)) return VarNR(eb->message);
  return init_null();
}
Пример #28
0
Variant APCHandle::toLocal() const {
  switch (m_kind) {
    case APCKind::Uninit:
    case APCKind::Null:
      return init_null(); // shortcut.. no point to forward
    case APCKind::Bool:
      return APCTypedValue::fromHandle(this)->getBoolean();
    case APCKind::Int:
      return APCTypedValue::fromHandle(this)->getInt64();
    case APCKind::Double:
      return APCTypedValue::fromHandle(this)->getDouble();
    case APCKind::StaticString:
    case APCKind::UncountedString:
      return Variant{APCTypedValue::fromHandle(this)->getStringData(),
                     Variant::PersistentStrInit{}};
    case APCKind::SharedString:
      return Variant::attach(
        StringData::MakeProxy(APCString::fromHandle(this))
      );
    case APCKind::StaticArray:
    case APCKind::UncountedArray:
      return Variant{APCTypedValue::fromHandle(this)->getArrayData(),
                     KindOfPersistentArray,
                     Variant::PersistentArrInit{}};
    case APCKind::StaticVec:
    case APCKind::UncountedVec:
      return Variant{APCTypedValue::fromHandle(this)->getVecData(),
                     KindOfPersistentVec,
                     Variant::PersistentArrInit{}};
    case APCKind::StaticDict:
    case APCKind::UncountedDict:
      return Variant{APCTypedValue::fromHandle(this)->getDictData(),
                     KindOfPersistentDict,
                     Variant::PersistentArrInit{}};
    case APCKind::StaticKeyset:
    case APCKind::UncountedKeyset:
      return Variant{APCTypedValue::fromHandle(this)->getKeysetData(),
                     KindOfPersistentKeyset,
                     Variant::PersistentArrInit{}};
    case APCKind::SerializedArray: {
      auto const serArr = APCString::fromHandle(this)->getStringData();
      auto const v = apc_unserialize(serArr->data(), serArr->size());
      assert(v.isPHPArray());
      return v;
    }
    case APCKind::SerializedVec: {
      auto const serVec = APCString::fromHandle(this)->getStringData();
      auto const v = apc_unserialize(serVec->data(), serVec->size());
      assert(v.isVecArray());
      return v;
    }
    case APCKind::SerializedDict: {
      auto const serDict = APCString::fromHandle(this)->getStringData();
      auto const v = apc_unserialize(serDict->data(), serDict->size());
      assert(v.isDict());
      return v;
    }
    case APCKind::SerializedKeyset: {
      auto const serKeyset = APCString::fromHandle(this)->getStringData();
      auto const v = apc_unserialize(serKeyset->data(), serKeyset->size());
      assert(v.isKeyset());
      return v;
    }
    case APCKind::SharedArray:
    case APCKind::SharedPackedArray:
      return Variant::attach(
        APCLocalArray::Make(APCArray::fromHandle(this))->asArrayData()
      );
    case APCKind::SharedVec:
      return Variant::attach(
        APCArray::fromHandle(this)->toLocalVec()
      );
    case APCKind::SharedDict:
      return Variant::attach(
        APCArray::fromHandle(this)->toLocalDict()
      );
    case APCKind::SharedKeyset:
      return Variant::attach(
        APCArray::fromHandle(this)->toLocalKeyset()
      );
    case APCKind::SerializedObject: {
      auto const serObj = APCString::fromHandle(this)->getStringData();
      return apc_unserialize(serObj->data(), serObj->size());
    }
    case APCKind::SharedCollection:
      return APCCollection::fromHandle(this)->createObject();
    case APCKind::SharedObject:
      return APCObject::MakeLocalObject(this);
  }
  not_reached();
}
Пример #29
0
Variant MySQLResult::getField(int64_t field) const {
  if (!m_localized || field < 0 || field >= (int64_t)m_current_row->size()) {
    return init_null();
  }
  return (*m_current_row)[field];
}
Пример #30
0
/* SOAP client calls this function to parse response from SOAP server */
bool parse_packet_soap(SoapClient *obj, const char *buffer,
                       int buffer_size,
                       std::shared_ptr<sdlFunction> fn, const char *fn_name,
                       Variant &return_value, Array& soap_headers) {
  char* envelope_ns = nullptr;
  xmlNodePtr trav, env, head, body, resp, cur, fault;
  xmlAttrPtr attr;
  int param_count = 0;
  int soap_version = SOAP_1_1;
  sdlSoapBindingFunctionHeaderMap *hdrs = nullptr;

  assert(return_value.asTypedValue()->m_type == KindOfUninit);
  return_value.asTypedValue()->m_type = KindOfNull;

  /* Response for one-way opearation */
  if (buffer_size == 0) {
    return true;
  }

  /* Parse XML packet */
  xmlDocPtr response = soap_xmlParseMemory(buffer, buffer_size);
  if (!response) {
    add_soap_fault(obj, "Client", "looks like we got no XML document");
    return false;
  }
  if (xmlGetIntSubset(response) != nullptr) {
    add_soap_fault(obj, "Client", "DTD are not supported by SOAP");
    xmlFreeDoc(response);
    return false;
  }

  /* Get <Envelope> element */
  env = nullptr;
  trav = response->children;
  while (trav != nullptr) {
    if (trav->type == XML_ELEMENT_NODE) {
      if (!env && node_is_equal_ex(trav,"Envelope", SOAP_1_1_ENV_NAMESPACE)) {
        env = trav;
        envelope_ns = SOAP_1_1_ENV_NAMESPACE;
        soap_version = SOAP_1_1;
      } else if (!env &&
                 node_is_equal_ex(trav, "Envelope", SOAP_1_2_ENV_NAMESPACE)) {
        env = trav;
        envelope_ns = SOAP_1_2_ENV_NAMESPACE;
        soap_version = SOAP_1_2;
      } else {
        add_soap_fault(obj, "VersionMismatch", "Wrong Version");
        xmlFreeDoc(response);
        return false;
      }
    }
    trav = trav->next;
  }
  if (env == nullptr) {
    add_soap_fault(obj, "Client",
                   "looks like we got XML without \"Envelope\" element");
    xmlFreeDoc(response);
    return false;
  }

  attr = env->properties;
  while (attr != nullptr) {
    if (attr->ns == nullptr) {
      add_soap_fault(obj, "Client",
                     "A SOAP Envelope element cannot have non Namespace "
                     "qualified attributes");
      xmlFreeDoc(response);
      return false;
    }
    if (attr_is_equal_ex(attr, "encodingStyle", SOAP_1_2_ENV_NAMESPACE)) {
      if (soap_version == SOAP_1_2) {
        add_soap_fault(obj, "Client",
                       "encodingStyle cannot be specified on the Envelope");
        xmlFreeDoc(response);
        return false;
      }
      if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE)) {
        add_soap_fault(obj, "Client", "Unknown data encoding style");
        xmlFreeDoc(response);
        return false;
      }
    }
    attr = attr->next;
  }

  /* Get <Header> element */
  head = nullptr;
  trav = env->children;
  while (trav != nullptr && trav->type != XML_ELEMENT_NODE) {
    trav = trav->next;
  }
  if (trav != nullptr && node_is_equal_ex(trav,"Header",envelope_ns)) {
    head = trav;
    trav = trav->next;
  }

  /* Get <Body> element */
  body = nullptr;
  while (trav != nullptr && trav->type != XML_ELEMENT_NODE) {
    trav = trav->next;
  }
  if (trav != nullptr && node_is_equal_ex(trav,"Body",envelope_ns)) {
    body = trav;
    trav = trav->next;
  }
  while (trav != nullptr && trav->type != XML_ELEMENT_NODE) {
    trav = trav->next;
  }
  if (body == nullptr) {
    add_soap_fault(obj, "Client", "Body must be present in a SOAP envelope");
    xmlFreeDoc(response);
    return false;
  }
  attr = body->properties;
  while (attr != nullptr) {
    if (attr->ns == nullptr) {
      if (soap_version == SOAP_1_2) {
        add_soap_fault(obj, "Client",
                       "A SOAP Body element cannot have non Namespace "
                       "qualified attributes");
        xmlFreeDoc(response);
        return false;
      }
    } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
      if (soap_version == SOAP_1_2) {
        add_soap_fault(obj, "Client",
                       "encodingStyle cannot be specified on the Body");
        xmlFreeDoc(response);
        return false;
      }
      if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE)) {
        add_soap_fault(obj, "Client", "Unknown data encoding style");
        xmlFreeDoc(response);
        return false;
      }
    }
    attr = attr->next;
  }
  if (trav != nullptr && soap_version == SOAP_1_2) {
    add_soap_fault(obj, "Client",
                   "A SOAP 1.2 envelope can contain only Header and Body");
    xmlFreeDoc(response);
    return false;
  }

  if (head != nullptr) {
    attr = head->properties;
    while (attr != nullptr) {
      if (attr->ns == nullptr) {
        add_soap_fault(obj, "Client",
                       "A SOAP Header element cannot have non Namespace "
                       "qualified attributes");
        xmlFreeDoc(response);
        return false;
      }
      if (attr_is_equal_ex(attr, "encodingStyle", SOAP_1_2_ENV_NAMESPACE)) {
        if (soap_version == SOAP_1_2) {
          add_soap_fault(obj, "Client",
                         "encodingStyle cannot be specified on the Header");
          xmlFreeDoc(response);
          return false;
        }
        if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE)) {
          add_soap_fault(obj, "Client", "Unknown data encoding style");
          xmlFreeDoc(response);
          return false;
        }
      }
      attr = attr->next;
    }
  }

  /* Check if <Body> contains <Fault> element */
  fault = get_node_ex(body->children,"Fault",envelope_ns);
  if (fault != nullptr) {
    char *faultcode = nullptr;
    String faultstring, faultactor;
    Variant details;
    xmlNodePtr tmp;

    if (soap_version == SOAP_1_1) {
      tmp = get_node(fault->children, "faultcode");
      if (tmp != nullptr && tmp->children != nullptr) {
        faultcode = (char*)tmp->children->content;
      }

      tmp = get_node(fault->children, "faultstring");
      if (tmp != nullptr && tmp->children != nullptr) {
        Variant zv = master_to_zval(get_conversion(KindOfString), tmp);
        faultstring = zv.toString();
      }

      tmp = get_node(fault->children, "faultactor");
      if (tmp != nullptr && tmp->children != nullptr) {
        Variant zv = master_to_zval(get_conversion(KindOfString), tmp);
        faultactor = zv.toString();
      }

      tmp = get_node(fault->children, "detail");
      if (tmp != nullptr) {
        details = master_to_zval(encodePtr(), tmp);
      }
    } else {
      tmp = get_node(fault->children, "Code");
      if (tmp != nullptr && tmp->children != nullptr) {
        tmp = get_node(tmp->children, "Value");
        if (tmp != nullptr && tmp->children != nullptr) {
          faultcode = (char*)tmp->children->content;
        }
      }

      tmp = get_node(fault->children,"Reason");
      if (tmp != nullptr && tmp->children != nullptr) {
        /* TODO: lang attribute */
        tmp = get_node(tmp->children,"Text");
        if (tmp != nullptr && tmp->children != nullptr) {
          Variant zv = master_to_zval(get_conversion(KindOfString), tmp);
          faultstring = zv.toString();
        }
      }

      tmp = get_node(fault->children,"Detail");
      if (tmp != nullptr) {
        details = master_to_zval(encodePtr(), tmp);
      }
    }
    obj->m_soap_fault =
        SystemLib::AllocSoapFaultObject(String(faultcode, CopyString),
                                        faultstring,
                                        faultactor,
                                        details);
    xmlFreeDoc(response);
    return false;
  }

  /* Parse content of <Body> element */
  return_value = Array::Create();
  resp = body->children;
  while (resp != nullptr && resp->type != XML_ELEMENT_NODE) {
    resp = resp->next;
  }
  if (resp != nullptr) {
    if (fn && fn->binding && fn->binding->bindingType == BINDING_SOAP) {
      /* Function has WSDL description */
      sdlParamPtr h_param, param;
      xmlNodePtr val = nullptr;
      const char *name, *ns = nullptr;
      Variant tmp(Variant::NullInit{});
      sdlSoapBindingFunctionPtr fnb =
        (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
      int res_count;

      hdrs = &fnb->output.headers;

      if (!fn->responseParameters.empty()) {
        res_count = fn->responseParameters.size();
        for (unsigned int i = 0; i < fn->responseParameters.size(); i++) {
          h_param = fn->responseParameters[i];
          param = h_param;
          if (fnb->style == SOAP_DOCUMENT) {
            if (param->element) {
              name = param->element->name.c_str();
              ns = param->element->namens.c_str();
/*
              name = param->encode->details.type_str;
              ns = param->encode->details.ns;
*/
            } else {
              name = param->paramName.c_str();
            }
          } else {
            name = fn->responseName.c_str();
            /* ns = ? */
          }

          /* Get value of parameter */
          cur = get_node_ex(resp, (char*)name, (char*)ns);
          if (!cur) {
            cur = get_node(resp, (char*)name);
            /* TODO: produce warning invalid ns */
          }
          if (!cur && fnb->style == SOAP_RPC) {
            cur = resp;
          }
          if (cur) {
            if (fnb->style == SOAP_DOCUMENT) {
              val = cur;
            } else {
              val = get_node(cur->children, (char*)param->paramName.c_str());
              if (res_count == 1) {
                if (val == nullptr) {
                  val = get_node(cur->children, "return");
                }
                if (val == nullptr) {
                  val = get_node(cur->children, "result");
                }
                if (val == nullptr && cur->children && !cur->children->next) {
                  val = cur->children;
                }
              }
            }
          }

          if (!val) {
            /* TODO: may be "nil" is not OK? */
/*
            add_soap_fault(obj, "Client", "Can't find response data");
            xmlFreeDoc(response);
            return false;
*/
          } else {
            /* Decoding value of parameter */
            if (param != nullptr) {
              tmp = master_to_zval(param->encode, val);
            } else {
              tmp = master_to_zval(encodePtr(), val);
            }
          }
          return_value.toArrRef().set(String(param->paramName), tmp);
          param_count++;
        }
      }
    } else {
      /* Function hasn't WSDL description */
      xmlNodePtr val;
      val = resp->children;
      while (val != nullptr) {
        while (val && val->type != XML_ELEMENT_NODE) {
          val = val->next;
        }
        if (val != nullptr) {
          if (!node_is_equal_ex(val,"result",RPC_SOAP12_NAMESPACE)) {
            Variant tmp = master_to_zval(encodePtr(), val);
            if (val->name) {
              String key((char*)val->name, CopyString);
              if (return_value.toCArrRef().exists(key)) {
                auto& lval = return_value.toArrRef().lvalAt(key);
                if (!lval.isArray()) lval = lval.toArray();
                lval.toArrRef().append(tmp);
              } else if (val->next && get_node(val->next, (char*)val->name)) {
                Array arr = Array::Create();
                arr.append(tmp);
                return_value.toArrRef().set(key, arr);
              } else {
                return_value.toArrRef().set(key, tmp);
              }
            } else {
              return_value.toArrRef().append(tmp);
            }
            ++param_count;
          }
          val = val->next;
        }
      }
    }
  }

  if (return_value.isArray()) {
    if (param_count == 0) {
      return_value = init_null();
    } else if (param_count == 1) {
      Array arr = return_value.toArray();
      ArrayIter iter(arr);
      return_value = iter.second();
    }
  }

  if (head) {
    trav = head->children;
    while (trav) {
      if (trav->type == XML_ELEMENT_NODE) {
        encodePtr enc;
        if (hdrs && !hdrs->empty()) {
          std::string key;
          if (trav->ns) {
            key += (char*)trav->ns->href;
            key += ':';
          }
          key += (char*)trav->name;
          sdlSoapBindingFunctionHeaderMap::const_iterator iter =
            hdrs->find(key);
          if (iter != hdrs->end()) {
            enc = iter->second->encode;
          }
        }
        soap_headers.set(String((char*)trav->name, CopyString),
                         master_to_zval(enc, trav));
      }
      trav = trav->next;
    }
  }

  xmlFreeDoc(response);
  return true;
}