Пример #1
0
bool f_hphp_instanceof(CObjRef obj, CStrRef name) {
  return obj.instanceof(name.data());
}
Пример #2
0
bool f_defined(CStrRef name, bool autoload /* = true */) {
  if (!name.get()) return false;
  const char *data = name.data();
  int len = name.length();
  char *colon;
  if ((colon = (char*)memchr(data, ':', len)) && colon[1] == ':') {
    // class constant
    int classNameLen = colon - data;
    char *constantName = colon + 2;
    String className(data, classNameLen, CopyString);

    // translate "self" or "parent"
    if (className == "self") {
      String this_class = hhvm
                          ? g_vmContext->getContextClassName()
                          : FrameInjection::GetClassName(true);
      if (this_class.empty()) {
        throw FatalErrorException("Cannot access self:: "
          "when no class scope is active");
      } else {
        className = this_class;
      }
    } else if (className == "parent") {
      String parent_class = hhvm
                            ? g_vmContext->getParentContextClassName()
                            : FrameInjection::GetParentClassName(true);
      if (parent_class.empty()) {
        throw FatalErrorException("Cannot access parent");
      } else {
        className = parent_class;
      }
    }
    if (class_exists(className)) { // taking care of volatile class
      const ClassInfo *info;
      for (String parentClass = className;
           !parentClass.empty();
           parentClass = info->getParentClass()) {
        info = ClassInfo::FindClass(parentClass);
        if (!info) {
          assert(false);
        }
        if (info->hasConstant(constantName)) return true;
      }
      return false;
    } else {
      return false;
    }
  } else {
    // system/uniquely defined scalar constant
    if (ClassInfo::FindConstant(name)) return true;
    if (hhvm ?
        g_vmContext->defined(name) :
        ((Globals*)get_global_variables())->defined(name)) {
      return true;
    }
    if (!autoload || !AutoloadHandler::s_instance->autoloadConstant(name)) {
      return false;
    }
    if (hhvm) return g_vmContext->defined(name);
    if (ClassInfo::FindConstant(name)) return true;
    return ((Globals*)get_global_variables())->defined(name);
  }
}
bool ConcurrentTableSharedStore::store(CStrRef key, CVarRef val, int64 ttl,
                                       bool overwrite /* = true */) {
  bool stats = RuntimeOption::EnableStats && RuntimeOption::EnableAPCStats;
  bool statsDetail = RuntimeOption::EnableAPCSizeStats &&
                     RuntimeOption::EnableAPCSizeGroup;
  StoreValue *sval;
  SharedVariant* var = construct(key, val);
  ReadLock l(m_lock);

  const char *kcp = strdup(key.data());
  bool present;
  time_t expiry;
  {
    Map::accessor acc;
    present = !m_vars.insert(acc, kcp);
    sval = &acc->second;
    if (present) {
      free((void *)kcp);
      if (overwrite || sval->expired()) {
        if (statsDetail) {
          SharedStoreStats::onDelete(key.get(), sval->var, true);
        }
        sval->var->decRef();
        if (RuntimeOption::EnableAPCSizeStats && !check_skip(key.data())) {
          int32 size = var->getSpaceUsage();
          SharedStoreStats::updateDirect(sval->size, size);
          sval->size = size;
        }
      } else {
        var->decRef();
        return false;
      }
    } else {
      if (RuntimeOption::EnableAPCSizeStats) {
        int32 size = var->getSpaceUsage();
        SharedStoreStats::addDirect(key.size(), size);
        sval->size = size;
      }
    }
    sval->set(var, ttl);
    expiry = sval->expiry;
    if (statsDetail) {
      SharedStoreStats::onStore(key.get(), var, ttl, false);
    }
  }
  if (RuntimeOption::ApcExpireOnSets) {
    if (ttl) {
      addToExpirationQueue(key.data(), expiry);
    }
    purgeExpired();
  }
  if (stats) {
    if (present) {
      ServerStats::Log("apc.update", 1);
    } else {
      ServerStats::Log("apc.new", 1);
      if (RuntimeOption::EnableStats && RuntimeOption::EnableAPCKeyStats) {
        string prefix = "apc.new.";
        prefix += GetSkeleton(key);
        ServerStats::Log(prefix, 1);
      }
    }
  }

  return true;
}
Пример #4
0
bool BZ2File::open(CStrRef filename, CStrRef mode) {
  assert(m_bzFile == nullptr);

  return m_innerFile->open(filename, mode) &&
    (m_bzFile = BZ2_bzdopen(dup(m_innerFile->fd()), mode.data()));
}
Пример #5
0
void Transport::setMimeType(CStrRef mimeType) {
  m_mimeType = mimeType.data();
}
Пример #6
0
Variant f_gzcompress(CStrRef data, int level /* = -1 */) {
  return gzcompress(data.data(), data.size(), level);
}
Пример #7
0
Variant f_gzdeflate(CStrRef data, int level /* = -1 */) {
  return gzdeflate(data.data(), data.size(), level);
}
Пример #8
0
Variant f_posix_getpwnam(CStrRef username) {
  return php_posix_passwd_to_array(getpwnam(username.data()));
}
Пример #9
0
String c_DebuggerClientCmdUser::t_wrap(CStrRef str) {
  INSTANCE_METHOD_INJECTION_BUILTIN(DebuggerClientCmdUser, DebuggerClientCmdUser::wrap);
  return m_client->wrap(str.data());
}
Пример #10
0
Variant f_icu_match(CStrRef pattern, CStrRef subject,
                    VRefParam matches /* = null */, int64_t flags /* = 0 */) {
  UErrorCode status = U_ZERO_ERROR;

  if (matches.isReferenced()) {
    matches = Array();
  }

  // Create hash map key by concatenating pattern and flags.
  StringBuffer bpattern;
  bpattern.append(pattern);
  bpattern.append(':');
  bpattern.append(flags);
  String spattern = bpattern.detach();

  // Find compiled pattern matcher in hash map or add it.
  PatternStringMap::accessor accessor;
  const RegexPattern* rpattern;
  if (s_patternCacheMap.find(accessor, spattern.get())) {
    rpattern = accessor->second;
  } else {
    // First 32 bits are reserved for ICU-specific flags.
    rpattern = RegexPattern::compile(
      UnicodeString::fromUTF8(pattern.data()), (flags & 0xFFFFFFFF), status);
    if (U_FAILURE(status)) {
      return false;
    }

    if (s_patternCacheMap.insert(
      accessor, StringData::GetStaticString(spattern.get()))) {
      accessor->second = rpattern;
    } else {
      delete rpattern;
      rpattern = accessor->second;
    }
  }

  // Build regex matcher from compiled pattern and passed-in subject.
  UnicodeString usubject = UnicodeString::fromUTF8(subject.data());
  boost::scoped_ptr<RegexMatcher> matcher(rpattern->matcher(usubject, status));
  if (U_FAILURE(status)) {
    return false;
  }

  // Return 0 or 1 depending on whether or not a match was found and
  // (optionally), set matched (sub-)patterns for passed-in reference.
  int matched = 0;
  if (matcher->find()) {
    matched = 1;

    if (matches.isReferenced()) {
      int32_t count = matcher->groupCount();

      for (int32_t i = 0; i <= count; i++) {
        UnicodeString ustring = matcher->group(i, status);
        if (U_FAILURE(status)) {
          return false;
        }

        // Convert UnicodeString back to UTF-8.
        std::string string;
        ustring.toUTF8String(string);
        String match = String(string);

        if (flags & k_UREGEX_OFFSET_CAPTURE) {
          // start() returns the index in UnicodeString, which
          // normally means the index into an array of 16-bit
          // code "units" (not "points").
          int32_t start = matcher->start(i, status);
          if (U_FAILURE(status)) {
            return false;
          }

          start = usubject.countChar32(0, start);
          matches->append(CREATE_VECTOR2(match, start));
        } else {
          matches->append(match);
        }
      }
    }
  }

  return matched;
}
Пример #11
0
Variant f_posix_getgrnam(CStrRef name) {
  return php_posix_group_to_array(getgrnam(name.data()));
}
Пример #12
0
String highlight_php(CStrRef source, int line /* = 0 */,
                     int lineFocus0 /* = 0 */, int charFocus0 /* = 0 */,
                     int lineFocus1 /* = 0 */, int charFocus1 /* = 0 */) {
  StringBuffer res;
  Scanner scanner(source.data(), source.size(),
                  Scanner::AllowShortTags | Scanner::ReturnAllTokens);
  ScannerToken tok1, tok2;
  std::vector<pair<int, string> > ahead_tokens;
  Location loc1, loc2;

  const char *colorComment = NULL, *endComment = NULL;
  get_color(T_COMMENT, 0, 0, colorComment, endComment);

  int prev = 0;
  int tokid = scanner.getNextToken(tok1, loc1);
  int next = 0;
  while (tokid) {
    // look ahead
    next = scanner.getNextToken(tok2, loc2);
    while (next == T_WHITESPACE ||
           next == T_COMMENT ||
           next == T_DOC_COMMENT) {

      string text = tok2.text();
      string hcolor = check_char_highlight(lineFocus0, charFocus0,
                                           lineFocus1, charFocus1, loc2);
      if (!hcolor.empty()) {
        text = hcolor + text + ANSI_COLOR_END;
      }

      ahead_tokens.push_back(pair<int, string>(next, text));
      next = scanner.getNextToken(tok2, loc2);
    }

    string hcolor = check_char_highlight(lineFocus0, charFocus0,
                                         lineFocus1, charFocus1, loc1);

    if (tokid < 256) {
      if (!hcolor.empty()) {
        res.append(hcolor);
        res.append((char)tokid);
        res.append(ANSI_COLOR_END);
      } else {
        res.append((char)tokid);
      }
    } else {
      const char *color = NULL, *end = NULL;
      get_color(tokid, prev, next, color, end);
      if (!hcolor.empty()) {
        color = hcolor.c_str();
        end = ANSI_COLOR_END;
      }

      const std::string &text = tok1.text();
      int offset = 0;
      if (text[0] == '$') {
        if (!hcolor.empty()) {
          res.append(hcolor);
          res.append('$');
          res.append(ANSI_COLOR_END);
        } else {
          res.append('$');
        }
        offset = 1;
      }
      append_line_no(res, text.c_str() + offset, line, color, end,
                     lineFocus0, charFocus0, lineFocus1, charFocus1);
    }

    if (!ahead_tokens.empty()) {
      for (unsigned int i = 0; i < ahead_tokens.size(); i++) {
        bool comment = ahead_tokens[i].first != T_WHITESPACE;
        append_line_no(res, ahead_tokens[i].second.c_str(), line,
                       comment ? colorComment : NULL,
                       comment ? endComment : NULL,
                       lineFocus0, charFocus0, lineFocus1, charFocus1);
      }
      ahead_tokens.clear();
    }

    if (!(tokid == T_WHITESPACE || tokid == T_COMMENT ||
          tokid == T_DOC_COMMENT)) {
      prev = tokid;
    }
    tok1 = tok2;
    loc1 = loc2;
    tokid = next;
  }

  append_line_no(res, NULL, line, NULL, NULL,
                 lineFocus0, charFocus0, lineFocus1, charFocus1);
  return res.detach();
}
Пример #13
0
bool EvalObjectData::o_instanceof(CStrRef s) const {
  return m_cls.getClass()->subclassOf(s.data()) ||
    (!parent.isNull() && parent->o_instanceof(s));
}
Пример #14
0
void f_hphp_throw_fatal_error(CStrRef error_msg) {
  std::string msg = error_msg.data();
  raise_error(msg);
}
Пример #15
0
Variant c_Normalizer::ti_normalize(CStrRef input,
                                   int64_t form /* = q_Normalizer$$FORM_C */) {
  s_intl_error->m_error.clear();

  int expansion_factor = 1;
  switch(form) {
  case UNORM_NONE:
  case UNORM_NFC:
  case UNORM_NFKC:
    break;
  case UNORM_NFD:
  case UNORM_NFKD:
    expansion_factor = 3;
    break;
  default:
    s_intl_error->m_error.code = U_ILLEGAL_ARGUMENT_ERROR;
    s_intl_error->m_error.custom_error_message =
      "normalizer_normalize: illegal normalization form";
    return uninit_null();
  }

  /* First convert the string to UTF-16. */
  UChar* uinput = NULL; int uinput_len = 0;
  UErrorCode status = U_ZERO_ERROR;
  intl_convert_utf8_to_utf16(&uinput, &uinput_len, input.data(), input.size(),
                             &status);

  if (U_FAILURE(status)) {
    s_intl_error->m_error.code = status;
    s_intl_error->m_error.custom_error_message =
        "Error converting string to UTF-16.";
    free(uinput);
    return uninit_null();
  }

  /* Allocate memory for the destination buffer for normalization */
  int uret_len = uinput_len * expansion_factor;
  UChar *uret_buf = (UChar*)malloc((uret_len + 1) * sizeof(UChar));

  /* normalize */
  int size_needed = unorm_normalize(uinput, uinput_len,
                                    (UNormalizationMode)form, (int32_t) 0,
                                    uret_buf, uret_len, &status);

  /* Bail out if an unexpected error occured.
   * (U_BUFFER_OVERFLOW_ERROR means that *target buffer is not large enough).
   * (U_STRING_NOT_TERMINATED_WARNING usually means that the input string
   * is empty).
   */
  if (U_FAILURE(status) &&
      status != U_BUFFER_OVERFLOW_ERROR &&
      status != U_STRING_NOT_TERMINATED_WARNING) {
    free(uret_buf);
    free(uinput);
    return uninit_null();
  }

  if (size_needed > uret_len) {
    /* realloc does not seem to work properly - memory is corrupted
     * uret_buf =  eurealloc(uret_buf, size_needed + 1); */
    free(uret_buf);
    uret_buf = (UChar*)malloc((size_needed + 1) * sizeof(UChar));
    uret_len = size_needed;

    status = U_ZERO_ERROR;

    /* try normalize again */
    size_needed = unorm_normalize( uinput, uinput_len,
                                   (UNormalizationMode)form, (int32_t) 0,
                                   uret_buf, uret_len, &status);

    /* Bail out if an unexpected error occured. */
    if (U_FAILURE(status)) {
      /* Set error messages. */
      s_intl_error->m_error.code = status;
      s_intl_error->m_error.custom_error_message = "Error normalizing string";
      free(uret_buf);
      free(uinput);
      return uninit_null();
    }
  }

  free(uinput);

  /* the buffer we actually used */
  uret_len = size_needed;

  /* Convert normalized string from UTF-16 to UTF-8. */
  char* ret_buf = NULL; int ret_len = 0;
  intl_convert_utf16_to_utf8(&ret_buf, &ret_len, uret_buf, uret_len, &status);
  free(uret_buf);
  if (U_FAILURE(status)) {
    s_intl_error->m_error.code = status;
    s_intl_error->m_error.custom_error_message =
      "normalizer_normalize: error converting normalized text UTF-8";
    return uninit_null();
  }

  return String(ret_buf, ret_len, AttachString);
}
Пример #16
0
void c_DebuggerClientCmdUser::t_helpbody(CStrRef str) {
  INSTANCE_METHOD_INJECTION_BUILTIN(DebuggerClientCmdUser, DebuggerClientCmdUser::helpbody);
  m_client->helpBody(str.data());
}
Пример #17
0
static Variant php_intl_idn_to(CStrRef domain, int64_t options, IdnVariant idn_variant, VRefParam idna_info, int mode) {
  UChar* ustring = NULL;
  int ustring_len = 0;
  UErrorCode status;
  char     *converted_utf8 = NULL;
  int32_t   converted_utf8_len;
  UChar*    converted = NULL;
  int32_t   converted_ret_len;

  if (idn_variant != INTL_IDN_VARIANT_2003) {
#ifdef HAVE_46_API
    if (idn_variant == INTL_IDN_VARIANT_UTS46) {
      return php_intl_idn_to_46(domain, options, idn_variant, ref(idna_info), mode);
    }
#endif
    return false;
  }

  // Convert the string to UTF-16
  status = U_ZERO_ERROR;
  intl_convert_utf8_to_utf16(&ustring, &ustring_len,
      (char*)domain.data(), domain.size(), &status);
  if (U_FAILURE(status)) {
    free(ustring);
    return false;
  }

  // Call the appropriate IDN function
  int converted_len = (ustring_len > 1) ? ustring_len : 1;
  for (;;) {
    UParseError parse_error;
    status = U_ZERO_ERROR;
    converted = (UChar*)malloc(sizeof(UChar)*converted_len);
    // If the malloc failed, bail out
    if (!converted) {
      free(ustring);
      return false;
    }
    if (mode == INTL_IDN_TO_ASCII) {
      converted_ret_len = uidna_IDNToASCII(ustring,
          ustring_len, converted, converted_len,
          (int32_t)options, &parse_error, &status);
    } else {
      converted_ret_len = uidna_IDNToUnicode(ustring,
          ustring_len, converted, converted_len,
          (int32_t)options, &parse_error, &status);
    }
    if (status != U_BUFFER_OVERFLOW_ERROR)
      break;
    // If we have a buffer overflow error, try again with a larger buffer
    free(converted);
    converted = NULL;
    converted_len = converted_len * 2;
  }
  free(ustring);
  if (U_FAILURE(status)) {
    free(converted);
    return false;
  }

  // Convert the string back to UTF-8
  status = U_ZERO_ERROR;
  intl_convert_utf16_to_utf8(&converted_utf8, &converted_utf8_len,
      converted, converted_ret_len, &status);
  free(converted);
  if (U_FAILURE(status)) {
    free(converted_utf8);
    return false;
  }

  // Return the string
  return String(converted_utf8, converted_utf8_len, AttachString);
}
Пример #18
0
void c_DebuggerClientCmdUser::t_helpsection(CStrRef str) {
  INSTANCE_METHOD_INJECTION_BUILTIN(DebuggerClientCmdUser, DebuggerClientCmdUser::helpsection);
  m_client->helpSection(str.data());
}
Пример #19
0
Variant f_gzuncompress(CStrRef data, int limit /* = 0 */) {
  return gzuncompress(data.data(), data.size(), limit);
}
Пример #20
0
void c_DebuggerClientCmdUser::t_tutorial(CStrRef str) {
  INSTANCE_METHOD_INJECTION_BUILTIN(DebuggerClientCmdUser, DebuggerClientCmdUser::tutorial);
  m_client->tutorial(str.data());
}
Пример #21
0
Variant f_gzinflate(CStrRef data, int limit /* = 0 */) {
  return gzinflate(data.data(), data.size(), limit);
}
Пример #22
0
bool c_DebuggerClientCmdUser::t_arg(int index, CStrRef str) {
  INSTANCE_METHOD_INJECTION_BUILTIN(DebuggerClientCmdUser, DebuggerClientCmdUser::arg);
  return m_client->arg(index + 1, str.data());
}
Пример #23
0
void StringBuffer::append(CStrRef s) {
  append(s.data(), s.size());
  #ifdef TAINTED
  propagate_tainting2_buf(s, *this, *this);
  #endif
}
Пример #24
0
Variant c_DebuggerClient::t_processcmd(CVarRef cmdName, CVarRef args) {
  INSTANCE_METHOD_INJECTION_BUILTIN(DebuggerClient, DebuggerClient::processcmd);
  if (!m_client ||
      m_client->getClientState() < DebuggerClient::StateReadyForCommand) {
    raise_warning("client is not initialized");
    return null;
  }
  if (m_client->getClientState() != DebuggerClient::StateReadyForCommand) {
    raise_warning("client is not ready to take command");
    return null;
  }
  if (!cmdName.isString()) {
    raise_warning("cmdName must be string");
    return null;
  }
  if (!args.isNull() && !args.isArray()) {
    raise_warning("args must be null or array");
    return null;
  }

  static const char *s_allowedCmds[] = {
    "break", "continue", "down", "exception", "frame", "global",
    "help", "info", "konstant", "next", "out", "print", "quit", "step",
    "up", "variable", "where", "bt", "set", "inst", "=", "@", NULL
  };

  bool allowed = false;
  for (int i = 0; ; i++) {
    const char *cmd = s_allowedCmds[i];
    if (cmd == NULL) {
      break;
    }
    if (cmdName.same(cmd)) {
      allowed = true;
      break;
    }
  }
  if (!allowed) {
    raise_warning("unsupported command %s", cmdName.toString().data());
    return null;
  }

  m_client->setCommand(cmdName.toString().data());
  StringVec *clientArgs = m_client->args();
  clientArgs->clear();
  if (!args.isNull()) {
    for (ArrayIter iter(args.toArray()); iter; ++iter) {
      CStrRef arg = iter.second().toString();
      clientArgs->push_back(std::string(arg.data(), arg.size()));
    }
  }
  try {
    if (!m_client->process()) {
      raise_warning("command \"%s\" not found", cmdName.toString().data());
    }
  } catch (DebuggerConsoleExitException &e) {
    // Flow-control command goes here
    Logger::Info("wait for debugger client to stop");
    m_client->setTakingInterrupt();
    m_client->setClientState(DebuggerClient::StateBusy);
    DebuggerCommandPtr cmd = m_client->waitForNextInterrupt();
    if (!cmd) {
      raise_warning("not getting a command");
    } else if (cmd->is(DebuggerCommand::KindOfInterrupt)) {
      CmdInterruptPtr cmdInterrupt = dynamic_pointer_cast<CmdInterrupt>(cmd);
      cmdInterrupt->onClientD(m_client);
    } else {
      // Previous pending commands
      cmd->handleReply(m_client);
      cmd->setClientOutput(m_client);
    }
    Logger::Info("debugger client ready for command");
  } catch (DebuggerClientExitException &e) {
    const std::string& nameStr = m_client->getNameApi();
    Logger::Info("client %s disconnected", nameStr.c_str());
    s_dbgCltMap.erase(nameStr);
    delete m_client;
    m_client = NULL;
    return true;
  } catch (DebuggerProtocolException &e) {
    raise_warning("DebuggerProtocolException");
    return null;
  }

  return m_client->getOutputArray();
}
Пример #25
0
bool Transport::setCookie(CStrRef name, CStrRef value, int64 expire /* = 0 */,
                          CStrRef path /* = "" */, CStrRef domain /* = "" */,
                          bool secure /* = false */,
                          bool httponly /* = false */,
                          bool encode_url /* = true */) {
  if (!name.empty() && strpbrk(name.data(), "=,; \t\r\n\013\014")) {
    Logger::Warning("Cookie names can not contain any of the following "
                    "'=,; \\t\\r\\n\\013\\014'");
    return false;
  }

  if (!encode_url &&
      !value.empty() && strpbrk(value.data(), ",; \t\r\n\013\014")) {
    Logger::Warning("Cookie values can not contain any of the following "
                    "',; \\t\\r\\n\\013\\014'");
    return false;
  }

  char *encoded_value = NULL;
  int len = 0;
  if (!value.empty() && encode_url) {
    int encoded_value_len = value.size();
    encoded_value = url_encode(value.data(), encoded_value_len);
    len += encoded_value_len;
  } else if (!value.empty()) {
    encoded_value = strdup(value.data());
    len += value.size();
  }
  len += path.size();
  len += domain.size();

  std::string cookie;
  cookie.reserve(len + 100);
  if (value.empty()) {
    /*
     * MSIE doesn't delete a cookie when you set it to a null value
     * so in order to force cookies to be deleted, even on MSIE, we
     * pick an expiry date in the past
     */
    String sdt = DateTime(1, true)
      .toString(DateTime::Cookie);
    cookie += name.data();
    cookie += "=deleted; expires=";
    cookie += sdt.data();
  } else {
    cookie += name.data();
    cookie += "=";
    cookie += encoded_value ? encoded_value : "";
    if (expire > 0) {
      if (expire > 253402300799LL) {
        raise_warning("Expiry date cannot have a year greater then 9999");
        return false;
      }
      cookie += "; expires=";
      String sdt = DateTime(expire, true).toString(DateTime::Cookie);
      cookie += sdt.data();
    }
  }

  if (encoded_value) {
    free(encoded_value);
  }

  if (!path.empty()) {
    cookie += "; path=";
    cookie += path.data();
  }
  if (!domain.empty()) {
    cookie += "; domain=";
    cookie += domain.data();
  }
  if (secure) {
    cookie += "; secure";
  }
  if (httponly) {
    cookie += "; httponly";
  }

  m_responseCookies[name.data()] = cookie;
  return true;
}
Пример #26
0
void StringBuffer::append(CStrRef s) {
  // REGISTER_MUTATED() is called by data()
  append(s.data(), s.size());
}
Пример #27
0
bool ConcurrentTableSharedStore::get(CStrRef key, Variant &value) {
  bool stats = RuntimeOption::EnableStats && RuntimeOption::EnableAPCStats;
  bool statsFetch = RuntimeOption::EnableAPCSizeStats &&
                    RuntimeOption::EnableAPCFetchStats;
  const StoreValue *val;
  SharedVariant *svar = NULL;
  ReadLock l(m_lock);
  bool expired = false;
  {
    Map::const_accessor acc;
    if (!m_vars.find(acc, key.data())) {
      if (stats) ServerStats::Log("apc.miss", 1);
      return false;
    } else {
      val = &acc->second;
      if (val->expired()) {
        // Because it only has a read lock on the data, deletion from
        // expiration has to happen after the lock is released
        expired = true;
      } else {
        svar = val->var;
        if (RuntimeOption::ApcAllowObj) {
          // Hold ref here
          svar->incRef();
        }
        value = svar->toLocal();
        if (statsFetch) {
          SharedStoreStats::onGet(key.get(), svar);
        }
      }
    }
  }
  if (expired) {
    if (stats) {
      ServerStats::Log("apc.miss", 1);
    }
    eraseImpl(key, true);
    return false;
  }
  if (stats) {
    ServerStats::Log("apc.hit", 1);
  }

  if (RuntimeOption::ApcAllowObj)  {
    bool statsDetail = RuntimeOption::EnableAPCSizeStats &&
                       RuntimeOption::EnableAPCSizeGroup;
    SharedVariant *converted = svar->convertObj(value);
    if (converted) {
      Map::accessor acc;
      m_vars.find(acc, key.data()); // start a write lock
      StoreValue *sval = &acc->second;
      SharedVariant *sv = sval->var;
      // sv may not be same as svar here because some other thread may have
      // updated it already, check before updating
      if (!sv->isUnserializedObj()) {
        if (statsDetail) {
          SharedStoreStats::onDelete(key.get(), sv, true);
        }
        sval->var = converted;
        sv->decRef();
        if (RuntimeOption::EnableAPCSizeStats) {
          int32 newSize = converted->getSpaceUsage();
          SharedStoreStats::updateDirect(sval->size, newSize);
          sval->size = newSize;
        }
        if (statsDetail) {
          int64 ttl = sval->expiry ? sval->expiry - time(NULL) : 0;
          SharedStoreStats::onStore(key.get(), converted, ttl, false);
        }
      } else {
        converted->decRef();
      }
    }
    // release the extra ref
    svar->decRef();
  }
  return true;
}
Пример #28
0
void f_parse_str(CStrRef str, Variant arr /* = null */) {
  HttpProtocol::DecodeParameters(arr, str.data(), str.size());
}
Пример #29
0
bool TimeZone::IsValid(CStrRef name) {
  return timelib_timezone_id_is_valid((char*)name.data(), GetDatabase());
}
Пример #30
0
Variant f_hphp_invoke(CStrRef name, CArrRef params) {
  return invoke(name.data(), params);
}