예제 #1
0
Variant f_setlocale(int _argc, int category, CVarRef locale, CArrRef _argv /* = null_array */) {
  Array argv = _argv;
  if (locale.is(KindOfArray)) {
    if (!argv.empty()) throw_invalid_argument("locale: not string)");
    argv = locale; // ignore _argv
  }

  for (int i = -1; i < argv.size(); i++) {
    String slocale;
    if (i == -1) {
      if (locale.is(KindOfArray)) continue;
      slocale = locale.toString();
    } else {
      slocale = argv[i].toString();
    }

    const char *loc = slocale;
    if (slocale.size() >= 255) {
      throw_invalid_argument("locale name is too long: %s", loc);
      return false;
    }
    if (strcmp("0", loc) == 0) {
      loc = NULL;
    }
    {
      Lock lock(s_mutex);
      const char *retval = setlocale(category, loc);
      if (retval) {
        return String(retval, CopyString);
      }
    }
  }
  return false;
}
예제 #2
0
Variant f_substr_replace(CVarRef str, CVarRef replacement, CVarRef start,
                         CVarRef length /* = 0x7FFFFFFF */) {
  if (!str.is(KindOfArray)) {
    String repl;
    if (replacement.is(KindOfArray)) {
      repl = replacement[0].toString();
    } else {
      repl = replacement.toString();
    }
    if (start.is(KindOfArray)) {
      if (!length.is(KindOfArray)) {
        throw_invalid_argument("start and length should be of same type - "
                               "numerical or array");
        return str;
      }
      Array startArr = start.toArray();
      Array lengthArr = length.toArray();
      if (startArr.size() != lengthArr.size()) {
        throw_invalid_argument("start and length: (different item count)");
        return str;
      }
      throw_invalid_argument("start and length as arrays not implemented");
      return str;
    }
    return str.toString().replace(start.toInt32(), length.toInt32(), repl);
  }

  Array ret;
  Array strArr = str.toArray();
  Array startArr = start.toArray();
  Array lengthArr = length.toArray();
  ArrayIter startIter(startArr);
  ArrayIter lengthIter(lengthArr);

  if (replacement.is(KindOfArray)) {
    Array replArr = replacement.toArray();
    ArrayIter replIter(replArr);
    for (ArrayIter iter(strArr); iter;
         ++iter, ++startIter, ++lengthIter) {
      int nStart = startIter.second().toInt32();
      int nLength = lengthIter.second().toInt32();
      String repl("");
      if (replIter) {
        repl = replIter.second().toString();
        ++replIter;
      }
      ret.append(iter.second().toString().replace(nStart, nLength, repl));
    }
  } else {
    String repl = replacement.toString();
    for (ArrayIter iter(strArr); iter;
         ++iter, ++startIter, ++lengthIter) {
      int nStart = startIter.second().toInt32();
      int nLength = lengthIter.second().toInt32();
      ret.append(iter.second().toString().replace(nStart, nLength, repl));
    }
  }
  return ret;
}
예제 #3
0
bool not_less(CVarRef v1, CVarRef v2) {
  if (v1.is(KindOfArray) && v2.is(KindOfArray)) {
    Array a1 = v1.toArray();
    Array a2 = v2.toArray();
    return a1.more(a2) || a1.equal(a2);
  }
  return !less(v1, v2);
}
예제 #4
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);
}
예제 #5
0
String f_implode(CVarRef arg1, CVarRef arg2 /* = null_variant */) {
  Array items;
  String delim;
  if (arg1.is(KindOfArray)) {
    items = arg1.toArray();
    delim = arg2.toString();
  } else if (arg2.is(KindOfArray)) {
    items = arg2.toArray();
    delim = arg1.toString();
  } else {
    throw_bad_type_exception("arguments need at least one array");
    return String();
  }
  return StringUtil::Implode(items, delim);
}
예제 #6
0
bool more_or_equal(CVarRef v1, CVarRef v2) {
  // To be PHP-compatible, when comparing two arrays or two objects we
  // cannot assume that "($x >= $y)" is equivalent to "!($x < $y)".
  if (v1.is(KindOfArray) && v2.is(KindOfArray)) {
    Array a1 = v1.toArray();
    Array a2 = v2.toArray();
    return a1.more(a2) || a1.equal(a2);
  }
  if (v1.is(KindOfObject) && v2.is(KindOfObject)) {
    Object o1 = v1.toObject();
    Object o2 = v2.toObject();
    return o1.more(o2) || o1.equal(o2);
  }
  return !less(v1, v2);
}
예제 #7
0
Variant f_max(int _argc, CVarRef value, CArrRef _argv /* = null_array */) {
  Variant ret;
  if (_argv.empty() && value.is(KindOfArray)) {
    Array v = value.toArray();
    if (!v.empty()) {
      ssize_t pos = v->iter_begin();
      if (pos != ArrayData::invalid_index) {
        ret = v->getValue(pos);
        while (true) {
          pos = v->iter_advance(pos);
          if (pos == ArrayData::invalid_index) break;
          Variant tmp = v->getValue(pos);
          if (more(tmp, ret)) {
            ret = tmp;
          }
        }
      }
    }
  } else {
    ret = value;
    if (!_argv.empty()) {
      for (ssize_t pos = _argv->iter_begin(); pos != ArrayData::invalid_index;
           pos = _argv->iter_advance(pos)) {
        Variant tmp = _argv->getValue(pos);
        if (more(tmp, ret)) {
          ret = tmp;
        }
      }
    }
  }
  return ret;
}
예제 #8
0
파일: ext_apc.cpp 프로젝트: TSMG1972/hhvm
Variant f_apc_exists(CVarRef key, int64_t cache_id /* = 0 */) {
  if (!apcExtension::Enable) return false;

  if (cache_id < 0 || cache_id >= MAX_SHARED_STORE) {
    throw_invalid_argument("cache_id: %" PRId64, cache_id);
    return false;
  }

  if (key.is(KindOfArray)) {
    Array keys = key.toArray();
    ArrayInit init(keys.size());
    for (ArrayIter iter(keys); iter; ++iter) {
      Variant k = iter.second();
      if (!k.isString()) {
        throw_invalid_argument("apc key: (not a string)");
        return false;
      }
      String strKey = k.toString();
      if (s_apc_store[cache_id].exists(strKey)) {
        init.set(strKey);
      }
    }
    return init.create();
  }

  return s_apc_store[cache_id].exists(key.toString());
}
예제 #9
0
static void url_encode_array(StringBuffer &ret, CVarRef varr,
                             std::set<void*> &seen_arrs,
                             CStrRef num_prefix, CStrRef key_prefix,
                             CStrRef key_suffix, CStrRef arg_sep) {
  void *id = varr.is(KindOfArray) ?
    (void*)varr.getArrayData() : (void*)varr.getObjectData();
  if (!seen_arrs.insert(id).second) {
    return; // recursive
  }

  Array arr = varr.toArray();

  for (ArrayIter iter(arr); iter; ++iter) {
    Variant data = iter.second();
    if (data.isNull() || data.isResource()) continue;

    String key = iter.first();
    bool numeric = key.isNumeric();

    if (data.is(KindOfArray) || data.is(KindOfObject)) {
      String encoded;
      if (numeric) {
        encoded = key;
      } else {
        encoded = StringUtil::UrlEncode(key);
      }
      StringBuffer new_prefix(key_prefix.size() + num_prefix.size() +
                              encoded.size() + key_suffix.size() + 4);
      new_prefix += key_prefix;
      if (numeric) new_prefix += num_prefix;
      new_prefix += encoded;
      new_prefix += key_suffix;
      new_prefix += "%5B";
      url_encode_array(ret, data, seen_arrs, String(),
                       new_prefix.detach(), String("%5D", AttachLiteral),
                       arg_sep);
    } else {
      if (!ret.empty()) {
        ret += arg_sep;
      }
      ret += key_prefix;
      if (numeric) {
        ret += num_prefix;
        ret += key;
      } else {
        ret += StringUtil::UrlEncode(key);
      }
      ret += key_suffix;
      ret += "=";
      if (data.isInteger() || data.is(KindOfBoolean)) {
        ret += String(data.toInt64());
      } else if (data.is(KindOfDouble)) {
        ret += String(data.toDouble());
      } else {
        ret += StringUtil::UrlEncode(data.toString());
      }
    }
  }
}
예제 #10
0
Variant f_strtr(CStrRef str, CVarRef from, CVarRef to /* = null_variant */) {
  if (str.empty()) {
    return str;
  }

  if (!to.isNull()) {
    return StringUtil::Translate(str, from.toString(), to.toString());
  }

  if (!from.is(KindOfArray)) {
    throw_invalid_argument("2nd argument: (not array)");
    return false;
  }

  int maxlen = 0;
  int minlen = -1;
  Array arr = from.toArray();
  for (ArrayIter iter(arr); iter; ++iter) {
    String search = iter.first();
    int len = search.size();
    if (len < 1) return false;
    if (maxlen < len) maxlen = len;
    if (minlen == -1 || minlen > len) minlen = len;
  }

  const char *s = str.data();
  int slen = str.size();
  char *key = (char *)malloc(maxlen+1);

  StringBuffer result(slen);
  for (int pos = 0; pos < slen; ) {
    if ((pos + maxlen) > slen) {
      maxlen = slen - pos;
    }
    bool found = false;
    memcpy(key, s + pos, maxlen);
    for (int len = maxlen; len >= minlen; len--) {
      key[len] = 0;
      if (arr.exists(key)) {
        String replace = arr[key].toString();
        if (!replace.empty()) {
          result += replace;
        }
        pos += len;
        found = true;
        break;
      }
    }
    if (!found) {
      result += s[pos++];
    }
  }
  free(key);

  return result.detach();
}
예제 #11
0
Variant f_http_build_query(CVarRef formdata,
                           CStrRef numeric_prefix /* = null_string */,
                           CStrRef arg_separator /* = null_string */) {
  if (!formdata.is(KindOfArray) && !formdata.is(KindOfObject)) {
    throw_invalid_argument("formdata: (need Array or Object)");
    return false;
  }

  String arg_sep;
  if (arg_separator.isNull()) {
    arg_sep = f_ini_get("arg_separator.output");
  } else {
    arg_sep = arg_separator;
  }

  StringBuffer ret(1024);
  std::set<void*> seen_arrs;
  url_encode_array(ret, formdata.toArray(), seen_arrs,
                   numeric_prefix, String(), String(), arg_sep);
  return String(ret);
}
예제 #12
0
static Variant str_replace(CVarRef search, CVarRef replace, CStrRef subject,
                           int &count, bool caseSensitive) {
  if (search.is(KindOfArray)) {
    String ret = subject;

    Array searchArr = search.toArray();
    if (replace.is(KindOfArray)) {
      Array replArr = replace.toArray();
      ArrayIter replIter(replArr);
      for (ArrayIter iter(searchArr); iter; ++iter) {
        TAINT_OBSERVER(TAINT_BIT_MUTATED, TAINT_BIT_NONE);
        if (replIter) {
          ret = ret.replace(iter.second().toString(),
                            replIter.second().toString(),
                            count, caseSensitive);
          ++replIter;
        } else {
          ret = ret.replace(iter.second().toString(),
                            "", count, caseSensitive);
        }
      }
      return ret;
    }

    TAINT_OBSERVER(TAINT_BIT_MUTATED, TAINT_BIT_NONE);
    String repl = replace.toString();
    for (ArrayIter iter(searchArr); iter; ++iter) {
      ret = ret.replace(iter.second().toString(), repl, count, caseSensitive);
    }
    return ret;
  }

  if (replace.is(KindOfArray)) {
    raise_notice("Array to string conversion");
  }
  TAINT_OBSERVER(TAINT_BIT_MUTATED, TAINT_BIT_NONE);
  return subject.replace(search.toString(), replace.toString(), count,
                         caseSensitive);
}
예제 #13
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;
}
예제 #14
0
static Variant str_replace(CVarRef search, CVarRef replace, CVarRef subject,
                           int &count, bool caseSensitive) {
  if (subject.is(KindOfArray)) {
    Array arr = subject.toArray();
    Array ret;
    for (ArrayIter iter(arr); iter; ++iter) {
      String replaced = str_replace(search, replace, iter.second().toString(),
                                    count, caseSensitive);
      ret.set(iter.first(), replaced);
    }
    return ret;
  }
  return str_replace(search, replace, subject.toString(), count,
                     caseSensitive);
}
예제 #15
0
파일: ext_apc.cpp 프로젝트: TSMG1972/hhvm
Variant f_apc_fetch(CVarRef key, VRefParam success /* = null */,
                    int64_t cache_id /* = 0 */) {
  if (!apcExtension::Enable) return false;

  if (cache_id < 0 || cache_id >= MAX_SHARED_STORE) {
    throw_invalid_argument("cache_id: %" PRId64, cache_id);
    return false;
  }

  Variant v;

  if (key.is(KindOfArray)) {
    bool tmp = false;
    Array keys = key.toArray();
    ArrayInit init(keys.size());
    for (ArrayIter iter(keys); iter; ++iter) {
      Variant k = iter.second();
      if (!k.isString()) {
        throw_invalid_argument("apc key: (not a string)");
        return false;
      }
      String strKey = k.toString();
      if (s_apc_store[cache_id].get(strKey, v)) {
        tmp = true;
        init.set(strKey, v, true);
      }
    }
    success = tmp;
    return init.create();
  }

  if (s_apc_store[cache_id].get(key.toString(), v)) {
    success = true;
  } else {
    success = false;
    v = false;
  }
  return v;
}
예제 #16
0
파일: ext_apc.cpp 프로젝트: TSMG1972/hhvm
Variant f_apc_add(CVarRef key_or_array, CVarRef var /* = null_variant */,
    int64_t ttl /* = 0 */, int64_t cache_id /* = 0 */) {
  if (!apcExtension::Enable) return false;

  if (cache_id < 0 || cache_id >= MAX_SHARED_STORE) {
    throw_invalid_argument("cache_id: %" PRId64, cache_id);
    return false;
  }

  if (key_or_array.is(KindOfArray))
  {
    Array valuesArr = key_or_array.toArray();

    // errors stores all keys corresponding to entries that could not be cached
    ArrayInit errors(valuesArr.size());

    for (ArrayIter iter(valuesArr); iter; ++iter)
    {
      Variant key = iter.first();
      if (!key.isString()) {
          throw_invalid_argument("apc key: (not a string)");
          return false;
      }
      Variant v = iter.second();
      if (!(s_apc_store[cache_id].store(key.toString(), v, ttl, false)))
          errors.set(key);
    }
    return errors.create();
  }

  if (!key_or_array.isString()) {
      throw_invalid_argument("apc key: (not a string)");
      return false;
  }
  String strKey = key_or_array.toString();
  return s_apc_store[cache_id].store(strKey, var, ttl, false);

}
예제 #17
0
bool not_more(CVarRef v1, CVarRef v2) {
  if (v1.is(KindOfArray) && v2.is(KindOfArray)) {
    return !v1.toArray().more(v2.toArray(), false);
  }
  return !more(v1, v2);
}
예제 #18
0
파일: ext_url.cpp 프로젝트: Alienfeel/hhvm
static void url_encode_array(StringBuffer &ret, CVarRef varr,
                             std::set<void*> &seen_arrs,
                             const String& num_prefix, const String& key_prefix,
                             const String& key_suffix, const String& arg_sep) {
  void *id = varr.is(KindOfArray) ?
    (void*)varr.getArrayData() : (void*)varr.getObjectData();
  if (!seen_arrs.insert(id).second) {
    return; // recursive
  }

  Array arr;
  if (varr.is(KindOfObject)) {
    Object o = varr.toObject();
    arr = (o.objectForCall()->isCollection()) ?
      varr.toArray() :
      f_get_object_vars(o).toArray();
  } else {
    arr = varr.toArray();
  }

  for (ArrayIter iter(arr); iter; ++iter) {
    Variant data = iter.second();
    if (data.isNull() || data.isResource()) continue;

    String key = iter.first();
    bool numeric = key.isNumeric();

    if (data.is(KindOfArray) || data.is(KindOfObject)) {
      String encoded;
      if (numeric) {
        encoded = key;
      } else {
        encoded = StringUtil::UrlEncode(key);
      }
      StringBuffer new_prefix(key_prefix.size() + num_prefix.size() +
                              encoded.size() + key_suffix.size() + 4);
      new_prefix.append(key_prefix);
      if (numeric) new_prefix.append(num_prefix);
      new_prefix.append(encoded);
      new_prefix.append(key_suffix);
      new_prefix.append("%5B");
      url_encode_array(ret, data, seen_arrs, String(),
                       new_prefix.detach(), String("%5D", CopyString),
                       arg_sep);
    } else {
      if (!ret.empty()) {
        ret.append(arg_sep);
      }
      ret.append(key_prefix);
      if (numeric) {
        ret.append(num_prefix);
        ret.append(key);
      } else {
        ret.append(StringUtil::UrlEncode(key));
      }
      ret.append(key_suffix);
      ret.append("=");
      if (data.isInteger() || data.is(KindOfBoolean)) {
        ret.append(String(data.toInt64()));
      } else if (data.is(KindOfDouble)) {
        ret.append(String(data.toDouble()));
      } else {
        ret.append(StringUtil::UrlEncode(data.toString()));
      }
    }
  }
}
예제 #19
0
bool f_is_object(CVarRef var) {
  return var.is(KindOfObject) && !var.isResource();
}
예제 #20
0
void binary_serialize(int8_t thrift_typeID, PHPOutputTransport& transport,
                      CVarRef value, CArrRef fieldspec) {
  // At this point the typeID (and field num, if applicable) should've already
  // been written to the output so all we need to do is write the payload.
  switch (thrift_typeID) {
    case T_STOP:
    case T_VOID:
      return;
    case T_STRUCT: {
      if (!value.is(KindOfObject)) {
        throw_tprotocolexception("Attempt to send non-object "
                                 "type as a T_STRUCT", INVALID_DATA);
      }
      binary_serialize_spec(value.toObject(), transport,
                            f_hphp_get_static_property(value.toObject()->
                                                       o_getClassName(),
                                                       s_TSPEC,
                                                       false).toArray());
    } return;
    case T_BOOL:
      transport.writeI8(value.toBoolean() ? 1 : 0);
      return;
    case T_BYTE:
      transport.writeI8(value.toByte());
      return;
    case T_I16:
      transport.writeI16(value.toInt16());
      return;
    case T_I32:
      transport.writeI32(value.toInt32());
      return;
    case T_I64:
    case T_U64:
      transport.writeI64(value.toInt64());
      return;
    case T_DOUBLE: {
      union {
        int64_t c;
        double d;
      } a;
      a.d = value.toDouble();
      transport.writeI64(a.c);
    } return;
    case T_FLOAT: {
      union {
        int32_t c;
        float d;
      } a;
      a.d = (float)value.toDouble();
      transport.writeI32(a.c);
    } return;
    //case T_UTF7:
    case T_UTF8:
    case T_UTF16:
    case T_STRING: {
        String sv = value.toString();
        transport.writeString(sv.data(), sv.size());
    } return;
    case T_MAP: {
      Array ht = value.toArray();
      uint8_t keytype = fieldspec.rvalAt(PHPTransport::s_ktype,
                                         AccessFlags::Error_Key).toByte();
      transport.writeI8(keytype);
      uint8_t valtype = fieldspec.rvalAt(PHPTransport::s_vtype,
                                         AccessFlags::Error_Key).toByte();
      transport.writeI8(valtype);

      Array valspec = fieldspec.rvalAt(PHPTransport::s_val,
                                       AccessFlags::Error_Key).toArray();

      transport.writeI32(ht.size());
      for (ArrayIter key_ptr = ht.begin(); !key_ptr.end(); ++key_ptr) {
        binary_serialize_hashtable_key(keytype, transport, key_ptr.first());
        binary_serialize(valtype, transport, key_ptr.second(), valspec);
      }
    } return;
    case T_LIST: {
      Array ht = value.toArray();
      Variant val;

      uint8_t valtype = fieldspec.rvalAt(PHPTransport::s_etype,
                                         AccessFlags::Error_Key).toInt64();
      transport.writeI8(valtype);
      Array valspec = fieldspec.rvalAt(PHPTransport::s_elem,
                                       AccessFlags::Error_Key).toArray();
      transport.writeI32(ht.size());
      for (ArrayIter key_ptr = ht.begin(); !key_ptr.end(); ++key_ptr) {
        binary_serialize(valtype, transport, key_ptr.second(), valspec);
      }
    } return;
    case T_SET: {
      Array ht = value.toArray();

      uint8_t keytype = fieldspec.rvalAt(PHPTransport::s_etype,
                                         AccessFlags::Error_Key).toByte();
      transport.writeI8(keytype);

      transport.writeI32(ht.size());
      for (ArrayIter key_ptr = ht.begin(); !key_ptr.end(); ++key_ptr) {
        binary_serialize_hashtable_key(keytype, transport, key_ptr.first());
      }
    } return;
  };
  char errbuf[128];
  sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID);
  throw_tprotocolexception(String(errbuf, CopyString), INVALID_DATA);
}
예제 #21
0
static String get_classname(CVarRef class_or_object) {
  if (class_or_object.is(KindOfObject)) {
    return class_or_object.toCObjRef().get()->o_getClassName();
  }
  return class_or_object.toString();
}
예제 #22
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);
      return f_call_user_func(2, "class_exists",
                              Array::Create(String(classname))) &&
        ClassInfo::hasAccess(classname, methodname, true, 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);
      Object obj;
      bool staticCall = false;
      if (v0.is(KindOfObject)) {
        obj = v0.toObject();
        v0 = obj->o_getClassName();
      } else if (v0.isString()) {
        if (!f_call_user_func(2, "class_exists",
                              Array::Create(v0))) {
          return false;
        }
        staticCall = true;
      }
      if (v1.isString()) {
        string lowered = Util::toLower((const char *)v1.toString());
        size_t c = lowered.find("::");
        if (c != 0 && c != string::npos && c+2 < lowered.size()) {
          string name1 = Util::toLower((const char *)v0.toString());
          string name2 = lowered.substr(0, c);
          if (name1 == name2 ||
              ClassInfo::isSubClass(name1, name2, false)) {
            staticCall = true;
            v0 = name2;
            v1 = lowered.substr(c+2);
          }
        }
      }
      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");
        }
        return ClassInfo::hasAccess(v0, v1, staticCall, !obj.isNull());
      }
    }
  }

  if (!name.isNull()) {
    name = v.toString();
  }
  return false;
}
예제 #23
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 str = v.toString();
    int c = str.find("::");
    if (c != 0 && c != String::npos && c + 2 < str.size()) {
      String classname = str.substr(0, c);
      String methodname = str.substr(c + 2);
      return f_class_exists(classname) &&
        ClassInfo::HasAccess(classname, methodname, true, false);
    }
    return f_function_exists(str);
  }

  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);
      Object obj;
      bool staticCall = false;
      if (v0.is(KindOfObject)) {
        obj = v0.toObject();
        v0 = obj->o_getClassName();
      } else if (v0.isString()) {
        if (!f_class_exists(v0.toString())) {
          return false;
        }
        staticCall = true;
      }
      if (v1.isString()) {
        String str = v1.toString();
        int c = str.find("::");
        if (c != 0 && c != String::npos && c + 2 < str.size()) {
          String name1 = v0.toString();
          String name2 = str.substr(0, c);
          ASSERT(name1.get() && name2.get());
          if (name1->isame(name2.get()) ||
              ClassInfo::IsSubClass(name1, name2, false)) {
            staticCall = true;
            v0 = name2;
            v1 = str.substr(c + 2);
          }
        }
      }
      if (v0.isString() && v1.isString()) {
        if (!name.isNull()) {
          name = v0.toString() + "::" + v1.toString();
        }
        if (same(v0, s_self) || same(v0, s_parent)) {
          throw NotImplementedException("augmenting class scope info");
        }
        return ClassInfo::HasAccess(v0, v1, staticCall, !obj.isNull());
      }
    }
  }

  if (!name.isNull()) {
    name = v.toString();
  }
  return false;
}
예제 #24
0
  bool setOption(long option, CVarRef value) {
    if (m_cp == NULL) {
      return false;
    }
    m_error_no = CURLE_OK;

    switch (option) {
    case CURLOPT_INFILESIZE:
    case CURLOPT_VERBOSE:
    case CURLOPT_HEADER:
    case CURLOPT_NOPROGRESS:
    case CURLOPT_NOBODY:
    case CURLOPT_FAILONERROR:
    case CURLOPT_UPLOAD:
    case CURLOPT_POST:
    case CURLOPT_FTPLISTONLY:
    case CURLOPT_FTPAPPEND:
    case CURLOPT_NETRC:
    case CURLOPT_PUT:
    case CURLOPT_TIMEOUT:
#if LIBCURL_VERSION_NUM >= 0x071002
    case CURLOPT_TIMEOUT_MS:
#endif
    case CURLOPT_FTP_USE_EPSV:
    case CURLOPT_LOW_SPEED_LIMIT:
    case CURLOPT_SSLVERSION:
    case CURLOPT_LOW_SPEED_TIME:
    case CURLOPT_RESUME_FROM:
    case CURLOPT_TIMEVALUE:
    case CURLOPT_TIMECONDITION:
    case CURLOPT_TRANSFERTEXT:
    case CURLOPT_HTTPPROXYTUNNEL:
    case CURLOPT_FILETIME:
    case CURLOPT_MAXREDIRS:
    case CURLOPT_MAXCONNECTS:
    case CURLOPT_CLOSEPOLICY:
    case CURLOPT_FRESH_CONNECT:
    case CURLOPT_FORBID_REUSE:
    case CURLOPT_CONNECTTIMEOUT:
#if LIBCURL_VERSION_NUM >= 0x071002
    case CURLOPT_CONNECTTIMEOUT_MS:
#endif
    case CURLOPT_SSL_VERIFYHOST:
    case CURLOPT_SSL_VERIFYPEER:
      //case CURLOPT_DNS_USE_GLOBAL_CACHE: not thread-safe when set to true
    case CURLOPT_NOSIGNAL:
    case CURLOPT_PROXYTYPE:
    case CURLOPT_BUFFERSIZE:
    case CURLOPT_HTTPGET:
    case CURLOPT_HTTP_VERSION:
    case CURLOPT_CRLF:
    case CURLOPT_DNS_CACHE_TIMEOUT:
    case CURLOPT_PROXYPORT:
    case CURLOPT_FTP_USE_EPRT:
    case CURLOPT_HTTPAUTH:
    case CURLOPT_PROXYAUTH:
    case CURLOPT_FTP_CREATE_MISSING_DIRS:
    case CURLOPT_FTPSSLAUTH:
    case CURLOPT_FTP_SSL:
    case CURLOPT_UNRESTRICTED_AUTH:
    case CURLOPT_PORT:
    case CURLOPT_AUTOREFERER:
    case CURLOPT_COOKIESESSION:
    case CURLOPT_TCP_NODELAY:
    case CURLOPT_IPRESOLVE:
    case CURLOPT_FOLLOWLOCATION:
      m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, value.toInt64());
      break;
    case CURLOPT_RETURNTRANSFER:
      m_write.method = value.toBoolean() ? PHP_CURL_RETURN : PHP_CURL_STDOUT;
      break;
    case CURLOPT_BINARYTRANSFER:
      m_write.type = value.toBoolean() ? PHP_CURL_BINARY : PHP_CURL_ASCII;
      break;
    case CURLOPT_PRIVATE:
    case CURLOPT_URL:
    case CURLOPT_PROXY:
    case CURLOPT_USERPWD:
    case CURLOPT_PROXYUSERPWD:
    case CURLOPT_RANGE:
    case CURLOPT_CUSTOMREQUEST:
    case CURLOPT_USERAGENT:
    case CURLOPT_FTPPORT:
    case CURLOPT_COOKIE:
    case CURLOPT_REFERER:
    case CURLOPT_INTERFACE:
    case CURLOPT_KRB4LEVEL:
    case CURLOPT_EGDSOCKET:
    case CURLOPT_CAINFO:
    case CURLOPT_CAPATH:
    case CURLOPT_SSL_CIPHER_LIST:
    case CURLOPT_SSLKEY:
    case CURLOPT_SSLKEYTYPE:
    case CURLOPT_SSLKEYPASSWD:
    case CURLOPT_SSLENGINE:
    case CURLOPT_SSLENGINE_DEFAULT:
    case CURLOPT_SSLCERTTYPE:
    case CURLOPT_ENCODING:
    case CURLOPT_COOKIEJAR:
    case CURLOPT_SSLCERT:
    case CURLOPT_RANDOM_FILE:
    case CURLOPT_COOKIEFILE:
      {
        String svalue = value.toString();
#if LIBCURL_VERSION_NUM >= 0x071100
        /* Strings passed to libcurl as 'char *' arguments, are copied
           by the library... NOTE: before 7.17.0 strings were not copied. */
        m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, svalue.c_str());
#else
        char *copystr = strndup(svalue.data(), svalue.size());
        m_to_free->str.push_back(copystr);
        m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, copystr);
#endif
        if (option == CURLOPT_URL) m_url = value;
      }
      break;
    case CURLOPT_FILE:
    case CURLOPT_INFILE:
    case CURLOPT_WRITEHEADER:
    case CURLOPT_STDERR:
      {
        if (!value.is(KindOfObject)) {
          return false;
        }

        Object obj = value.toObject();
        if (obj.isNull() || obj.getTyped<File>(true) == NULL) {
          return false;
        }

        switch (option) {
          case CURLOPT_FILE:
            m_write.fp = obj;
            m_write.method = PHP_CURL_FILE;
            break;
          case CURLOPT_WRITEHEADER:
            m_write_header.fp = obj;
            m_write_header.method = PHP_CURL_FILE;
            break;
          case CURLOPT_INFILE:
            m_read.fp = obj;
            m_emptyPost = false;
            break;
          default: {
            if (obj.getTyped<PlainFile>(true) == NULL) {
              return false;
            }
            FILE *fp = obj.getTyped<PlainFile>()->getStream();
            if (!fp) {
              return false;
            }
            m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, fp);
            break;
          }
        }
      }
      break;
    case CURLOPT_WRITEFUNCTION:
      m_write.callback = value;
      m_write.method = PHP_CURL_USER;
      break;
    case CURLOPT_READFUNCTION:
      m_read.callback = value;
      m_read.method = PHP_CURL_USER;
      m_emptyPost = false;
      break;
    case CURLOPT_HEADERFUNCTION:
      m_write_header.callback = value;
      m_write_header.method = PHP_CURL_USER;
      break;
    case CURLOPT_POSTFIELDS:
      m_emptyPost = false;
      if (value.is(KindOfArray) || value.is(KindOfObject)) {
        Array arr = value.toArray();
        curl_httppost *first = NULL;
        curl_httppost *last  = NULL;
        for (ArrayIter iter(arr); iter; ++iter) {
          String key = iter.first().toString();
          String val = iter.second().toString();
          const char *postval = val.data();

          /* The arguments after _NAMELENGTH and _CONTENTSLENGTH
           * must be explicitly cast to long in curl_formadd
           * use since curl needs a long not an int. */
          if (*postval == '@') {
            ++postval;
            m_error_no = (CURLcode)curl_formadd
              (&first, &last,
               CURLFORM_COPYNAME, key.data(),
               CURLFORM_NAMELENGTH, (long)key.size(),
               CURLFORM_FILE, postval,
               CURLFORM_END);
          } else {
            m_error_no = (CURLcode)curl_formadd
              (&first, &last,
               CURLFORM_COPYNAME, key.data(),
               CURLFORM_NAMELENGTH, (long)key.size(),
               CURLFORM_COPYCONTENTS, postval,
               CURLFORM_CONTENTSLENGTH,(long)val.size(),
               CURLFORM_END);
          }
        }

        if (m_error_no != CURLE_OK) {
          return false;
        }

        m_to_free->post.push_back(first);
        m_error_no = curl_easy_setopt(m_cp, CURLOPT_HTTPPOST, first);

      } else {
        String svalue = value.toString();
#if LIBCURL_VERSION_NUM >= 0x071100
        /* with curl 7.17.0 and later, we can use COPYPOSTFIELDS,
           but we have to provide size before */
        m_error_no = curl_easy_setopt(m_cp, CURLOPT_POSTFIELDSIZE,
                                      svalue.size());
        m_error_no = curl_easy_setopt(m_cp, CURLOPT_COPYPOSTFIELDS,
                                      svalue.c_str());
#else
        char *post = strndup(svalue.data(), svalue.size());
        m_to_free->str.push_back(post);

        m_error_no = curl_easy_setopt(m_cp, CURLOPT_POSTFIELDS, post);
        m_error_no = curl_easy_setopt(m_cp, CURLOPT_POSTFIELDSIZE,
                                      svalue.size());
#endif
      }
      break;
    case CURLOPT_HTTPHEADER:
    case CURLOPT_QUOTE:
    case CURLOPT_HTTP200ALIASES:
    case CURLOPT_POSTQUOTE:
      if (value.is(KindOfArray) || value.is(KindOfObject)) {
        Array arr = value.toArray();
        curl_slist *slist = NULL;
        for (ArrayIter iter(arr); iter; ++iter) {
          String key = iter.first().toString();
          String val = iter.second().toString();

          slist = curl_slist_append(slist, val.c_str());
          if (!slist) {
            raise_warning("Could not build curl_slist");
            return false;
          }
        }

        m_to_free->slist.push_back(slist);
        m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, slist);

      } else {
        raise_warning("You must pass either an object or an array with "
                      "the CURLOPT_HTTPHEADER, CURLOPT_QUOTE, "
                      "CURLOPT_HTTP200ALIASES and CURLOPT_POSTQUOTE "
                      "arguments");
        return false;
      }
      break;

    case CURLINFO_HEADER_OUT:
      if (value.toInt64() == 1) {
        curl_easy_setopt(m_cp, CURLOPT_DEBUGFUNCTION, curl_debug);
        curl_easy_setopt(m_cp, CURLOPT_DEBUGDATA, (void *)this);
        curl_easy_setopt(m_cp, CURLOPT_VERBOSE, 1);
      } else {
        curl_easy_setopt(m_cp, CURLOPT_DEBUGFUNCTION, NULL);
        curl_easy_setopt(m_cp, CURLOPT_DEBUGDATA, NULL);
        curl_easy_setopt(m_cp, CURLOPT_VERBOSE, 0);
      }
      break;

    default:
      m_error_no = CURLE_FAILED_INIT;
      throw_invalid_argument("option: %d", option);
      break;
    }

    m_opts.set(int64(option), value);

    return m_error_no == CURLE_OK;
  }
예제 #25
0
Variant c_Memcache::t_get(CVarRef key, VRefParam flags /*= null*/) {
  if (key.is(KindOfArray)) {
    std::vector<const char *> real_keys;
    std::vector<size_t> key_len;
    Array keyArr = key.toArray();

    real_keys.reserve(keyArr.size());
    key_len.reserve(keyArr.size());

    for (ArrayIter iter(keyArr); iter; ++iter) {
      real_keys.push_back(const_cast<char *>(iter.second().toString().c_str()));
      key_len.push_back(iter.second().toString().length());
    }

    if (!real_keys.empty()) {
      const char *payload = NULL;
      size_t payload_len = 0;
      uint32_t flags = 0;
      const char *res_key = NULL;
      size_t res_key_len = 0;

      memcached_result_st result;

      memcached_return_t ret = memcached_mget(&m_memcache, &real_keys[0],
                                              &key_len[0], real_keys.size());
      memcached_result_create(&m_memcache, &result);
      Array return_val;

      while ((memcached_fetch_result(&m_memcache, &result, &ret)) != NULL) {
        if (ret != MEMCACHED_SUCCESS) {
          // should probably notify about errors
          continue;
        }

        payload     = memcached_result_value(&result);
        payload_len = memcached_result_length(&result);
        flags       = memcached_result_flags(&result);
        res_key     = memcached_result_key_value(&result);
        res_key_len = memcached_result_key_length(&result);

        return_val.set(String(res_key, res_key_len, CopyString),
                       memcache_fetch_from_storage(payload,
                                                   payload_len, flags));
      }
      memcached_result_free(&result);

      return return_val;
    }
  } else {
    char *payload = NULL;
    size_t payload_len = 0;
    uint32_t flags = 0;

    memcached_return_t ret;
    String skey = key.toString();

    if (skey.length() == 0) {
      return false;
    }

    payload = memcached_get(&m_memcache, skey.c_str(), skey.length(),
                            &payload_len, &flags, &ret);

    /* This is for historical reasons from libmemcached*/
    if (ret == MEMCACHED_END) {
      ret = MEMCACHED_NOTFOUND;
    }

    if (ret == MEMCACHED_NOTFOUND) {
      return false;
    }

    Variant retval = memcache_fetch_from_storage(payload, payload_len, flags);
    free(payload);

    return retval;
  }
  return false;
}
예제 #26
0
bool not_less(CVarRef v1, CVarRef v2) {
  if (v1.is(KindOfArray) && v2.is(KindOfArray)) {
    return !v1.toArray().less(v2.toArray(), true);
  }
  return !less(v1, v2);
}