Beispiel #1
0
Variant ThisExpression::set(VariableEnvironment &env, CVarRef val) const {
  throw FatalErrorException("Cannot re-assign $this");
}
Beispiel #2
0
CVarRef ArrayData::endRef() {
  if (size_t(m_pos) < size_t(size())) {
    return getValueRef(size() - 1);
  }
  throw FatalErrorException("invalid ArrayData::m_pos");
}
Beispiel #3
0
void ArrayData::uasort(CVarRef cmp_function) {
  throw FatalErrorException("Unimplemented ArrayData::uasort");
}
Beispiel #4
0
OutputFile::OutputFile(const String& filename): File(true, s_php, s_output) {
  if (filename != s_php_output) {
    throw FatalErrorException("not a php://output file ");
  }
  m_isLocal = true;
}
Beispiel #5
0
ArrayData *ArrayData::nonSmartCopy() const {
  throw FatalErrorException("nonSmartCopy not implemented.");
}
Beispiel #6
0
CVarRef ArrayData::endRef() {
  if (m_pos != invalid_index) {
    return getValueRef(iter_end());
  }
  throw FatalErrorException("invalid ArrayData::m_pos");
}
Beispiel #7
0
void ArrayData::ZSetStr(ArrayData* ad, StringData* k, RefData* v) {
  throw FatalErrorException("Unimplemented ArrayData::ZSetStr");
}
ObjectData *FrameInjectionFunction::getThisForArrow() {
  if (ObjectData *obj = getThis()) {
    return obj;
  }
  throw FatalErrorException("Using $this when not in object context");
}
ObjectData *FrameInjectionObjectMethod::getThisForArrow() {
  if (m_object->o_getId()) {
    return m_object;
  }
  throw FatalErrorException("Using $this when not in object context");
}
Beispiel #10
0
int64 MemFile::writeImpl(const char *buffer, int64 length) {
  throw FatalErrorException((string("cannot write a mem stream: ") +
                             m_name).c_str());
}
Beispiel #11
0
bool MemFile::flush() {
  throw FatalErrorException((string("cannot flush a mem stream: ") +
                             m_name).c_str());
}
Beispiel #12
0
void AsioContext::runUntil(c_WaitableWaitHandle* wait_handle) {
  assert(wait_handle);
  assert(wait_handle->getContext() == this);

  auto session = AsioSession::Get();
  auto ete_queue = session->getExternalThreadEventQueue();

  if (!session->hasAbruptInterruptException()) {
    session->initAbruptInterruptException();
  }

  while (!wait_handle->isFinished()) {
    // Run queue of ready async functions once.
    if (!m_runnableQueue.empty()) {
      auto current = m_runnableQueue.back();
      m_runnableQueue.pop_back();
      current->resume();
      continue;
    }

    // Process all sleep handles that have completed their sleep.
    if (session->processSleepEvents()) {
      continue;
    }

    // Process all external thread events that have completed their operation.
    // Queue may contain received unprocessed events from failed runUntil().
    if (UNLIKELY(ete_queue->hasReceived()) || ete_queue->tryReceiveSome()) {
      ete_queue->processAllReceived();
      continue;
    }

    // Run default priority queue once.
    if (runSingle(m_priorityQueueDefault)) {
      continue;
    }

    // Wait for pending external thread events...
    if (!m_externalThreadEvents.empty()) {
      // ...but only until the next sleeper (from any context) finishes.
      auto waketime = session->sleepWakeTime();

      // Wait if necessary.
      if (LIKELY(!ete_queue->hasReceived())) {
        onIOWaitEnter(session);
        ete_queue->receiveSomeUntil(waketime);
        onIOWaitExit(session);
      }

      if (ete_queue->hasReceived()) {
        // Either we didn't have to wait, or we waited but no sleeper timed us
        // out, so just handle the ETEs.
        ete_queue->processAllReceived();
      } else {
        // No received events means the next-to-wake sleeper timed us out.
        session->processSleepEvents();
      }

      continue;
    }

    // If we're here, then the only things left are sleepers.  Wait for one to
    // be ready (in any context).
    if (!m_sleepEvents.empty()) {
      onIOWaitEnter(session);
      std::this_thread::sleep_until(session->sleepWakeTime());
      onIOWaitExit(session);

      session->processSleepEvents();
      continue;
    }

    // Run no-pending-io priority queue once.
    if (runSingle(m_priorityQueueNoPendingIO)) {
      continue;
    }

    // What? The wait handle did not finish? We know it is part of the current
    // context and since there is nothing else to run, it cannot be in RUNNING
    // or SCHEDULED state. So it must be BLOCKED on something. Apparently, the
    // same logic can be used recursively on the something, so there is an
    // infinite chain of blocked wait handles. But our memory is not infinite.
    // What could it possibly mean? I think we are in a deep sh^H^Hcycle.
    // But we can't, the cycles are detected and avoided at blockOn() time.
    // So, looks like it's not cycle, but the word I started typing first.
    assert(false);
    throw FatalErrorException(
      "Invariant violation: queues are empty, but wait handle did not finish");
  }
}
Beispiel #13
0
void AsioContext::runUntil(c_WaitableWaitHandle* wait_handle) {
  assert(!m_current);
  assert(wait_handle);
  assert(wait_handle->getContext() == this);

  auto session = AsioSession::Get();
  uint8_t check_ete_counter = 0;

  while (!wait_handle->isFinished()) {
    // process ready external thread events once per 256 other events
    // (when 8-bit check_ete_counter overflows)
    if (!++check_ete_counter) {
      auto ete_wh = session->getReadyExternalThreadEvents();
      while (ete_wh) {
        auto next_wh = ete_wh->getNextToProcess();
        ete_wh->process();
        ete_wh = next_wh;
      }
    }

    // run queue of ready continuations once
    if (!m_runnableQueue.empty()) {
      auto current = m_runnableQueue.front();
      m_runnableQueue.pop();
      m_current = current;
      m_current->run();
      m_current = nullptr;
      decRefObj(current);
      continue;
    }

    // run default priority queue once
    if (runSingle(m_priorityQueueDefault)) {
      continue;
    }

    // pending external thread events? wait for at least one to become ready
    if (!m_externalThreadEvents.empty()) {
      // all your wait time are belong to us
      auto ete_wh = session->waitForExternalThreadEvents();
      while (ete_wh) {
        auto next_wh = ete_wh->getNextToProcess();
        ete_wh->process();
        ete_wh = next_wh;
      }
      continue;
    }

    // run no-pending-io priority queue once
    if (runSingle(m_priorityQueueNoPendingIO)) {
      continue;
    }

    // What? The wait handle did not finish? We know it is part of the current
    // context and since there is nothing else to run, it cannot be in RUNNING
    // or SCHEDULED state. So it must be BLOCKED on something. Apparently, the
    // same logic can be used recursively on the something, so there is an
    // infinite chain of blocked wait handles. But our memory is not infinite.
    // What could it possibly mean? I think we are in a deep sh^H^Hcycle.
    // But we can't, the cycles are detected and avoided at blockOn() time.
    // So, looks like it's not cycle, but the word I started typing first.
    assert(false);
    throw FatalErrorException(
      "Invariant violation: queues are empty, but wait handle did not finish");
  }
}
bool FunctionCallExpression::exist(VariableEnvironment &env, int op) const {
  throw FatalErrorException(0, "Cannot call %s on a function return value",
                            op == T_ISSET ? "isset" : "empty");
}
CVarRef NameValueTableWrapper::currentRef() {
  if (m_pos != ArrayData::invalid_index) {
    return getValueRef(m_pos);
  }
  throw FatalErrorException("invalid ArrayData::m_pos");
}
Beispiel #16
0
bool TempFile::open(const String& filename, const String& mode) {
  throw FatalErrorException((std::string("cannot open a temp file ") +
                             m_name).c_str());
}
void c_ContinuationWaitHandle::run() {
    // may happen if scheduled in multiple contexts
    if (getState() != STATE_SCHEDULED) {
        return;
    }

    try {
        setState(STATE_RUNNING);

        do {
            // iterate continuation
            if (m_child.isNull()) {
                // first iteration or null dependency
                m_continuation->call_next();
            } else if (m_child->isSucceeded()) {
                // child succeeded, pass the result to the continuation
                m_continuation->call_send(m_child->getResult());
            } else if (m_child->isFailed()) {
                // child failed, raise the exception inside continuation
                m_continuation->call_raise(m_child->getException());
            } else {
                throw FatalErrorException(
                    "Invariant violation: child neither succeeded nor failed");
            }

            // continuation finished, retrieve result from its m_value
            if (m_continuation->m_done) {
                markAsSucceeded(m_continuation->m_value.asTypedValue());
                return;
            }

            // set up dependency
            TypedValue* value = m_continuation->m_value.asTypedValue();
            if (IS_NULL_TYPE(value->m_type)) {
                // null dependency
                m_child = nullptr;
            } else {
                c_WaitHandle* child = c_WaitHandle::fromTypedValue(value);
                if (UNLIKELY(!child)) {
                    Object e(SystemLib::AllocInvalidArgumentExceptionObject(
                                 "Expected yield argument to be an instance of WaitHandle"));
                    throw e;
                }

                AsioSession* session = AsioSession::Get();
                if (UNLIKELY(session->hasOnContinuationYieldCallback())) {
                    session->onContinuationYield(this, child);
                }

                m_child = child;
            }
        } while (m_child.isNull() || m_child->isFinished());

        // we are blocked on m_child so it must be WaitableWaitHandle
        assert(dynamic_cast<c_WaitableWaitHandle*>(m_child.get()));
        blockOn(static_cast<c_WaitableWaitHandle*>(m_child.get()));
    } catch (const Object& exception) {
        // process exception thrown by generator or blockOn cycle detection
        markAsFailed(exception);
    }
}
Variant f_func_get_arg(int arg_num) {
  throw FatalErrorException("bad HPHP code generation");
}
Beispiel #19
0
void ArrayData::ZSetInt(ArrayData* ad, int64_t k, RefData* v) {
  throw FatalErrorException("Unimplemented ArrayData::ZSetInt");
}
Array f_func_get_args() {
  throw FatalErrorException("bad HPHP code generation");
}
Beispiel #21
0
void ArrayData::ZAppend(ArrayData* ad, RefData* v) {
  throw FatalErrorException("Unimplemented ArrayData::ZAppend");
}
Beispiel #22
0
void Expression::byteCodeRefval(ByteCodeProgram &code) const {
  throw FatalErrorException("Cannot compile %s:%d", m_loc.file, m_loc.line1);

}
Beispiel #23
0
bool OutputFile::open(const String& filename, const String& mode) {
  throw FatalErrorException("cannot open a php://output file ");
}
Beispiel #24
0
void StringData::append(const char *s, int len) {
  ASSERT(!isStatic()); // never mess around with static strings!
  if (len == 0) return;
  if (UNLIKELY(uint32_t(len) > MaxSize)) {
    throw InvalidArgumentException("len>=2^30", len);
  }
  if (UNLIKELY(len + m_len > MaxSize)) {
    throw FatalErrorException(0, "String length exceeded 2^30 - 1: %u",
                              len + m_len);
  }
  int newlen;
  // TODO: t1122987: in any of the cases below where we need a bigger buffer,
  // we can probably assume we're in a concat-loop and pick a good buffer
  // size to avoid O(N^2) copying cost.
  if (isShared() || isLiteral()) {
    // buffer is immutable, don't modify it.
    // We are mutating, so we don't need to repropagate our own taint
    StringSlice r = slice();
    char* newdata = string_concat(r.ptr, r.len, s, len, newlen);
    if (isShared()) m_big.shared->decRef();
    m_len = newlen;
    m_data = newdata;
    m_big.cap = newlen | IsMalloc;
    m_hash = 0;
  } else if (rawdata() == s) {
    // appending ourself to ourself, be conservative.
    // We are mutating, so we don't need to repropagate our own taint
    StringSlice r = slice();
    char *newdata = string_concat(r.ptr, r.len, s, len, newlen);
    releaseData();
    m_len = newlen;
    m_data = newdata;
    m_big.cap = newlen | IsMalloc;
    m_hash = 0;
  } else if (isSmall()) {
    // we're currently small but might not be after append.
    // We are mutating, so we don't need to repropagate our own taint
    int oldlen = m_len;
    newlen = oldlen + len;
    if (unsigned(newlen) <= MaxSmallSize) {
      // win.
      memcpy(&m_small[oldlen], s, len);
      m_small[newlen] = 0;
      m_small[MaxSmallSize] = 0;
      m_len = newlen;
      m_data = m_small;
      m_hash = 0;
    } else {
      // small->big string transition.
      char *newdata = string_concat(m_small, oldlen, s, len, newlen);
      m_len = newlen;
      m_data = newdata;
      m_big.cap = newlen | IsMalloc;
      m_hash = 0;
    }
  } else {
    // generic "big string concat" path.  realloc buffer.
    int oldlen = m_len;
    char* oldp = m_data;
    ASSERT((oldp > s && oldp - s > len) ||
           (oldp < s && s - oldp > oldlen)); // no overlapping
    newlen = oldlen + len;
    char* newdata = (char*) realloc(oldp, newlen + 1);
    memcpy(newdata + oldlen, s, len);
    newdata[newlen] = 0;
    m_len = newlen;
    m_data = newdata;
    m_big.cap = newlen | IsMalloc;
    m_hash = 0;
  }
  ASSERT(uint32_t(newlen) <= MaxSize);
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, rawdata());
  ASSERT(checkSane());
}
Beispiel #25
0
ArrayData *ArrayData::lvalPtr(StringData* k, Variant *&ret, bool copy,
                              bool create) {
  throw FatalErrorException("Unimplemented ArrayData::lvalPtr");
}
Beispiel #26
0
ArrayData*
GlobalsArray::CopyWithStrongIterators(const ArrayData* ad) {
  throw FatalErrorException(
    "Unimplemented ArrayData::copyWithStrongIterators");
}
Beispiel #27
0
void ArrayData::asort(int sort_flags, bool ascending) {
  throw FatalErrorException("Unimplemented ArrayData::asort");
}
Beispiel #28
0
ArrayData* GlobalsArray::CopyStatic(const ArrayData*) {
  throw FatalErrorException("GlobalsArray::copyStatic "
    "not implemented.");
}
Beispiel #29
0
ArrayData* ArrayData::copyWithStrongIterators() const {
  throw FatalErrorException("Unimplemented ArrayData::copyWithStrongIterators");
}
void HttpRequestHandler::handleRequest(Transport *transport) {
  ExecutionProfiler ep(ThreadInfo::RuntimeFunctions);

  Logger::OnNewRequest();
  GetAccessLog().onNewRequest();
  transport->enableCompression();

  ServerStatsHelper ssh("all", true);
  Logger::Verbose("receiving %s", transport->getCommand().c_str());

  // will clear all extra logging when this function goes out of scope
  StackTraceNoHeap::ExtraLoggingClearer clearer;
  StackTraceNoHeap::AddExtraLogging("URL", transport->getUrl());

  // resolve virtual host
  const VirtualHost *vhost = HttpProtocol::GetVirtualHost(transport);
  ASSERT(vhost);
  if (vhost->disabled() ||
      vhost->isBlocking(transport->getCommand(), transport->getRemoteHost())) {
    transport->sendString("Not Found", 404);
    return;
  }
  ServerStats::StartRequest(transport->getCommand().c_str(),
                            transport->getRemoteHost(),
                            vhost->getName().c_str());

  // resolve source root
  string host = transport->getHeader("Host");
  SourceRootInfo sourceRootInfo(host.c_str());

  if (sourceRootInfo.error()) {
    sourceRootInfo.handleError(transport);
    return;
  }

  // request URI
  string pathTranslation = m_pathTranslation ?
    vhost->getPathTranslation().c_str() : "";
  RequestURI reqURI(vhost, transport, sourceRootInfo.path(), pathTranslation);
  if (reqURI.done()) {
    return; // already handled with redirection or 404
  }
  string path = reqURI.path().data();
  string absPath = reqURI.absolutePath().data();

  // determine whether we should compress response
  bool compressed = transport->decideCompression();

  const char *data; int len;
  size_t pos = path.rfind('.');
  const char *ext =
    (pos != string::npos) &&
    path.find('/', pos) == string::npos // no extention in ./foo or ../bar
      ? (path.c_str() + pos + 1) : NULL;
  bool cachableDynamicContent =
    (!RuntimeOption::StaticFileGenerators.empty() &&
     RuntimeOption::StaticFileGenerators.find(path) !=
     RuntimeOption::StaticFileGenerators.end());

  // If this is not a php file, check the static and dynamic content caches
  if (ext && strcasecmp(ext, "php") != 0) {
    if (RuntimeOption::EnableStaticContentCache) {
      bool original = compressed;
      // check against static content cache
      if (StaticContentCache::TheCache.find(path, data, len, compressed)) {
        struct stat st;
        st.st_mtime = 0;
        String str;
        // (qigao) not calling stat at this point because the timestamp of
        // local cache file is not valuable, maybe misleading. This way
        // the Last-Modified header will not show in response.
        // stat(RuntimeOption::FileCache.c_str(), &st);
        if (!original && compressed) {
          data = gzdecode(data, len);
          if (data == NULL) {
            throw FatalErrorException("cannot unzip compressed data");
          }
          compressed = false;
          str = NEW(StringData)(data, len, AttachString);
        }
        sendStaticContent(transport, data, len, st.st_mtime, compressed, path);
        StaticContentCache::TheFileCache->adviseOutMemory();
        ServerStats::LogPage(path, 200);
        return;
      }
    }

    if (RuntimeOption::EnableStaticContentFromDisk) {
      String translated = File::TranslatePath(String(absPath));
      if (!translated.empty()) {
        StringBuffer sb(translated.data());
        if (sb.valid()) {
          struct stat st;
          st.st_mtime = 0;
          stat(translated.data(), &st);
          sendStaticContent(transport, sb.data(), sb.size(), st.st_mtime,
                            false, path);
          ServerStats::LogPage(path, 200);
          return;
        }
      }
    }

    // check static contents that were generated by dynamic pages
    if (cachableDynamicContent) {
      // check against dynamic content cache
      ASSERT(transport->getUrl());
      string key = path + transport->getUrl();
      if (DynamicContentCache::TheCache.find(key, data, len, compressed)) {
        sendStaticContent(transport, data, len, 0, compressed, path);
        ServerStats::LogPage(path, 200);
        return;
      }
    }
  }

  // proxy any URLs that not specified in ServeURLs
  if (!RuntimeOption::ProxyOrigin.empty() &&
      ((RuntimeOption::UseServeURLs &&
        RuntimeOption::ServeURLs.find(path) ==
        RuntimeOption::ServeURLs.end()) ||
       (RuntimeOption::UseProxyURLs &&
        (RuntimeOption::ProxyURLs.find(path) !=
         RuntimeOption::ProxyURLs.end() ||
         MatchAnyPattern(path, RuntimeOption::ProxyPatterns) ||
         (abs(rand()) % 100) < RuntimeOption::ProxyPercentage)))) {
    for (int i = 0; i < RuntimeOption::ProxyRetry; i++) {
      bool force = (i == RuntimeOption::ProxyRetry - 1); // last one
      if (handleProxyRequest(transport, force)) break;
    }
    return;
  }

  // record request for debugging purpose
  std::string tmpfile = HttpProtocol::RecordRequest(transport);

  // main body
  hphp_session_init();
  vhost->setRequestTimeoutSeconds();

  bool ret = false;
  try {
    ret = executePHPRequest(transport, reqURI, sourceRootInfo,
                            cachableDynamicContent);
  } catch (const Eval::DebuggerException &e) {
    transport->sendString(e.what(), 200);
    transport->onSendEnd();
    hphp_context_exit(g_context.getNoCheck(), true, true, transport->getUrl());
  } catch (...) {
    Logger::Error("Unhandled exception in HPHP server engine.");
  }
  GetAccessLog().log(transport, vhost);
  hphp_session_exit();

  HttpProtocol::ClearRecord(ret, tmpfile);
}