Beispiel #1
0
Variant f_class_uses(CVarRef obj, bool autoload /* = true */) {
  String clsname;
  if (obj.isString()) {
    clsname = obj.toString();
  } else if (obj.isObject()) {
    clsname = obj.toObject()->o_getClassName();
  } else {
    return false;
  }

  const ClassInfo *info = ClassInfo::FindClassInterfaceOrTrait(clsname);
  if (!info) {
    if (!autoload) return false;
    AutoloadHandler::s_instance->invokeHandler(clsname);
    return f_class_uses(clsname, false);
  }

  Array ret(Array::Create());
  const ClassInfo::TraitVec &traits = info->getTraitsVec();
  for (unsigned int i = 0; i < traits.size(); i++) {
    ret.set(traits[i], traits[i]);
  }

  return ret;
}
Beispiel #2
0
bool ArrayData::hasInternalReference(PointerSet &vars) const {
  if (supportValueRef()) {
    for (ArrayIter iter(this); iter; ++iter) {
      CVarRef var = iter.secondRef();
      if (var.isReferenced()) {
        Variant *pvar = var.getVariantData();
        if (vars.find(pvar) != vars.end()) {
          return true;
        }
        vars.insert(pvar);
      }
      if (var.isObject()) {
        ObjectData *pobj = var.getObjectData();
        if (vars.find(pobj) != vars.end()) {
          return true;
        }
        vars.insert(pobj);

        if (pobj->o_toArray().get()->hasInternalReference(vars)) {
          return true;
        }
      } else if (var.isArray() &&
                 var.getArrayData()->hasInternalReference(vars)) {
        return true;
      }
    }
  }
  return false;
}
Beispiel #3
0
bool ArrayData::hasInternalReference(PointerSet &vars,
                                     bool ds /* = false */) const {
  if (isSharedMap()) return false;
  for (ArrayIter iter(this); iter; ++iter) {
    CVarRef var = iter.secondRef();
    if (var.isReferenced()) {
      Variant *pvar = var.getRefData();
      if (vars.find(pvar) != vars.end()) {
        return true;
      }
      vars.insert(pvar);
    }
    if (var.isObject()) {
      ObjectData *pobj = var.getObjectData();
      if (vars.find(pobj) != vars.end()) {
        return true;
      }
      vars.insert(pobj);
      if (ds && pobj->o_instanceof("Serializable")) {
        return true;
      }
      if (pobj->hasInternalReference(vars, ds)) {
        return true;
      }
    } else if (var.isArray() &&
               var.getArrayData()->hasInternalReference(vars, ds)) {
      return true;
    }
  }
  return false;
}
Beispiel #4
0
Variant f_get_object_vars(CVarRef object) {
  if (object.isObject()) {
    return object.toObject()->o_toIterArray(ctxClassName());
  }
  raise_warning("get_object_vars() expects parameter 1 to be object");
  return Variant(Variant::nullInit);
}
Beispiel #5
0
Object Certificate::Get(CVarRef var) {
  if (var.isResource()) {
    return var.toObject();
  }
  if (var.isString() || var.isObject()) {
    bool file;
    BIO *in = ReadData(var, &file);
    if (in == nullptr) return Object();

    X509 *cert;
    /*
    if (file) {
      cert = PEM_read_bio_X509(in, NULL, NULL, NULL);
    } else {
      cert = (X509 *)PEM_ASN1_read_bio
        ((char *(*)())d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL);
    }
    */
    cert = PEM_read_bio_X509(in, nullptr, nullptr, nullptr);
    BIO_free(in);
    if (cert) {
      return Object(new Certificate(cert));
    }
  }
  return Object();
}
Beispiel #6
0
Variant f_class_implements(CVarRef obj, bool autoload /* = true */) {
  String clsname;
  if (obj.isString()) {
    clsname = obj.toString();
  } else if (obj.isObject()) {
    clsname = obj.toObject()->o_getClassName();
  } else {
    return false;
  }

  const ClassInfo *info = ClassInfo::FindClassInterfaceOrTrait(clsname);
  if (info == NULL) {
    if (!autoload) return false;
    AutoloadHandler::s_instance->invokeHandler(clsname);
    return f_class_implements(clsname, false);
  }

  Array ret(Array::Create());
  ClassInfo::InterfaceVec ifs;
  info->getAllInterfacesVec(ifs);
  for (unsigned int i = 0; i < ifs.size(); i++) {
    ret.set(ifs[i], ifs[i]);
  }

  return ret;
}
Beispiel #7
0
Variant f_property_exists(CVarRef class_or_object, const String& property) {
  if (class_or_object.isObject()) {
    const String& context = ctxClassName();
    return (bool)class_or_object.toObject()->o_realProp(
      property, ObjectData::RealPropExist, context);
  }
  if (!class_or_object.isString()) {
    raise_warning(
      "First parameter must either be an object"
      " or the name of an existing class"
    );
    return Variant(Variant::NullInit());
  }

  Class* cls = Unit::lookupClass(get_classname(class_or_object).get());
  if (!cls) {
    return false;
  }
  bool accessible;
  auto propInd = cls->getDeclPropIndex(cls, property.get(), accessible);
  if (propInd != kInvalidSlot) {
    return true;
  }
  propInd = cls->lookupSProp(property.get());
  return (propInd != kInvalidSlot);
}
Beispiel #8
0
Variant f_get_parent_class(CVarRef object /* = null_variant */) {
  if (!object.isInitialized()) {
    CallerFrame cf;
    Class* cls = arGetContextClass(cf());
    if (cls && cls->parent()) {
      return String(cls->parentRef());
    }
    return false;
  }

  Variant class_name;
  if (object.isObject()) {
    class_name = f_get_class(object);
  } else if (object.isString()) {
    class_name = object;
  } else {
    return false;
  }

  const Class* cls = Unit::lookupClass(class_name.toString().get());
  if (cls) {
    auto& parentClass = *(const String*)(&cls->parentRef());
    if (!parentClass.empty()) {
      return parentClass;
    }
  }
  return false;
}
Variant f_hphp_invoke_method(CVarRef obj, CStrRef cls, CStrRef name,
                             CArrRef params) {
  if (!obj.isObject()) {
    return invoke_static_method(cls.data(), name.data(), params);
  }
  return obj.toObject()->o_invoke(name.data(), params, -1);
}
Beispiel #10
0
Variant f_get_parent_class(CVarRef object /* = null_variant */) {
  if (hhvm) {
    if (!object.isInitialized()) {
      CallerFrame cf;
      HPHP::VM::Class* cls = arGetContextClass(cf());
      if (cls && cls->parent()) {
        return CStrRef(cls->parentRef());
      }
      return false;
    }
  }
  Variant class_name;
  if (object.isObject()) {
    class_name = f_get_class(object);
  } else if (object.isString()) {
    class_name = object;
  } else {
    return false;
  }
  const ClassInfo *classInfo = ClassInfo::FindClass(class_name.toString());
  if (classInfo) {
    CStrRef parentClass = classInfo->getParentClass();
    if (!parentClass.empty()) {
      return parentClass;
    }
  }
  return false;
}
Beispiel #11
0
void f_var_dump(CVarRef v) {
  VariableSerializer vs(VariableSerializer::VarDump, 0, 2);
  // manipulate maxCount to match PHP behavior
  if (!v.isObject()) {
    vs.incMaxCount();
  }
  vs.serialize(v, false);
}
Variant f_hphp_invoke_method(CVarRef obj, CStrRef cls, CStrRef name,
                             CArrRef params) {
  if (!obj.isObject()) {
    return invoke_static_method(cls, name, params);
  }
  ObjectData *o = obj.toCObjRef().get();
  return o->o_invoke(name, params);
}
void VariableSerializer::write(CVarRef v, bool isArrayKey /* = false */) {
  if (!isArrayKey && v.isObject()) {
    write(v.toObject());
    return;
  }
  setReferenced(v.isReferenced());
  setRefCount(v.getRefCount());
  v.serialize(this, isArrayKey);
}
Beispiel #14
0
bool same(CVarRef v1, CObjRef v2) {
  bool null1 = v1.isNull();
  bool null2 = v2.isNull();
  if (null1 && null2) return true;
  if (null1 || null2) return false;
  if (!v1.isObject()) return false;
  auto const od = v1.getObjectData();
  return od == v2.get();
}
Beispiel #15
0
Variant invoke_failed(CVarRef func, CArrRef params,
                      bool fatal /* = true */) {
  if (func.isObject()) {
    return o_invoke_failed(
        func.objectForCall()->o_getClassName().c_str(),
        "__invoke", fatal);
  } else {
    return invoke_failed(func.toString().c_str(), params, fatal);
  }
}
Variant ObjectStringPropertyExpression::eval(VariableEnvironment &env) const {
  CVarRef obj = m_obj->eval(env);
  SET_LINE;
  if (!g_context->getDebuggerBypassCheck()) {
    return obj.o_get(m_name);
  }
  Variant v = obj.o_get(m_name, false);
  if (!v.isNull()) return v;
  CStrRef context = obj.isObject() ?
                    obj.getObjectData()->o_getClassName() :
                    null_string;
  return obj.o_get(m_name, false, context);
}
Beispiel #17
0
bool f_property_exists(CVarRef class_or_object, CStrRef property) {
  if (class_or_object.isObject()) {
    // Call o_exists for objects, to include dynamic properties.
    return class_or_object.toObject()->o_propExists(property);
  }
  const ClassInfo *classInfo =
    ClassInfo::FindClass(get_classname(class_or_object));
  while (classInfo) {
    if (classInfo->hasProperty(property)) {
      return true;
    } else {
      classInfo = classInfo->getParentClassInfo();
    }
  }
  return false;
}
static Variant collator_convert_object_to_string(CVarRef obj) {
  if (!obj.isObject()) return obj;
  String str;
  try {
    str = obj.toString();
  } catch (Exception &e) {
    return obj;
  }
  UErrorCode status;
  String ustr = intl_convert_str_utf8_to_utf16(str, &status);
  if (U_FAILURE(status)) {
    raise_warning("Error casting object to string in "
                  "collator_convert_object_to_string()");
    return uninit_null();
  }
  return ustr;
}
Beispiel #19
0
static Variant HHVM_STATIC_METHOD(IntlTimeZone, createEnumeration,
                                  CVarRef countryRawOffset) {
  icu::StringEnumeration *se = nullptr;

  if (countryRawOffset.isNull()) {
    se = icu::TimeZone::createEnumeration();
  } else if (countryRawOffset.isNumeric(true)) {
    se = icu::TimeZone::createEnumeration((int32_t)countryRawOffset.toInt64());
  } else if (countryRawOffset.isString() || countryRawOffset.isObject()) {
    se = icu::TimeZone::createEnumeration(countryRawOffset.toString().c_str());
  } else {
    s_intl_error->set(U_ILLEGAL_ARGUMENT_ERROR,
                      "intltz_create_enumeration: invalid argument type");
    return false;
  }
  return IntlIterator::newInstance(se);
}
Beispiel #20
0
Variant f_get_parent_class(CVarRef object /* = null_variant */) {
  Variant class_name;
  if (object.isObject()) {
    class_name = f_get_class(object);
  } else if (object.isString()) {
    class_name = object;
  } else {
    return false;
  }
  const ClassInfo *classInfo = ClassInfo::FindClass(class_name.toString());
  if (classInfo) {
    CStrRef parentClass = classInfo->getParentClass();
    if (!parentClass.empty()) {
      return parentClass;
    }
  }
  return false;
}
Beispiel #21
0
Variant f_class_uses(CVarRef obj, bool autoload /* = true */) {
    Class* cls;
    if (obj.isString()) {
        cls = Unit::getClass(obj.getStringData(), autoload);
        if (!cls) {
            return false;
        }
    } else if (obj.isObject()) {
        cls = obj.getObjectData()->getVMClass();
    } else {
        return false;
    }
    Array ret(Array::Create());
    for (auto const& traitName : cls->preClass()->usedTraits()) {
        const String& nameRef = *(String*)(&traitName);
        ret.set(nameRef, nameRef);
    }
    return ret;
}
Beispiel #22
0
Variant f_get_class(CVarRef object /* = null_variant */) {
  if (object.isNull()) {
    // No arg passed.
    String ret;
    CallerFrame cf;
    Class* cls = arGetContextClassImpl<true>(cf());
    if (cls) {
      ret = String(cls->nameRef());
    }

    if (ret.empty()) {
      raise_warning("get_class() called without object from outside a class");
      return false;
    }
    return ret;
  }
  if (!object.isObject()) return false;
  return object.toObject()->o_getClassName();
}
Beispiel #23
0
Variant f_class_parents(CVarRef obj, bool autoload /* = true */) {
  Class* cls;
  if (obj.isString()) {
    cls = Unit::getClass(obj.getStringData(), autoload);
    if (!cls) {
      return false;
    }
  } else if (obj.isObject()) {
    cls = obj.getObjectData()->getVMClass();
  } else {
    return false;
  }
  Array ret(Array::Create());
  for (cls = cls->parent(); cls; cls = cls->parent()) {
    auto& clsName = cls->nameRef();
    ret.set(clsName, clsName);
  }
  return ret;
}
Beispiel #24
0
Variant f_class_implements(CVarRef obj, bool autoload /* = true */) {
  Class* cls;
  if (obj.isString()) {
    cls = Unit::getClass(obj.getStringData(), autoload);
    if (!cls) {
      return false;
    }
  } else if (obj.isObject()) {
    cls = obj.getObjectData()->getVMClass();
  } else {
    return false;
  }
  Array ret(Array::Create());
  const Class::InterfaceMap& ifaces = cls->allInterfaces();
  for (int i = 0, size = ifaces.size(); i < size; i++) {
    ret.set(ifaces[i]->nameRef(), ifaces[i]->nameRef());
  }
  return ret;
}
Beispiel #25
0
Variant f_class_uses(CVarRef obj, bool autoload /* = true */) {
  Class* cls;
  if (obj.isString()) {
    cls = Unit::getClass(obj.getStringData(), autoload);
    if (!cls) {
      return false;
    }
  } else if (obj.isObject()) {
    cls = obj.getObjectData()->getVMClass();
  } else {
    return false;
  }
  Array ret(Array::Create());
  for (auto& elem : cls->usedTraits()) {
    auto& traitName = elem->nameRef();
    ret.set(traitName, traitName);
  }
  return ret;
}
Beispiel #26
0
bool ArrayData::hasInternalReference(PointerSet &vars,
                                     bool ds /* = false */) const {
    if (isSharedMap()) return false;
    for (ArrayIter iter(this); iter; ++iter) {
        CVarRef var = iter.secondRef();
        if (var.isReferenced()) {
            Variant *pvar = var.getVariantData();
            if (vars.find(pvar) != vars.end()) {
                return true;
            }
            vars.insert(pvar);
        }
        if (var.isObject()) {
            ObjectData *pobj = var.getObjectData();
            if (vars.find(pobj) != vars.end()) {
                return true;
            }
            vars.insert(pobj);
            if (pobj->o_instanceof("Serializable")) {
                if (ds) {
                    // We want to detect Serializable object as well
                    return true;
                } else {
                    // Serializable object does not have internal reference issue
                    return false;
                }
            }
            if (pobj->o_toArray().get()->hasInternalReference(vars, ds)) {
                return true;
            }
        } else if (var.isArray() &&
                   var.getArrayData()->hasInternalReference(vars, ds)) {
            return true;
        }
    }
    return false;
}
Beispiel #27
0
Variant f_class_parents(CVarRef obj, bool autoload /* = true */) {
  String clsname;
  if (obj.isString()) {
    clsname = obj.toString();
  } else if (obj.isObject()) {
    clsname = obj.toObject()->o_getClassName();
  } else {
    return false;
  }

  const ClassInfo *info = ClassInfo::FindClass(clsname);
  if (info == NULL) {
    return false;
  }

  Array ret(Array::Create());
  ClassInfo::ClassVec parents;
  info->getAllParentsVec(parents);
  for (unsigned int i = 0; i < parents.size(); i++) {
    ret.set(parents[i], parents[i]);
  }

  return ret;
}
Beispiel #28
0
bool BuiltinSymbols::Load(AnalysisResultPtr ar, bool extOnly /* = false */) {
    if (Loaded) return true;
    Loaded = true;

    // load extension functions first, so system/classes may call them
    ParseExtFunctions(ar, ExtensionFunctions, false);
    AnalysisResultPtr ar2 = AnalysisResultPtr(new AnalysisResult());
    s_variables = VariableTablePtr(new VariableTable(*ar2.get()));
    s_constants = ConstantTablePtr(new ConstantTable(*ar2.get()));

    // parse all PHP files under system/classes
    if (!extOnly) {
        ar = AnalysisResultPtr(new AnalysisResult());
        ar->loadBuiltinFunctions();
        string slib = systemlib_path();
        if (slib.empty()) {
            for (const char **cls = SystemClasses; *cls; cls++) {
                string phpBaseName = "/system/classes/";
                phpBaseName += *cls;
                phpBaseName += ".php";
                Parse(ar, phpBaseName, Option::GetSystemRoot() + phpBaseName);
            }
        } else {
            Parse(ar, slib, slib);
        }
        ar->analyzeProgram(true);
        ar->inferTypes();
        const StringToFileScopePtrMap &files = ar->getAllFiles();
        for (StringToFileScopePtrMap::const_iterator iterFile = files.begin();
                iterFile != files.end(); iterFile++) {
            const StringToClassScopePtrVecMap &classes =
                iterFile->second->getClasses();
            for (StringToClassScopePtrVecMap::const_iterator iter = classes.begin();
                    iter != classes.end(); ++iter) {
                assert(iter->second.size() == 1);
                iter->second[0]->setSystem();
                assert(!s_classes[iter->first]);
                s_classes[iter->first] = iter->second[0];
            }
        }
    } else {
        NoSuperGlobals = true;
    }

    // load extension constants, classes and dynamics
    ParseExtConsts(ar, ExtensionConsts, false);
    ParseExtClasses(ar, ExtensionClasses, false);
    for (unsigned int i = 0; i < Option::SepExtensions.size(); i++) {
        Option::SepExtensionOptions &options = Option::SepExtensions[i];
        string soname = options.soname;
        if (soname.empty()) {
            soname = string("lib") + options.name + ".so";
        }
        if (!options.lib_path.empty()) {
            soname = options.lib_path + "/" + soname;
        }
        if (!LoadSepExtensionSymbols(ar, options.name, soname)) {
            return false;
        }
    }

    if (!extOnly) {
        Array constants = ClassInfo::GetSystemConstants();
        LocationPtr loc(new Location);
        for (ArrayIter it = constants.begin(); it; ++it) {
            CVarRef key = it.first();
            if (!key.isString()) continue;
            std::string name = key.toCStrRef().data();
            if (s_constants->getSymbol(name)) continue;
            if (name == "true" || name == "false" || name == "null") continue;
            CVarRef value = it.secondRef();
            if (!value.isInitialized() || value.isObject()) continue;
            ExpressionPtr e = Expression::MakeScalarExpression(ar2, ar2, loc, value);
            TypePtr t =
                value.isNull()    ? Type::Null    :
                value.isBoolean() ? Type::Boolean :
                value.isInteger() ? Type::Int64   :
                value.isDouble()  ? Type::Double  :
                value.isArray()   ? Type::Array   : Type::Variant;

            s_constants->add(key.toCStrRef().data(), t, e, ar2, e);
        }
        s_variables = ar2->getVariables();
        for (int i = 0, n = NumGlobalNames(); i < n; ++i) {
            s_variables->add(GlobalNames[i], Type::Variant, false, ar,
                             ConstructPtr(), ModifierExpressionPtr());
        }
    }
    s_constants->setDynamic(ar, "SID", true);

    return true;
}
Beispiel #29
0
bool BuiltinSymbols::Load(AnalysisResultPtr ar) {
  if (Loaded) return true;
  Loaded = true;

  if (g_context.isNull()) init_thread_locals();
  ClassInfo::Load();

  // load extension functions first, so system/php may call them
  ImportExtFunctions(ar, ClassInfo::GetSystem());

  ConstantTablePtr cns = ar->getConstants();
  // load extension constants, classes and dynamics
  ImportNativeConstants(ar, cns);
  ImportExtConstants(ar, cns, ClassInfo::GetSystem());
  ImportExtClasses(ar);

  Array constants = ClassInfo::GetSystemConstants();
  LocationPtr loc(new Location);
  for (ArrayIter it = constants.begin(); it; ++it) {
    CVarRef key = it.first();
    if (!key.isString()) continue;
    std::string name = key.toCStrRef().data();
    if (cns->getSymbol(name)) continue;
    if (name == "true" || name == "false" || name == "null") continue;
    CVarRef value = it.secondRef();
    if (!value.isInitialized() || value.isObject()) continue;
    ExpressionPtr e = Expression::MakeScalarExpression(ar, ar, loc, value);
    TypePtr t =
      value.isNull()    ? Type::Null    :
      value.isBoolean() ? Type::Boolean :
      value.isInteger() ? Type::Int64   :
      value.isDouble()  ? Type::Double  :
      value.isArray()   ? Type::Array   : Type::Variant;

    cns->add(key.toCStrRef().data(), t, e, ar, e);
  }
  for (int i = 0, n = NumGlobalNames(); i < n; ++i) {
    ar->getVariables()->add(GlobalNames[i], Type::Variant, false, ar,
                            ConstructPtr(), ModifierExpressionPtr());
  }

  cns->setDynamic(ar, "PHP_BINARY", true);
  cns->setDynamic(ar, "PHP_BINDIR", true);
  cns->setDynamic(ar, "PHP_OS", true);
  cns->setDynamic(ar, "PHP_SAPI", true);
  cns->setDynamic(ar, "SID", true);

  // Systemlib files were all parsed by hphp_process_init

  const StringToFileScopePtrMap &files = ar->getAllFiles();
  for (const auto& file : files) {
    file.second->setSystem();

    const auto& classes = file.second->getClasses();
    for (const auto& clsVec : classes) {
      assert(clsVec.second.size() == 1);
      auto cls = clsVec.second[0];
      cls->setSystem();
      ar->addSystemClass(cls);
      for (const auto& func : cls->getFunctions()) {
        FunctionScope::RecordFunctionInfo(func.first, func.second);
      }
    }

    const auto& functions = file.second->getFunctions();
    for (const auto& func : functions) {
      func.second->setSystem();
      ar->addSystemFunction(func.second);
      FunctionScope::RecordFunctionInfo(func.first, func.second);
    }
  }

  return true;
}
Beispiel #30
0
Variant f_get_object_vars(CVarRef object) {
  if (object.isObject()) {
    return object.toObject()->o_toIterArray(FrameInjection::GetClassName(true));
  }
  return false;
}