예제 #1
0
static int collator_numeric_compare_function(CVarRef v1, CVarRef v2,
                                             const void *data,
                                             bool ascending) {
  Variant num1;
  Variant num2;

  if (v1.isString()) {
    num1 = collator_convert_string_to_double(v1);
  } else {
    num1 = v1.toDouble();
  }
  if (v2.isString()) {
    num2 = collator_convert_string_to_double(v2);
  } else {
    num2 = v2.toDouble();
  }
  if (ascending) {
    if (num1.less(num2)) return -1;
    if (num1.equal(num2)) return 0;
    return 1;
  }
  if (num1.less(num2)) return 1;
  if (num1.equal(num2)) return 0;
  return -1;
}
예제 #2
0
static int collator_string_compare_function(CVarRef v1, CVarRef v2,
                                            const void *data,
                                            bool ascending) {
  assert(data);
  String str1;
  if (v1.isString()) {
    str1 = v1.toString();
  } else {
    UErrorCode status;
    str1 = intl_convert_str_utf8_to_utf16(v1.toString(), &status);
    if (U_FAILURE(status)) {
      raise_warning("Error converting utf8 to utf16 in "
                    "collator_string_compare_function()");
    }
  }
  String str2;
  if (v2.isString()) {
    str2 = v2.toString();
  } else {
    UErrorCode status;
    str2 = intl_convert_str_utf8_to_utf16(v2.toString(), &status);
    if (U_FAILURE(status)) {
      raise_warning("Error converting utf8 to utf16 in "
                    "collator_string_compare_function()");
    }
  }

  int ret = ucol_strcoll((const UCollator *)data,
                         (UChar*)(str1.data()),
                         UCHARS(str1.length()),
                         (UChar*)(str2.data()),
                         UCHARS(str2.length()));
  return ascending ? ret : (-ret);
}
예제 #3
0
Variant f_range(CVarRef low, CVarRef high, CVarRef step /* = 1 */) {
  bool is_step_double = false;
  double dstep = 1.0;
  if (step.isDouble()) {
    dstep = step.toDouble();
    is_step_double = true;
  } else if (step.isString()) {
    int64_t sn;
    double sd;
    DataType stype = step.toString()->isNumericWithVal(sn, sd, 0);
    if (stype == KindOfDouble) {
      is_step_double = true;
      dstep = sd;
    } else if (stype == KindOfInt64) {
      dstep = (double)sn;
    } else {
      dstep = step.toDouble();
    }
  } else {
    dstep = step.toDouble();
  }
  /* We only want positive step values. */
  if (dstep < 0.0) dstep *= -1;
  if (low.isString() && high.isString()) {
    String slow = low.toString();
    String shigh = high.toString();
    if (slow.size() >= 1 && shigh.size() >=1) {
      int64_t n1, n2;
      double d1, d2;
      DataType type1 = slow->isNumericWithVal(n1, d1, 0);
      DataType type2 = shigh->isNumericWithVal(n2, d2, 0);
      if (type1 == KindOfDouble || type2 == KindOfDouble || is_step_double) {
        if (type1 != KindOfDouble) d1 = slow.toDouble();
        if (type2 != KindOfDouble) d2 = shigh.toDouble();
        return ArrayUtil::Range(d1, d2, dstep);
      }

      int64_t lstep = (int64_t) dstep;
      if (type1 == KindOfInt64 || type2 == KindOfInt64) {
        if (type1 != KindOfInt64) n1 = slow.toInt64();
        if (type2 != KindOfInt64) n2 = shigh.toInt64();
        return ArrayUtil::Range((double)n1, (double)n2, lstep);
      }

      return ArrayUtil::Range((unsigned char)slow.charAt(0),
                              (unsigned char)shigh.charAt(0), lstep);
    }
  }

  if (low.is(KindOfDouble) || high.is(KindOfDouble) || is_step_double) {
    return ArrayUtil::Range(low.toDouble(), high.toDouble(), dstep);
  }

  int64_t lstep = (int64_t) dstep;
  return ArrayUtil::Range(low.toDouble(), high.toDouble(), lstep);
}
예제 #4
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();
}
예제 #5
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;
}
예제 #6
0
bool ZendArray::exists(CVarRef k) const {
  TypedValueAccessor tva = k.getTypedAccessor();
  if (isIntKey(tva)) return find(getIntKey(tva));
  ASSERT(k.isString());
  StringData *key = getStringKey(tva);
  return find(key->data(), key->size(), key->hash());
}
예제 #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);
}
예제 #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;
}
예제 #9
0
static bool ctype(CVarRef v, int (*iswhat)(int)) {
  if (v.isInteger()) {
    int64_t n = v.toInt64();
    if (n <= 255 && n >= 0) {
      return iswhat(n);
    }

    if (n >= -128 && n < 0) {
      return iswhat(n + 256);
    }

    return ctype(v.toString(), iswhat);
  }

  if (v.isString()) {
    String s = v.toString();
    if (!s.empty()) {
      const char *p = s.data();
      const char *e = s.data() + s.size();
      while (p < e) {
        if (!iswhat((int)*(unsigned char *)(p++))) {
          return false;
        }
      }
      return true;
    }
  }
  return false;
}
예제 #10
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;
}
예제 #11
0
bool VectorString::setImpl(int index, CVarRef v, bool copy, ArrayData *&ret) {
  bool keepVector = false;
  if (index >= 0) {
    keepVector = true;
  }

  if (!v.isString()) {
    if (keepVector) {
      ret = NEW(VectorVariant)(this, index, v);
      return true;
    }
    return false;
  }

  if (!keepVector) {
    return false;
  }
  if (copy) {
    ret = NEW(VectorString)(this, index, v.toString());
    return true;
  }

  if ((ssize_t)index < size()) {
    ASSERT(index >= 0);
    m_elems[index] = v.toString();
  } else {
    ASSERT((ssize_t)index == size());
    m_elems.push_back(v.toString());
  }
  ret = NULL;
  return true;
}
예제 #12
0
Variant f_bzopen(CVarRef filename, CStrRef mode) {
  if (mode != "r" && mode != "w") {
    raise_warning(
      "'%s' is not a valid mode for bzopen(). "
      "Only 'w' and 'r' are supported.",
      mode.data()
    );
    return false;
  }

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

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

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

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

    bz = NEWOBJ(BZ2File)(f);
  }
  Object handle(bz);
  return handle;
}
예제 #13
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;
}
예제 #14
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, -1);
      }
    } else if (handler.isArray() && handler.getArrayData()->size() == 2 &&
               (handler[0].isString() || handler[0].isObject()) &&
               handler[1].isString()) {
      if (handler[0].isString()) {
        // static method
        retval = ObjectData::os_invoke(handler[0].toString(),
                                       handler[1].toString(), args, -1);
      } else {
        // instance method
        retval = handler[0].toObject()->o_invoke(handler[1].toString(),
                                                 args, -1);
      }
    } else {
      raise_warning("Handler is invalid");
    }
    return retval;
  }
  return null;
}
예제 #15
0
Variant f_exit(CVarRef status /* = null_variant */) {
  if (status.isString()) {
    echo(status.toString());
    throw ExitException(0);
  }
  throw ExitException(status.toInt32());
}
예제 #16
0
파일: comparisons.cpp 프로젝트: 1mr3yn/hhvm
bool same(CVarRef v1, const StringData* v2) {
  bool null1 = v1.isNull();
  bool null2 = (v2 == nullptr);
  if (null1 && null2) return true;
  if (null1 || null2) return false;
  if (!v1.isString()) return false;
  auto const sdata = v1.getStringData();
  return sdata == v2 || v2->same(sdata);
}
예제 #17
0
Variant f_strripos(CStrRef haystack, CVarRef needle, int offset /* = 0 */) {
  int pos;
  if (needle.isString()) {
    pos = haystack.rfind(needle.toString(), offset, false);
  } else {
    pos = haystack.rfind(needle.toByte(), offset, false);
  }
  if (pos >= 0) return pos;
  return false;
}
예제 #18
0
static void xml_set_handler(Variant * handler, CVarRef data) {
  if (same(data, false) || data.isString() ||
      (data.isArray() && data.getArrayData()->size() == 2 &&
       (data[0].isString() || data[0].isObject()) &&
       data[1].isString())) {
    *handler = data;
  } else {
    raise_warning("Handler is invalid");
  }
}
예제 #19
0
Variant f_assert(CVarRef assertion) {
  if (!s_option_data->assertActive) return true;

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

  auto const passed = [&]() -> bool {
    if (assertion.isString()) {
      if (RuntimeOption::RepoAuthoritative) {
        // 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();

    VectorInit ai(3);
    ai.add(String(unit->filepath()));
    ai.add(Variant(unit->getLineNumber(callerOffset)));
    ai.add(assertion.isString() ? assertion.toString() : String(""));
    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 uninit_null();
}
예제 #20
0
String static memcache_prepare_for_storage(CVarRef var, int &flag) {
  if (var.isString()) {
    return var.toString();
  } else if (var.isNumeric() || var.isBoolean()) {
    return var.toString();
  } else {
    flag |= MMC_SERIALIZED;
    return f_serialize(var);
  }
}
string& SourceRootInfo::initPhpRoot() {
  GlobalVariables *g = get_global_variables();
  CVarRef server = g->get(s_SERVER);
  CVarRef v = server.rvalAt(s_PHP_ROOT);
  if (v.isString()) {
    *s_phproot.getCheck() = string(v.asCStrRef().data()) + string("/");
  } else {
    // Our best guess at the source root.
    *s_phproot.getCheck() = GetCurrentSourceRoot();
  }
  return *s_phproot.getCheck();
}
예제 #22
0
static Variant collator_convert_string_to_number_if_possible(CVarRef str) {
  int64_t lval     = 0;
  double dval    = 0;

  if (!str.isString()) return false;

  DataType ret = collator_is_numeric((UChar*)(str.toString().data()),
                                     UCHARS(str.toString().length()),
                                     &lval, &dval, 1);
  if (ret == KindOfInt64) return lval;
  if (ret == KindOfDouble) return dval;
  return false;
}
예제 #23
0
int MapVariant::insertKey(CVarRef key, int64 prehash /* = -1 */) {
    int res;
    ASSERT(key.isInteger() || key.isString());
    if (m_map.insert(key, m_elems.size(), res, prehash)) {
        if (m_keys) {
            m_keys->push_back(key);
        }
        if (key.isInteger()) {
            int64 index = key.toInt64();
            if (index + 1 > m_nextIndex) m_nextIndex = index + 1;
        }
    }
    return res;
}
예제 #24
0
static void collator_convert_array_from_utf16_to_utf8(Array &array,
                                                      UErrorCode * status) {
  for (ArrayIter iter(array); iter; ++iter) {
    CVarRef value = iter.secondRef();
    /* Process string values only. */
    if (!value.isString()) continue;
    String str = intl_convert_str_utf16_to_utf8(value, status);
    if (U_FAILURE(*status)) {
      return;
    }
    /* Update current value with the converted value. */
    const_cast<Variant&>(value) = str;
  }
}
예제 #25
0
bool f_is_callable(CVarRef v, bool syntax /* = false */,
                   Variant name /* = null */) {
  if (v.isString()) {
    if (!name.isNull()) name = v;
    if (syntax) return true;

    string lowered = Util::toLower((const char *)v.toString());
    size_t c = lowered.find("::");
    if (c != 0 && c != string::npos && c+2 < lowered.size()) {
      string classname = lowered.substr(0, c);
      string methodname = lowered.substr(c+2);
      const ClassInfo *clsInfo = ClassInfo::FindClass(classname.c_str());
      if (clsInfo && clsInfo->isDeclared()) {
        return clsInfo->hasMethod(methodname.c_str());
      }
      return false;
    }

    return f_function_exists(v.toString());
  }

  if (v.is(KindOfArray)) {
    Array arr = v.toArray();
    if (arr.size() == 2 && arr.exists(0LL) && arr.exists(1LL)) {
      Variant v0 = arr.rvalAt(0LL);
      Variant v1 = arr.rvalAt(1LL);
      if (v0.is(KindOfObject)) {
        v0 = v0.toObject()->o_getClassName();
      }
      if (v0.isString() && v1.isString()) {
        if (!name.isNull()) {
          name = v0.toString() + "::" + v1.toString();
        }
        if (same(v0, "self") || same(v0, "parent")) {
          throw NotImplementedException("augmenting class scope info");
        }
        const ClassInfo *clsInfo = ClassInfo::FindClass(v0.toString());
        if (clsInfo && clsInfo->isDeclared()) {
          return clsInfo->hasMethod(v1.toString());
        }
        return false;
      }
    }
  }

  if (!name.isNull()) {
    name = v.toString();
  }
  return false;
}
예제 #26
0
ssize_t ZendArray::getIndex(CVarRef k) const {
  Bucket *p;
  TypedValueAccessor tva = k.getTypedAccessor();
  if (isIntKey(tva)) {
    p = find(getIntKey(tva));
  } else {
    ASSERT(k.isString());
    StringData *key = getStringKey(tva);
    p = find(key->data(), key->size(), key->hash());
  }
  if (p) {
    return (ssize_t)p;
  }
  return ArrayData::invalid_index;
}
예제 #27
0
void ZendArray::load(CVarRef k, Variant &v) const {
  Bucket *p;
  TypedValueAccessor tva = k.getTypedAccessor();
  if (isIntKey(tva)) {
    p = find(getIntKey(tva));
  } else {
    ASSERT(k.isString());
    StringData *strkey = getStringKey(tva);
    int64 prehash = strkey->hash();
    p = find(strkey->data(), strkey->size(), prehash);
  }
  if (p) {
    v.setWithRef(p->data);
  }
}
예제 #28
0
bool f_stream_context_set_option(CVarRef stream_or_context,
                                 CVarRef wrapper_or_options,
                                 CVarRef option /* = null_variant */,
                                 CVarRef value /* = null_variant */) {
  StreamContext* context = get_stream_context(stream_or_context);
  if (!context) {
    raise_warning("Invalid stream/context parameter");
    return false;
  }
  if (wrapper_or_options.isArray() &&
      !option.isInitialized() &&
      !value.isInitialized()) {
    return f_stream_context_set_option0(context, wrapper_or_options.toArray());
  } else if (wrapper_or_options.isString() &&
             option.isInitialized() &&
             option.isString() &&
             value.isInitialized()) {
    return f_stream_context_set_option1(context, wrapper_or_options.toString(),
                                        option.toString(), value);
  } else {
    raise_warning("called with wrong number or type of parameters; please RTM");
    return false;
  }
}
예제 #29
0
static Variant collator_normalize_sort_argument(CVarRef arg) {
  if (!arg.isString()) return arg;

  Variant n_arg = collator_convert_string_to_number_if_possible(arg);
  if (same(n_arg, false)) {
    /* Conversion to number failed. */
    UErrorCode status;
    n_arg = intl_convert_str_utf16_to_utf8(arg, &status);
    if (U_FAILURE(status)) {
      raise_warning("Error converting utf16 to utf8 in "
                    "collator_normalize_sort_argument()");
    }
  }
  return n_arg;
}
예제 #30
0
Variant f_strpos(CStrRef haystack, CVarRef needle, int offset /* = 0 */) {
  int pos;
  if (needle.isString()) {
    String n(needle.toString());
    if (n.length() == 0) {
      raise_warning("Empty delimiter");
      return false;
    }
    pos = haystack.find(n, offset);
  } else {
    pos = haystack.find(needle.toByte(), offset);
  }
  if (pos >= 0) return pos;
  return false;
}