예제 #1
0
파일: AsyncIO.cpp 프로젝트: zunc/folly
Range<AsyncIO::Op**> AsyncIO::pollCompleted() {
  CHECK(ctx_);
  CHECK_NE(pollFd_, -1) << "pollCompleted() only allowed on pollable object";
  uint64_t numEvents;
  // This sets the eventFd counter to 0, see
  // http://www.kernel.org/doc/man-pages/online/pages/man2/eventfd.2.html
  ssize_t rc;
  do {
    rc = ::read(pollFd_, &numEvents, 8);
  } while (rc == -1 && errno == EINTR);
  if (UNLIKELY(rc == -1 && errno == EAGAIN)) {
    return Range<Op**>();  // nothing completed
  }
  checkUnixError(rc, "AsyncIO: read from event fd failed");
  DCHECK_EQ(rc, 8);

  DCHECK_GT(numEvents, 0);
  DCHECK_LE(numEvents, pending_);

  // Don't reap more than numEvents, as we've just reset the counter to 0.
  return doWait(numEvents, numEvents);
}
예제 #2
0
파일: String.cpp 프로젝트: Aliced3645/folly
size_t hexDumpLine(const void* ptr, size_t offset, size_t size,
                   std::string& line) {
  // Line layout:
  // 8: address
  // 1: space
  // (1+2)*16: hex bytes, each preceded by a space
  // 1: space separating the two halves
  // 3: "  |"
  // 16: characters
  // 1: "|"
  // Total: 78
  line.clear();
  line.reserve(78);
  const uint8_t* p = reinterpret_cast<const uint8_t*>(ptr) + offset;
  size_t n = std::min(size - offset, size_t(16));
  format("{:08x} ", offset).appendTo(line);

  for (size_t i = 0; i < n; i++) {
    if (i == 8) {
      line.push_back(' ');
    }
    format(" {:02x}", p[i]).appendTo(line);
  }

  // 3 spaces for each byte we're not printing, one separating the halves
  // if necessary
  line.append(3 * (16 - n) + (n <= 8), ' ');
  line.append("  |");

  for (size_t i = 0; i < n; i++) {
    char c = (p[i] >= 32 && p[i] <= 126 ? static_cast<char>(p[i]) : '.');
    line.push_back(c);
  }
  line.append(16 - n, ' ');
  line.push_back('|');
  DCHECK_EQ(line.size(), 78);

  return n;
}
예제 #3
0
 void acquire_reply( size_t offset, void * payload, size_t payload_size ) { 
   DVLOG(5) << "Worker " << Grappa::current_worker() 
            << " copying reply payload of " << payload_size
            << " and waking Worker " << thread_;
   memcpy( ((char*)(*pointer_)) + offset, payload, payload_size );
   ++response_count_;
   total_reply_payload_ += payload_size;
   if ( response_count_ == num_messages_ ) {
     DCHECK_EQ( total_reply_payload_, expected_reply_payload_ ) << "Got back the wrong amount of data "
                                                                << "(with base = " << *request_address_
                                                                << " and sizeof(T) = " << sizeof(T) 
                                                                << " and count = " << *count_;
     acquired_ = true;
     if( thread_ != NULL ) {
       Grappa::wake( thread_ );
     }
     if( start_time_ != 0 ) {
       network_time_ = Grappa::timestamp();
       IAMetrics::record_network_latency( start_time_ );
     }
   }
 }
예제 #4
0
void ResourceLoader::requestSynchronously(const ResourceRequest& request) {
  // downloadToFile is not supported for synchronous requests.
  DCHECK(!request.downloadToFile());
  DCHECK(m_loader);
  DCHECK_EQ(request.priority(), ResourceLoadPriorityHighest);

  WrappedResourceRequest requestIn(request);
  WebURLResponse responseOut;
  WebURLError errorOut;
  WebData dataOut;
  int64_t encodedDataLength = WebURLLoaderClient::kUnknownEncodedDataLength;
  int64_t encodedBodyLength = 0;
  m_loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut,
                              encodedDataLength, encodedBodyLength);

  // A message dispatched while synchronously fetching the resource
  // can bring about the cancellation of this load.
  if (!m_loader)
    return;
  if (errorOut.reason) {
    didFail(errorOut, encodedDataLength, encodedBodyLength);
    return;
  }
  didReceiveResponse(responseOut);
  if (!m_loader)
    return;
  DCHECK_GE(responseOut.toResourceResponse().encodedBodyLength(), 0);

  // Follow the async case convention of not calling didReceiveData or
  // appending data to m_resource if the response body is empty. Copying the
  // empty buffer is a noop in most cases, but is destructive in the case of
  // a 304, where it will overwrite the cached data we should be reusing.
  if (dataOut.size()) {
    m_fetcher->didReceiveData(m_resource.get(), dataOut.data(), dataOut.size());
    m_resource->setResourceBuffer(dataOut);
  }
  didFinishLoading(monotonicallyIncreasingTime(), encodedDataLength,
                   encodedBodyLength);
}
  PassRefPtr<CSSTransformNonInterpolableValue> composite(
      const CSSTransformNonInterpolableValue& other,
      double otherProgress) {
    DCHECK(!isAdditive());
    if (other.m_isSingle) {
      DCHECK_EQ(otherProgress, 0);
      DCHECK(other.isAdditive());
      TransformOperations result;
      result.operations() = concat(transform(), other.transform());
      return create(std::move(result));
    }

    DCHECK(other.m_isStartAdditive || other.m_isEndAdditive);
    TransformOperations start;
    start.operations() = other.m_isStartAdditive
                             ? concat(transform(), other.m_start)
                             : other.m_start.operations();
    TransformOperations end;
    end.operations() = other.m_isEndAdditive ? concat(transform(), other.m_end)
                                             : other.m_end.operations();
    return create(end.blend(start, otherProgress));
  }
bool FileManagerWindows::writeBlockOrBlob(const block_id block,
                                          const void *buffer,
                                          const size_t length) {
  DCHECK(buffer != nullptr);
  DCHECK_EQ(0u, length % kSlotSizeBytes);

  const string filename(blockFilename(block));

  FILE *file = fopen(filename.c_str(), "wb");
  if (file == nullptr) {
    // Note: On most, but not all, library implementations, the errno variable
    //       is set to a system-specific error code on failure.
    LOG(ERROR) << "Failed to open file " << filename << " with error: " << strerror(errno);
    return false;
  }

  const size_t bytes = std::fwrite(buffer, sizeof(char), length, file);
  const bool result_is_ok = (bytes == length);
  if (!result_is_ok) {
    LOG(ERROR) << "Failed to write file " << filename << " with error: " << strerror(ferror(file));
    clearerr(file);
  }

  if (fflush(file)) {
    LOG(ERROR) << "Failed to flush file " << filename << " with error: " << strerror(ferror(file));
  }

  if (!FlushFileBuffers(reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(file))))) {
    LOG(ERROR) << "Failed to re-flush file " << filename << " with error: " << strerror(ferror(file));
  }

  if (fclose(file)) {
    // Note: fclose does not set errno on failure.
    LOG(ERROR) << "Failed to close file " << filename;
  }

  return result_is_ok;
}
예제 #7
0
char* Pickle::BeginWriteData(int length)
{
    DCHECK_EQ(variable_buffer_offset_, 0U) <<
        "There can only be one variable buffer in a Pickle";

    if(length<0 || !WriteInt(length))
    {
        return NULL;
    }

    char* data_ptr = BeginWrite(length);
    if(!data_ptr)
    {
        return NULL;
    }

    variable_buffer_offset_ = data_ptr -
        reinterpret_cast<char*>(header_) - sizeof(int);

    // 数据写入后不必要再调用EndWrite, 所以在这里调用进行数据对齐.
    EndWrite(data_ptr, length);
    return data_ptr;
}
예제 #8
0
// Helper function. Must take a lowercase language as input.
static bool isLegacySupportedJavaScriptLanguage(const String& language)
{
    // Mozilla 1.8 accepts javascript1.0 - javascript1.7, but WinIE 7 accepts only javascript1.1 - javascript1.3.
    // Mozilla 1.8 and WinIE 7 both accept javascript and livescript.
    // WinIE 7 accepts ecmascript and jscript, but Mozilla 1.8 doesn't.
    // Neither Mozilla 1.8 nor WinIE 7 accept leading or trailing whitespace.
    // We want to accept all the values that either of these browsers accept, but not other values.

    // FIXME: This function is not HTML5 compliant. These belong in the MIME registry as "text/javascript<version>" entries.
    DCHECK_EQ(language, language.lower());
    return language == "javascript"
        || language == "javascript1.0"
        || language == "javascript1.1"
        || language == "javascript1.2"
        || language == "javascript1.3"
        || language == "javascript1.4"
        || language == "javascript1.5"
        || language == "javascript1.6"
        || language == "javascript1.7"
        || language == "livescript"
        || language == "ecmascript"
        || language == "jscript";
}
예제 #9
0
void SVGFilterRecordingContext::endContent(FilterData* filterData) {
  DCHECK_EQ(filterData->m_state, FilterData::RecordingContent);

  Filter* filter = filterData->lastEffect->getFilter();
  SourceGraphic* sourceGraphic = filter->getSourceGraphic();
  DCHECK(sourceGraphic);

  // Use the context that contains the filtered content.
  DCHECK(m_paintController);
  DCHECK(m_context);
  m_context->beginRecording(filter->filterRegion());
  m_paintController->commitNewDisplayItems();
  m_paintController->paintArtifact().replay(*m_context);

  SkiaImageFilterBuilder::buildSourceGraphic(sourceGraphic,
                                             m_context->endRecording());

  // Content is cached by the source graphic so temporaries can be freed.
  m_paintController = nullptr;
  m_context = nullptr;

  filterData->m_state = FilterData::ReadyToPaint;
}
예제 #10
0
void ReadableStreamOperations::tee(ScriptState* scriptState,
                                   ScriptValue stream,
                                   ScriptValue* newStream1,
                                   ScriptValue* newStream2) {
  DCHECK(isReadableStream(scriptState, stream));
  DCHECK(!isLocked(scriptState, stream));

  v8::Local<v8::Value> args[] = {stream.v8Value()};

  ScriptValue result(scriptState, V8ScriptRunner::callExtraOrCrash(
                                      scriptState, "ReadableStreamTee", args));
  DCHECK(result.v8Value()->IsArray());
  v8::Local<v8::Array> branches = result.v8Value().As<v8::Array>();
  DCHECK_EQ(2u, branches->Length());

  *newStream1 = ScriptValue(
      scriptState, branches->Get(scriptState->context(), 0).ToLocalChecked());
  *newStream2 = ScriptValue(
      scriptState, branches->Get(scriptState->context(), 1).ToLocalChecked());

  DCHECK(isReadableStream(scriptState, *newStream1));
  DCHECK(isReadableStream(scriptState, *newStream2));
}
예제 #11
0
// static
void BrowserList::AddBrowser(Browser* browser)
{
    DCHECK(browser);
    browsers_.push_back(browser);
	StartKeepAlive();

    //if(!activity_observer)
    //{
    //    activity_observer = new BrowserActivityObserver;
    //}

    //NotificationService::current()->Notify(
    //    chrome::NOTIFICATION_BROWSER_OPENED,
    //    Source<Browser>(browser),
    //    NotificationService::NoDetails());

    // Send out notifications after add has occurred. Do some basic checking to
    // try to catch evil observers that change the list from under us.
    size_t original_count = observers_.size();
    FOR_EACH_OBSERVER(Observer, observers_, OnBrowserAdded(browser));
    DCHECK_EQ(original_count, observers_.size())
        << "observer list modified during notification";
}
예제 #12
0
파일: AsyncIO.cpp 프로젝트: GYGit/folly
void AsyncIO::submit(Op* op) {
  CHECK_EQ(op->state(), Op::State::INITIALIZED);
  initializeContext();  // on demand

  // We can increment past capacity, but we'll clean up after ourselves.
  auto p = pending_.fetch_add(1, std::memory_order_acq_rel);
  if (p >= capacity_) {
    decrementPending();
    throw std::range_error("AsyncIO: too many pending requests");
  }
  iocb* cb = &op->iocb_;
  cb->data = nullptr;  // unused
  if (pollFd_ != -1) {
    io_set_eventfd(cb, pollFd_);
  }
  int rc = io_submit(ctx_, 1, &cb);
  if (rc < 0) {
    decrementPending();
    throwSystemErrorExplicit(-rc, "AsyncIO: io_submit failed");
  }
  submitted_++;
  DCHECK_EQ(rc, 1);
  op->start();
}
예제 #13
0
void ProcessingInstruction::removedFrom(ContainerNode* insertionPoint) {
  CharacterData::removedFrom(insertionPoint);
  if (!insertionPoint->isConnected())
    return;

  // No need to remove XSLStyleSheet from StyleEngine.
  if (!DocumentXSLT::processingInstructionRemovedFromDocument(document(), this))
    document().styleEngine().removeStyleSheetCandidateNode(*this);

  StyleSheet* removedSheet = m_sheet;
  if (m_sheet) {
    DCHECK_EQ(m_sheet->ownerNode(), this);
    clearSheet();
  }

  // No need to remove pending sheets.
  clearResource();

  // If we're in document teardown, then we don't need to do any notification of
  // our sheet's removal.
  if (document().isActive())
    document().styleEngine().setNeedsActiveStyleUpdate(removedSheet,
                                                       FullStyleUpdate);
}
예제 #14
0
void RadioButtonGroupScope::addButton(HTMLInputElement* element) {
  DCHECK_EQ(element->type(), InputTypeNames::radio);
  if (element->name().isEmpty())
    return;

  if (!m_nameToGroupMap)
    m_nameToGroupMap = new NameToGroupMap;

  auto keyValue = m_nameToGroupMap->add(element->name(), nullptr).storedValue;
  if (!keyValue->value) {
    keyValue->value = RadioButtonGroup::create();
  } else {
    if (keyValue->key == element->name())
      UseCounter::count(element->document(),
                        UseCounter::RadioNameMatchingStrict);
    else if (equalIgnoringASCIICase(keyValue->key, element->name()))
      UseCounter::count(element->document(),
                        UseCounter::RadioNameMatchingASCIICaseless);
    else
      UseCounter::count(element->document(),
                        UseCounter::RadioNameMatchingCaseFolding);
  }
  keyValue->value->add(element);
}
예제 #15
0
PositionTemplate<Strategy>
PositionIteratorAlgorithm<Strategy>::computePosition() const {
  DCHECK(isValid());
  // Assume that we have the following DOM tree:
  // A
  // |-B
  // | |-E
  // | +-F
  // |
  // |-C
  // +-D
  //   |-G
  //   +-H
  if (m_nodeAfterPositionInAnchor) {
    // For example, position is before E, F.
    DCHECK_EQ(Strategy::parent(*m_nodeAfterPositionInAnchor), m_anchorNode);
    DCHECK_NE(m_offsetsInAnchorNode[m_depthToAnchorNode], kInvalidOffset);
    // TODO(yoichio): This should be equivalent to
    // PositionTemplate<Strategy>(m_anchorNode,
    // PositionAnchorType::BeforeAnchor);
    return PositionTemplate<Strategy>(
        m_anchorNode, m_offsetsInAnchorNode[m_depthToAnchorNode]);
  }
  if (Strategy::hasChildren(*m_anchorNode))
    // For example, position is the end of B.
    return PositionTemplate<Strategy>::lastPositionInOrAfterNode(m_anchorNode);
  if (m_anchorNode->isTextNode())
    return PositionTemplate<Strategy>(m_anchorNode, m_offsetInAnchor);
  if (m_offsetInAnchor)
    // For example, position is after G.
    return PositionTemplate<Strategy>(m_anchorNode,
                                      PositionAnchorType::AfterAnchor);
  // For example, position is before G.
  return PositionTemplate<Strategy>(m_anchorNode,
                                    PositionAnchorType::BeforeAnchor);
}
예제 #16
0
DocumentWriter* DocumentLoader::createWriterFor(
    const DocumentInit& init,
    const AtomicString& mimeType,
    const AtomicString& encoding,
    bool dispatchWindowObjectAvailable,
    ParserSynchronizationPolicy parsingPolicy,
    const KURL& overridingURL) {
  LocalFrame* frame = init.frame();

  DCHECK(!frame->document() || !frame->document()->isActive());
  DCHECK_EQ(frame->tree().childCount(), 0u);

  if (!init.shouldReuseDefaultView())
    frame->setDOMWindow(LocalDOMWindow::create(*frame));

  Document* document =
      frame->localDOMWindow()->installNewDocument(mimeType, init);

  if (!init.shouldReuseDefaultView())
    frame->page()->chromeClient().installSupplements(*frame);

  // This should be set before receivedFirstData().
  if (!overridingURL.isEmpty())
    frame->document()->setBaseURLOverride(overridingURL);

  frame->loader().didInstallNewDocument(dispatchWindowObjectAvailable);

  // This must be called before DocumentWriter is created, otherwise HTML parser
  // will use stale values from HTMLParserOption.
  if (!dispatchWindowObjectAvailable)
    frame->loader().receivedFirstData();

  frame->loader().didBeginDocument();

  return DocumentWriter::create(document, parsingPolicy, mimeType, encoding);
}
HTMLElement* ScriptCustomElementDefinition::createElementSync(
    Document& document,
    const QualifiedName& tagName,
    ExceptionState& exceptionState) {
  DCHECK(ScriptState::current(m_scriptState->isolate()) == m_scriptState);

  // Create an element
  // https://dom.spec.whatwg.org/#concept-create-element
  // 6. If definition is non-null
  // 6.1. If the synchronous custom elements flag is set:
  // 6.1.2. Set result to Construct(C). Rethrow any exceptions.

  // Create an element and push to the construction stack.
  // V8HTMLElement::constructorCustom() can only refer to
  // window.document(), but it is different from the document here
  // when it is an import document.  This is not exactly what the
  // spec defines, but the public behavior matches to the spec.
  Element* element = createElementForConstructor(document);
  {
    ConstructionStackScope constructionStackScope(this, element);
    v8::TryCatch tryCatch(m_scriptState->isolate());
    element = runConstructor();
    if (tryCatch.HasCaught()) {
      exceptionState.rethrowV8Exception(tryCatch.Exception());
      return nullptr;
    }
  }

  // 6.1.3. through 6.1.9.
  checkConstructorResult(element, document, tagName, exceptionState);
  if (exceptionState.hadException())
    return nullptr;

  DCHECK_EQ(element->getCustomElementState(), CustomElementState::Custom);
  return toHTMLElement(element);
}
예제 #18
0
IDBTransaction::IDBTransaction(ScriptState* scriptState,
                               int64_t id,
                               const HashSet<String>& scope,
                               WebIDBTransactionMode mode,
                               IDBDatabase* db)
    : ActiveScriptWrappable(this),
      ActiveDOMObject(scriptState->getExecutionContext()),
      m_id(id),
      m_database(db),
      m_mode(mode),
      m_scope(scope) {
  DCHECK(m_database);
  DCHECK(!m_scope.isEmpty()) << "Non-versionchange transactions must operate "
                                "on a well-defined set of stores";
  DCHECK(m_mode == WebIDBTransactionModeReadOnly ||
         m_mode == WebIDBTransactionModeReadWrite)
      << "Invalid transaction mode";

  DCHECK_EQ(m_state, Active);
  V8PerIsolateData::from(scriptState->isolate())
      ->addEndOfScopeTask(DeactivateTransactionTask::create(this));

  m_database->transactionCreated(this);
}
예제 #19
0
void IDBTransaction::indexDeleted(IDBIndex* index) {
  DCHECK(index);
  DCHECK(!index->isDeleted()) << "indexDeleted called twice for the same index";

  IDBObjectStore* objectStore = index->objectStore();
  DCHECK_EQ(objectStore->transaction(), this);
  DCHECK(m_objectStoreMap.contains(objectStore->name()))
      << "An index was deleted without accessing its object store";

  const auto& objectStoreIterator = m_oldStoreMetadata.find(objectStore);
  if (objectStoreIterator == m_oldStoreMetadata.end()) {
    // The index's object store was created in this transaction, so this
    // index was also created (and deleted) in this transaction, and will
    // not be restored if the transaction aborts.
    //
    // Subtle proof for the first sentence above: Deleting an index requires
    // calling deleteIndex() on the store's IDBObjectStore instance.
    // Whenever we create an IDBObjectStore instance for a previously
    // created store, we snapshot the store's metadata. So, deleting an
    // index of an "old" store can only be done after the store's metadata
    // is snapshotted.
    return;
  }

  const IDBObjectStoreMetadata* oldStoreMetadata =
      objectStoreIterator->value.get();
  DCHECK(oldStoreMetadata);
  if (!oldStoreMetadata->indexes.contains(index->id())) {
    // The index's object store was created before this transaction, but the
    // index was created (and deleted) in this transaction, so it will not
    // be restored if the transaction aborts.
    return;
  }

  m_deletedIndexes.append(index);
}
예제 #20
0
uint32_t StaticMetaBase::allocate(EntryID* ent) {
  uint32_t id;
  auto& meta = *this;
  std::lock_guard<std::mutex> g(meta.lock_);

  id = ent->value.load();
  if (id != kEntryIDInvalid) {
    return id;
  }

  if (!meta.freeIds_.empty()) {
    id = meta.freeIds_.back();
    meta.freeIds_.pop_back();
  } else {
    id = meta.nextId_++;
  }

  uint32_t old_id = ent->value.exchange(id);
  DCHECK_EQ(old_id, kEntryIDInvalid);

  reserveHeadUnlocked(id);

  return id;
}
예제 #21
0
void ContextLifecycleNotifier::notifyResumingActiveDOMObjects()
{
    TemporaryChange<IterationType> scope(m_iterating, IteratingOverAll);
    Vector<UntracedMember<ContextLifecycleObserver>> snapshotOfObservers;
    copyToVector(m_observers, snapshotOfObservers);
    for (ContextLifecycleObserver* observer : snapshotOfObservers) {
        // FIXME: Oilpan: At the moment, it's possible that a ActiveDOMObject
        // observer is destructed while iterating. Once we enable Oilpan by default
        // for all LifecycleObserver<T>s, we can remove the hack by making m_observers
        // a HeapHashSet<WeakMember<LifecycleObserver<T>>>.
        // (i.e., we can just iterate m_observers without taking a snapshot).
        // For more details, see https://codereview.chromium.org/247253002/.
        if (m_observers.contains(observer)) {
            if (observer->observerType() != ContextLifecycleObserver::ActiveDOMObjectType)
                continue;
            ActiveDOMObject* activeDOMObject = static_cast<ActiveDOMObject*>(observer);
#if DCHECK_IS_ON()
            DCHECK_EQ(activeDOMObject->getExecutionContext(), context());
            DCHECK(activeDOMObject->suspendIfNeededCalled());
#endif
            activeDOMObject->resume();
        }
    }
}
예제 #22
0
void IDatabase::LoadContent(const events_info::LoadDatabaseContentRequest& req) {
  DCHECK_EQ(req.inf, info_);

  server_->LoadDatabaseContent(req);
}
예제 #23
0
DispatchEventResult EventDispatchMediator::dispatchEvent(
    EventDispatcher& dispatcher) const {
  DCHECK_EQ(m_event.get(), &dispatcher.event());
  return dispatcher.dispatch();
}
예제 #24
0
// In this method, we can clear |request| to tell content::WebURLLoaderImpl of
// Chromium not to follow the redirect. This works only when this method is
// called by RawResource::willSendRequest(). If called by
// RawResource::didAddClient(), clearing |request| won't be propagated to
// content::WebURLLoaderImpl. So, this loader must also get detached from the
// resource by calling clearResource().
bool DocumentThreadableLoader::redirectReceived(
    Resource* resource,
    const ResourceRequest& request,
    const ResourceResponse& redirectResponse) {
  DCHECK(m_client);
  DCHECK_EQ(resource, this->resource());
  DCHECK(m_async);

  m_checker.redirectReceived();

  if (!m_actualRequest.isNull()) {
    reportResponseReceived(resource->identifier(), redirectResponse);

    handlePreflightFailure(redirectResponse.url().getString(),
                           "Response for preflight is invalid (redirect)");

    return false;
  }

  if (m_redirectMode == WebURLRequest::FetchRedirectModeManual) {
    // We use |m_redirectMode| to check the original redirect mode. |request| is
    // a new request for redirect. So we don't set the redirect mode of it in
    // WebURLLoaderImpl::Context::OnReceivedRedirect().
    DCHECK(request.useStreamOnResponse());
    // There is no need to read the body of redirect response because there is
    // no way to read the body of opaque-redirect filtered response's internal
    // response.
    // TODO(horo): If we support any API which expose the internal body, we will
    // have to read the body. And also HTTPCache changes will be needed because
    // it doesn't store the body of redirect responses.
    responseReceived(resource, redirectResponse,
                     WTF::makeUnique<EmptyDataHandle>());

    if (m_client) {
      DCHECK(m_actualRequest.isNull());
      notifyFinished(resource);
    }

    return false;
  }

  if (m_redirectMode == WebURLRequest::FetchRedirectModeError) {
    ThreadableLoaderClient* client = m_client;
    clear();
    client->didFailRedirectCheck();

    return false;
  }

  // Allow same origin requests to continue after allowing clients to audit the
  // redirect.
  if (isAllowedRedirect(request.url())) {
    m_client->didReceiveRedirectTo(request.url());
    if (m_client->isDocumentThreadableLoaderClient()) {
      return static_cast<DocumentThreadableLoaderClient*>(m_client)
          ->willFollowRedirect(request, redirectResponse);
    }
    return true;
  }

  if (m_corsRedirectLimit <= 0) {
    ThreadableLoaderClient* client = m_client;
    clear();
    client->didFailRedirectCheck();
    return false;
  }

  --m_corsRedirectLimit;

  InspectorInstrumentation::didReceiveCORSRedirectResponse(
      document().frame(), resource->identifier(),
      document().frame()->loader().documentLoader(), redirectResponse,
      resource);

  bool allowRedirect = false;
  String accessControlErrorDescription;

  if (!CrossOriginAccessControl::isLegalRedirectLocation(
          request.url(), accessControlErrorDescription)) {
    accessControlErrorDescription =
        "Redirect from '" + redirectResponse.url().getString() +
        "' has been blocked by CORS policy: " + accessControlErrorDescription;
  } else if (!m_sameOriginRequest &&
             !passesAccessControlCheck(
                 redirectResponse, effectiveAllowCredentials(),
                 getSecurityOrigin(), accessControlErrorDescription,
                 m_requestContext)) {
    // The redirect response must pass the access control check if the original
    // request was not same-origin.
    accessControlErrorDescription =
        "Redirect from '" + redirectResponse.url().getString() + "' to '" +
        request.url().getString() + "' has been blocked by CORS policy: " +
        accessControlErrorDescription;
  } else {
    allowRedirect = true;
  }

  if (!allowRedirect) {
    ThreadableLoaderClient* client = m_client;
    clear();
    client->didFailAccessControlCheck(ResourceError(
        errorDomainBlinkInternal, 0, redirectResponse.url().getString(),
        accessControlErrorDescription));
    return false;
  }

  m_client->didReceiveRedirectTo(request.url());

  // FIXME: consider combining this with CORS redirect handling performed by
  // CrossOriginAccessControl::handleRedirect().
  clearResource();

  // If the original request wasn't same-origin, then if the request URL origin
  // is not same origin with the original URL origin, set the source origin to a
  // globally unique identifier. (If the original request was same-origin, the
  // origin of the new request should be the original URL origin.)
  if (!m_sameOriginRequest) {
    RefPtr<SecurityOrigin> originalOrigin =
        SecurityOrigin::create(redirectResponse.url());
    RefPtr<SecurityOrigin> requestOrigin =
        SecurityOrigin::create(request.url());
    if (!originalOrigin->isSameSchemeHostPort(requestOrigin.get()))
      m_securityOrigin = SecurityOrigin::createUnique();
  }
  // Force any subsequent requests to use these checks.
  m_sameOriginRequest = false;

  // Since the request is no longer same-origin, if the user didn't request
  // credentials in the first place, update our state so we neither request them
  // nor expect they must be allowed.
  if (m_resourceLoaderOptions.credentialsRequested ==
      ClientDidNotRequestCredentials)
    m_forceDoNotAllowStoredCredentials = true;

  // Save the referrer to use when following the redirect.
  m_overrideReferrer = true;
  m_referrerAfterRedirect =
      Referrer(request.httpReferrer(), request.getReferrerPolicy());

  ResourceRequest crossOriginRequest(request);

  // Remove any headers that may have been added by the network layer that cause
  // access control to fail.
  crossOriginRequest.clearHTTPReferrer();
  crossOriginRequest.clearHTTPOrigin();
  crossOriginRequest.clearHTTPUserAgent();
  // Add any request headers which we previously saved from the
  // original request.
  for (const auto& header : m_requestHeaders)
    crossOriginRequest.setHTTPHeaderField(header.key, header.value);
  makeCrossOriginAccessRequest(crossOriginRequest);

  return false;
}
예제 #25
0
void Subprocess::communicate(FdCallback readCallback,
                             FdCallback writeCallback) {
  returnCode_.enforce(ProcessReturnCode::RUNNING);
  setAllNonBlocking();

  std::vector<pollfd> fds;
  fds.reserve(pipes_.size());
  std::vector<int> toClose;
  toClose.reserve(pipes_.size());

  while (!pipes_.empty()) {
    fds.clear();
    toClose.clear();

    for (auto& p : pipes_) {
      pollfd pfd;
      pfd.fd = p.parentFd;
      // Yes, backwards, PIPE_IN / PIPE_OUT are defined from the
      // child's point of view.
      if (!p.enabled) {
        // Still keeping fd in watched set so we get notified of POLLHUP /
        // POLLERR
        pfd.events = 0;
      } else if (p.direction == PIPE_IN) {
        pfd.events = POLLOUT;
      } else {
        pfd.events = POLLIN;
      }
      fds.push_back(pfd);
    }

    int r;
    do {
      r = ::poll(fds.data(), fds.size(), -1);
    } while (r == -1 && errno == EINTR);
    checkUnixError(r, "poll");

    for (int i = 0; i < pipes_.size(); ++i) {
      auto& p = pipes_[i];
      DCHECK_EQ(fds[i].fd, p.parentFd);
      short events = fds[i].revents;

      bool closed = false;
      if (events & POLLOUT) {
        DCHECK(!(events & POLLIN));
        if (writeCallback(p.parentFd, p.childFd)) {
          toClose.push_back(i);
          closed = true;
        }
      }

      if (events & POLLIN) {
        DCHECK(!(events & POLLOUT));
        if (readCallback(p.parentFd, p.childFd)) {
          toClose.push_back(i);
          closed = true;
        }
      }

      if ((events & (POLLHUP | POLLERR)) && !closed) {
        toClose.push_back(i);
        closed = true;
      }
    }

    // Close the fds in reverse order so the indexes hold after erase()
    for (int idx : boost::adaptors::reverse(toClose)) {
      auto pos = pipes_.begin() + idx;
      closeChecked(pos->parentFd);
      pipes_.erase(pos);
    }
  }
}
void ClientPrintHandlerGtk::OnDialogResponse(GtkDialog *dialog,
                                             gint response_id) {
  int num_matched_handlers = g_signal_handlers_disconnect_by_func(
      dialog_, reinterpret_cast<gpointer>(&OnDialogResponseThunk), this);
  DCHECK_EQ(1, num_matched_handlers);

  gtk_widget_hide(dialog_);

  switch (response_id) {
    case GTK_RESPONSE_OK: {
      if (gtk_settings_)
        g_object_unref(gtk_settings_);
      gtk_settings_ = gtk_print_unix_dialog_get_settings(
          GTK_PRINT_UNIX_DIALOG(dialog_));

      if (printer_)
        g_object_unref(printer_);
      printer_ = gtk_print_unix_dialog_get_selected_printer(
          GTK_PRINT_UNIX_DIALOG(dialog_));
      g_object_ref(printer_);

      if (page_setup_)
        g_object_unref(page_setup_);
      page_setup_ = gtk_print_unix_dialog_get_page_setup(
          GTK_PRINT_UNIX_DIALOG(dialog_));
      g_object_ref(page_setup_);

      // Handle page ranges.
      CefPrintSettings::PageRangeList ranges_vector;
      gint num_ranges;
      bool print_selection_only = false;
      switch (gtk_print_settings_get_print_pages(gtk_settings_)) {
        case GTK_PRINT_PAGES_RANGES: {
          GtkPageRange* gtk_range =
              gtk_print_settings_get_page_ranges(gtk_settings_, &num_ranges);
          if (gtk_range) {
            for (int i = 0; i < num_ranges; ++i) {
              ranges_vector.push_back(
                  CefPageRange(gtk_range[i].start, gtk_range[i].end));
            }
            g_free(gtk_range);
          }
          break;
        }
        case GTK_PRINT_PAGES_SELECTION:
          print_selection_only = true;
          break;
        case GTK_PRINT_PAGES_ALL:
          // Leave |ranges_vector| empty to indicate print all pages.
          break;
        case GTK_PRINT_PAGES_CURRENT:
        default:
          NOTREACHED();
          break;
      }

      CefRefPtr<CefPrintSettings> settings = CefPrintSettings::Create();
      settings->SetPageRanges(ranges_vector);
      settings->SetSelectionOnly(print_selection_only);
      InitPrintSettings(gtk_settings_, page_setup_, settings);
      dialog_callback_->Continue(settings);
      dialog_callback_ = NULL;
      return;
    }
    case GTK_RESPONSE_DELETE_EVENT:  // Fall through.
    case GTK_RESPONSE_CANCEL: {
      dialog_callback_->Cancel();
      dialog_callback_ = NULL;
      return;
    }
    case GTK_RESPONSE_APPLY:
    default: {
      NOTREACHED();
    }
  }
}
std::string BootEventRecordStore::GetBootEventPath(
    const std::string& event) const {
  DCHECK_EQ('/', store_path_.back());
  return store_path_ + event;
}
void BootEventRecordStore::SetStorePath(const std::string& path) {
  DCHECK_EQ('/', path.back());
  store_path_ = path;
}
int main(int argc, char **argv) {
  android::base::InitLogging(argv);

  const std::string cmd_line = GetCommandLine(argc, argv);
  LOG(INFO) << "Service started: " << cmd_line;

  int option_index = 0;
  static const char boot_complete_str[] = "record_boot_complete";
  static const char boot_reason_str[] = "record_boot_reason";
  static const char factory_reset_str[] = "record_time_since_factory_reset";
  static const struct option long_options[] = {
    { "help",            no_argument,       NULL,   'h' },
    { "log",             no_argument,       NULL,   'l' },
    { "print",           no_argument,       NULL,   'p' },
    { "record",          required_argument, NULL,   'r' },
    { boot_complete_str, no_argument,       NULL,   0 },
    { boot_reason_str,   no_argument,       NULL,   0 },
    { factory_reset_str, no_argument,       NULL,   0 },
    { NULL,              0,                 NULL,   0 }
  };

  int opt = 0;
  while ((opt = getopt_long(argc, argv, "hlpr:", long_options, &option_index)) != -1) {
    switch (opt) {
      // This case handles long options which have no single-character mapping.
      case 0: {
        const std::string option_name = long_options[option_index].name;
        if (option_name == boot_complete_str) {
          RecordBootComplete();
        } else if (option_name == boot_reason_str) {
          RecordBootReason();
        } else if (option_name == factory_reset_str) {
          RecordFactoryReset();
        } else {
          LOG(ERROR) << "Invalid option: " << option_name;
        }
        break;
      }

      case 'h': {
        ShowHelp(argv[0]);
        break;
      }

      case 'l': {
        LogBootEvents();
        break;
      }

      case 'p': {
        PrintBootEvents();
        break;
      }

      case 'r': {
        // |optarg| is an external variable set by getopt representing
        // the option argument.
        const char* event = optarg;

        BootEventRecordStore boot_event_store;
        boot_event_store.AddBootEvent(event);
        break;
      }

      default: {
        DCHECK_EQ(opt, '?');

        // |optopt| is an external variable set by getopt representing
        // the value of the invalid option.
        LOG(ERROR) << "Invalid option: " << optopt;
        ShowHelp(argv[0]);
        return EXIT_FAILURE;
      }
    }
  }

  return 0;
}
예제 #30
0
size_t WebSurroundingText::hitOffsetInTextContent() const {
  DCHECK_EQ(m_private->startOffsetInContent(), m_private->endOffsetInContent());
  return m_private->startOffsetInContent();
}