Exemple #1
0
already_AddRefed<Promise>
Cache::AddAll(JSContext* aContext,
              const Sequence<OwningRequestOrUSVString>& aRequestList,
              CallerType aCallerType,
              ErrorResult& aRv)
{
  if (NS_WARN_IF(!mActor)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return nullptr;
  }

  CacheChild::AutoLock actorLock(mActor);

  GlobalObject global(aContext, mGlobal->GetGlobalJSObject());
  MOZ_DIAGNOSTIC_ASSERT(!global.Failed());

  nsTArray<RefPtr<Request>> requestList(aRequestList.Length());
  for (uint32_t i = 0; i < aRequestList.Length(); ++i) {
    RequestOrUSVString requestOrString;

    if (aRequestList[i].IsRequest()) {
      requestOrString.SetAsRequest() = aRequestList[i].GetAsRequest();
      if (NS_WARN_IF(!IsValidPutRequestMethod(requestOrString.GetAsRequest(),
                     aRv))) {
        return nullptr;
      }
    } else {
      requestOrString.SetAsUSVString().Rebind(
        aRequestList[i].GetAsUSVString().Data(),
        aRequestList[i].GetAsUSVString().Length());
    }

    RefPtr<Request> request = Request::Constructor(global, requestOrString,
                                                   RequestInit(), aRv);
    if (NS_WARN_IF(aRv.Failed())) {
      return nullptr;
    }

    nsAutoString url;
    request->GetUrl(url);
    if (NS_WARN_IF(!IsValidPutRequestURL(url, aRv))) {
      return nullptr;
    }

    requestList.AppendElement(std::move(request));
  }

  return AddAll(global, std::move(requestList), aCallerType, aRv);
}
void
MobileMessageManager::Send(const Sequence<nsString>& aNumbers,
                           const nsAString& aText,
                           const SmsSendParameters& aSendParams,
                           nsTArray<RefPtr<DOMRequest>>& aReturn,
                           ErrorResult& aRv)
{
  nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
  if (!smsService) {
    aRv.Throw(NS_ERROR_FAILURE);
    return;
  }

  // Use the default one unless |aSendParams.serviceId| is available.
  uint32_t serviceId;
  if (aSendParams.mServiceId.WasPassed()) {
    serviceId = aSendParams.mServiceId.Value();
  } else {
    nsresult rv = smsService->GetSmsDefaultServiceId(&serviceId);
    if (NS_FAILED(rv)) {
      aRv.Throw(rv);
      return;
    }
  }

  const uint32_t size = aNumbers.Length();
  for (uint32_t i = 0; i < size; ++i) {
    RefPtr<DOMRequest> request = Send(smsService, serviceId, aNumbers[i], aText, aRv);
    if (aRv.Failed()) {
      return;
    }
    aReturn.AppendElement(request);
  }
}
already_AddRefed<DOMRequest>
MobileMessageManager::Delete(const Sequence<OwningLongOrSmsMessageOrMmsMessage>& aParams,
                             ErrorResult& aRv)
{
  const uint32_t size = aParams.Length();
  FallibleTArray<int32_t> idArray;
  if (!idArray.SetLength(size, fallible)) {
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    return nullptr;
  }

  DebugOnly<nsresult> rv;
  for (uint32_t i = 0; i < size; i++) {
    const OwningLongOrSmsMessageOrMmsMessage& element = aParams[i];
    int32_t &id = idArray[i];

    if (element.IsLong()) {
      id = element.GetAsLong();
    } else if (element.IsMmsMessage()) {
      id = element.GetAsMmsMessage()->Id();
    } else /*if (element.IsSmsMessage())*/ {
      id = element.GetAsSmsMessage()->Id();
    }
  }

  return Delete(idArray.Elements(), size, aRv);
}
Exemple #4
0
already_AddRefed<DOMMatrix>
DOMMatrix::Constructor(const GlobalObject& aGlobal, const Sequence<double>& aNumberSequence, ErrorResult& aRv)
{
  RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports());
  SetDataInMatrix(obj, aNumberSequence.Elements(), aNumberSequence.Length(), aRv);

  return obj.forget();
}
Exemple #5
0
already_AddRefed<TouchList> TouchEvent::CopyTouches(
    const Sequence<OwningNonNull<Touch>>& aTouches) {
  RefPtr<TouchList> list = new TouchList(GetParentObject());
  size_t len = aTouches.Length();
  for (size_t i = 0; i < len; ++i) {
    list->Append(aTouches[i]);
  }
  return list.forget();
}
Exemple #6
0
already_AddRefed<Promise>
Cache::AddAll(const Sequence<OwningRequestOrUSVString>& aRequests,
              ErrorResult& aRv)
{
  MOZ_ASSERT(mActor);

  nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
  if (!promise) {
    return nullptr;
  }

  // If there is no work to do, then resolve immediately
  if (aRequests.IsEmpty()) {
    promise->MaybeResolve(JS::UndefinedHandleValue);
    return promise.forget();
  }

  AutoChildRequestList requests(this, aRequests.Length());

  for (uint32_t i = 0; i < aRequests.Length(); ++i) {
    if (!IsValidPutRequestMethod(aRequests[i], aRv)) {
      return nullptr;
    }

    nsRefPtr<InternalRequest> ir = ToInternalRequest(aRequests[i], ReadBody,
                                                     aRv);
    if (aRv.Failed()) {
      return nullptr;
    }

    requests.Add(ir, ReadBody, ExpandReferrer, NetworkErrorOnInvalidScheme,
                 aRv);
    if (aRv.Failed()) {
      return nullptr;
    }
  }

  RequestId requestId = AddRequestPromise(promise, aRv);

  unused << mActor->SendAddAll(requestId, requests.SendAsRequestList());

  return promise.forget();
}
Exemple #7
0
bool
CryptoKey::AllUsagesRecognized(const Sequence<nsString>& aUsages)
{
  for (uint32_t i = 0; i < aUsages.Length(); ++i) {
    if (!IsRecognizedUsage(aUsages[i])) {
      return false;
    }
  }
  return true;
}
void
MultipartBlobImpl::InitializeBlob(
       JSContext* aCx,
       const Sequence<OwningArrayBufferOrArrayBufferViewOrBlobOrString>& aData,
       const nsAString& aContentType,
       bool aNativeEOL,
       ErrorResult& aRv)
{
  mContentType = aContentType;
  BlobSet blobSet;

  for (uint32_t i = 0, len = aData.Length(); i < len; ++i) {
    const OwningArrayBufferOrArrayBufferViewOrBlobOrString& data = aData[i];

    if (data.IsBlob()) {
      nsRefPtr<Blob> blob = data.GetAsBlob().get();
      blobSet.AppendBlobImpl(blob->Impl());
    }

    else if (data.IsString()) {
      aRv = blobSet.AppendString(data.GetAsString(), aNativeEOL, aCx);
      if (aRv.Failed()) {
        return;
      }
    }

    else if (data.IsArrayBuffer()) {
      const ArrayBuffer& buffer = data.GetAsArrayBuffer();
      buffer.ComputeLengthAndData();
      aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length());
      if (aRv.Failed()) {
        return;
      }
    }

    else if (data.IsArrayBufferView()) {
      const ArrayBufferView& buffer = data.GetAsArrayBufferView();
      buffer.ComputeLengthAndData();
      aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length());
      if (aRv.Failed()) {
        return;
      }
    }

    else {
      MOZ_CRASH("Impossible blob data type.");
    }
  }


  mBlobImpls = blobSet.GetBlobImpls();
  SetLengthAndModifiedDate();
}
Exemple #9
0
  void
  Initialize(JSContext* aCx, Console::MethodName aName,
             const nsAString& aString, const Sequence<JS::Value>& aArguments)
  {
    mGlobal = JS::CurrentGlobalOrNull(aCx);
    mMethodName = aName;
    mMethodString = aString;

    for (uint32_t i = 0; i < aArguments.Length(); ++i) {
      mArguments.AppendElement(aArguments[i]);
    }
  }
void
InternalHeaders::Fill(const Sequence<Sequence<nsCString>>& aInit, ErrorResult& aRv)
{
  for (uint32_t i = 0; i < aInit.Length() && !aRv.Failed(); ++i) {
    const Sequence<nsCString>& tuple = aInit[i];
    if (tuple.Length() != 2) {
      aRv.ThrowTypeError<MSG_INVALID_HEADER_SEQUENCE>();
      return;
    }
    Append(tuple[0], tuple[1], aRv);
  }
}
static nsCString ToCString(const Sequence<Type>& aSequence) {
  nsCString str;
  str.AppendLiteral("[");
  for (size_t i = 0; i < aSequence.Length(); i++) {
    if (i != 0) {
      str.AppendLiteral(",");
    }
    str.Append(ToCString(aSequence[i]));
  }
  str.AppendLiteral("]");
  return str;
}
void
MultipartBlobImpl::InitializeBlob(const Sequence<Blob::BlobPart>& aData,
                                  const nsAString& aContentType,
                                  bool aNativeEOL,
                                  ErrorResult& aRv)
{
  mContentType = aContentType;
  BlobSet blobSet;

  for (uint32_t i = 0, len = aData.Length(); i < len; ++i) {
    const Blob::BlobPart& data = aData[i];

    if (data.IsBlob()) {
      RefPtr<Blob> blob = data.GetAsBlob().get();
      blobSet.AppendBlobImpl(blob->Impl());
    }

    else if (data.IsUSVString()) {
      aRv = blobSet.AppendString(data.GetAsUSVString(), aNativeEOL);
      if (aRv.Failed()) {
        return;
      }
    }

    else if (data.IsArrayBuffer()) {
      const ArrayBuffer& buffer = data.GetAsArrayBuffer();
      buffer.ComputeLengthAndData();
      aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length());
      if (aRv.Failed()) {
        return;
      }
    }

    else if (data.IsArrayBufferView()) {
      const ArrayBufferView& buffer = data.GetAsArrayBufferView();
      buffer.ComputeLengthAndData();
      aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length());
      if (aRv.Failed()) {
        return;
      }
    }

    else {
      MOZ_CRASH("Impossible blob data type.");
    }
  }


  mBlobImpls = blobSet.GetBlobImpls();
  SetLengthAndModifiedDate(aRv);
  NS_WARNING_ASSERTION(!aRv.Failed(), "SetLengthAndModifiedDate failed");
}
Exemple #13
0
// static
nsresult KeyPath::Parse(const Sequence<nsString>& aStrings, KeyPath* aKeyPath) {
  KeyPath keyPath(0);
  keyPath.SetType(ARRAY);

  for (uint32_t i = 0; i < aStrings.Length(); ++i) {
    if (!keyPath.AppendStringWithValidation(aStrings[i])) {
      return NS_ERROR_FAILURE;
    }
  }

  *aKeyPath = keyPath;
  return NS_OK;
}
Exemple #14
0
void
BluetoothAdapter::DispatchAttributeEvent(const Sequence<nsString>& aTypes)
{
  NS_ENSURE_TRUE_VOID(aTypes.Length());

  BluetoothAttributeEventInit init;
  init.mAttrs = aTypes;

  nsRefPtr<BluetoothAttributeEvent> event =
    BluetoothAttributeEvent::Constructor(
      this, NS_LITERAL_STRING(ATTRIBUTE_CHANGED_ID), init);

  DispatchTrustedEvent(event);
}
Exemple #15
0
bool
nsScreen::MozLockOrientation(const Sequence<nsString>& aOrientations,
                             ErrorResult& aRv)
{
  if (ShouldResistFingerprinting()) {
    return false;
  }
  hal::ScreenOrientation orientation = hal::eScreenOrientation_None;

  for (uint32_t i = 0; i < aOrientations.Length(); ++i) {
    const nsString& item = aOrientations[i];

    if (item.EqualsLiteral("portrait")) {
      orientation |= hal::eScreenOrientation_PortraitPrimary |
                     hal::eScreenOrientation_PortraitSecondary;
    } else if (item.EqualsLiteral("portrait-primary")) {
      orientation |= hal::eScreenOrientation_PortraitPrimary;
    } else if (item.EqualsLiteral("portrait-secondary")) {
      orientation |= hal::eScreenOrientation_PortraitSecondary;
    } else if (item.EqualsLiteral("landscape")) {
      orientation |= hal::eScreenOrientation_LandscapePrimary |
                     hal::eScreenOrientation_LandscapeSecondary;
    } else if (item.EqualsLiteral("landscape-primary")) {
      orientation |= hal::eScreenOrientation_LandscapePrimary;
    } else if (item.EqualsLiteral("landscape-secondary")) {
      orientation |= hal::eScreenOrientation_LandscapeSecondary;
    } else if (item.EqualsLiteral("default")) {
      orientation |= hal::eScreenOrientation_Default;
    } else {
      // If we don't recognize the token, we should just return 'false'
      // without throwing.
      return false;
    }
  }

  switch (mScreenOrientation->GetLockOrientationPermission(false)) {
    case ScreenOrientation::LOCK_DENIED:
      return false;
    case ScreenOrientation::LOCK_ALLOWED:
      UpdateDocShellOrientationLock(GetOwner(), orientation);
      return mScreenOrientation->LockDeviceOrientation(orientation, false, aRv);
    case ScreenOrientation::FULLSCREEN_LOCK_ALLOWED:
      UpdateDocShellOrientationLock(GetOwner(), orientation);
      return mScreenOrientation->LockDeviceOrientation(orientation, true, aRv);
  }

  // This is only for compilers that don't understand that the previous switch
  // will always return.
  MOZ_CRASH("unexpected lock orientation permission value");
}
Exemple #16
0
already_AddRefed<nsIDocument>
nsDOMParser::ParseFromBuffer(const Sequence<uint8_t>& aBuf, uint32_t aBufLen,
                             SupportedType aType, ErrorResult& rv)
{
  if (aBufLen > aBuf.Length()) {
    rv.Throw(NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY);
    return nullptr;
  }
  nsCOMPtr<nsIDOMDocument> domDocument;
  rv = nsDOMParser::ParseFromBuffer(aBuf.Elements(), aBufLen,
                                    SupportedTypeValues::strings[aType].value,
                                    getter_AddRefs(domDocument));
  nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
  return document.forget();
}
Exemple #17
0
void
nsBrowserElement::SendTouchEvent(const nsAString& aType,
                                 const Sequence<uint32_t>& aIdentifiers,
                                 const Sequence<int32_t>& aXs,
                                 const Sequence<int32_t>& aYs,
                                 const Sequence<uint32_t>& aRxs,
                                 const Sequence<uint32_t>& aRys,
                                 const Sequence<float>& aRotationAngles,
                                 const Sequence<float>& aForces,
                                 uint32_t aCount,
                                 uint32_t aModifiers,
                                 ErrorResult& aRv)
{
  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
  NS_ENSURE_TRUE_VOID(IsNotWidgetOrThrow(aRv));

  if (aIdentifiers.Length() != aCount ||
      aXs.Length() != aCount ||
      aYs.Length() != aCount ||
      aRxs.Length() != aCount ||
      aRys.Length() != aCount ||
      aRotationAngles.Length() != aCount ||
      aForces.Length() != aCount) {
    aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
    return;
  }

  nsresult rv = mBrowserElementAPI->SendTouchEvent(aType,
                                                   aIdentifiers.Elements(),
                                                   aXs.Elements(),
                                                   aYs.Elements(),
                                                   aRxs.Elements(),
                                                   aRys.Elements(),
                                                   aRotationAngles.Elements(),
                                                   aForces.Elements(),
                                                   aCount,
                                                   aModifiers);

  if (NS_WARN_IF(NS_FAILED(rv))) {
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
  }
}
/* static */
bool
MediaKeySystemAccess::IsSupported(const nsAString& aKeySystem,
                                  const Sequence<MediaKeySystemOptions>& aOptions)
{
  nsCOMPtr<mozIGeckoMediaPluginService> mps =
    do_GetService("@mozilla.org/gecko-media-plugin-service;1");
  if (NS_WARN_IF(!mps)) {
    return false;
  }

  for (size_t i = 0; i < aOptions.Length(); i++) {
    const MediaKeySystemOptions& options = aOptions[i];
    if (!options.mInitDataType.EqualsLiteral("cenc")) {
      continue;
    }
    if (!options.mAudioCapability.IsEmpty() ||
        !options.mVideoCapability.IsEmpty()) {
      // Don't support any capabilites until we know we have a CDM with
      // capabilities...
      continue;
    }
    if (!options.mAudioType.IsEmpty() &&
        !IsPlayableWithGMP(mps, aKeySystem, options.mAudioType)) {
      continue;
    }
    if (!options.mVideoType.IsEmpty() &&
        !IsPlayableWithGMP(mps, aKeySystem, options.mVideoType)) {
      continue;
    }

    // Our sandbox provides an origin specific unique identifier, and the
    // ability to persist data. We don't yet have a way to turn those off
    // and on for specific GMPs/CDMs, so we don't check the uniqueidentifier
    // and stateful attributes here.

    return true;
  }
  return false;
}
Exemple #19
0
bool
nsScreen::MozLockOrientation(const Sequence<nsString>& aOrientations,
                             ErrorResult& aRv)
{
  ScreenOrientation orientation = eScreenOrientation_None;

  for (uint32_t i = 0; i < aOrientations.Length(); ++i) {
    const nsString& item = aOrientations[i];

    if (item.EqualsLiteral("portrait")) {
      orientation |= eScreenOrientation_PortraitPrimary |
                     eScreenOrientation_PortraitSecondary;
    } else if (item.EqualsLiteral("portrait-primary")) {
      orientation |= eScreenOrientation_PortraitPrimary;
    } else if (item.EqualsLiteral("portrait-secondary")) {
      orientation |= eScreenOrientation_PortraitSecondary;
    } else if (item.EqualsLiteral("landscape")) {
      orientation |= eScreenOrientation_LandscapePrimary |
                     eScreenOrientation_LandscapeSecondary;
    } else if (item.EqualsLiteral("landscape-primary")) {
      orientation |= eScreenOrientation_LandscapePrimary;
    } else if (item.EqualsLiteral("landscape-secondary")) {
      orientation |= eScreenOrientation_LandscapeSecondary;
    } else {
      // If we don't recognize the token, we should just return 'false'
      // without throwing.
      return false;
    }
  }

  switch (GetLockOrientationPermission()) {
    case LOCK_DENIED:
      return false;
    case LOCK_ALLOWED:
      return hal::LockScreenOrientation(orientation);
    case FULLSCREEN_LOCK_ALLOWED: {
      // We need to register a listener so we learn when we leave full-screen
      // and when we will have to unlock the screen.
      // This needs to be done before LockScreenOrientation call to make sure
      // the locking can be unlocked.
      nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
      if (!target) {
        return false;
      }

      if (!hal::LockScreenOrientation(orientation)) {
        return false;
      }

      // We are fullscreen and lock has been accepted.
      if (!mEventListener) {
        mEventListener = new FullScreenEventListener();
      }

      aRv = target->AddSystemEventListener(NS_LITERAL_STRING("mozfullscreenchange"),
                                           mEventListener, /* useCapture = */ true);
      return true;
    }
  }

  // This is only for compilers that don't understand that the previous switch
  // will always return.
  MOZ_NOT_REACHED();
  return false;
}
Exemple #20
0
already_AddRefed<WebSocket>
WebSocket::Constructor(JSContext* aCx,
                       nsISupports* aGlobal,
                       const nsAString& aUrl,
                       const Sequence<nsString>& aProtocols,
                       ErrorResult& aRv)
{
  if (!PrefEnabled()) {
    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
    return nullptr;
  }

  nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal = do_QueryInterface(aGlobal);
  if (!scriptPrincipal) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  nsCOMPtr<nsIPrincipal> principal = scriptPrincipal->GetPrincipal();
  if (!principal) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aGlobal);
  if (!sgo) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  nsCOMPtr<nsPIDOMWindow> ownerWindow = do_QueryInterface(aGlobal);
  if (!ownerWindow) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  nsTArray<nsString> protocolArray;

  for (uint32_t index = 0, len = aProtocols.Length(); index < len; ++index) {

    const nsString& protocolElement = aProtocols[index];

    if (protocolElement.IsEmpty()) {
      aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
      return nullptr;
    }
    if (protocolArray.Contains(protocolElement)) {
      aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
      return nullptr;
    }
    if (protocolElement.FindChar(',') != -1)  /* interferes w/list */ {
      aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
      return nullptr;
    }

    protocolArray.AppendElement(protocolElement);
  }

  nsRefPtr<WebSocket> webSocket = new WebSocket();
  nsresult rv = webSocket->Init(aCx, principal, ownerWindow, aUrl, protocolArray);
  if (NS_FAILED(rv)) {
    aRv.Throw(rv);
    return nullptr;
  }

  return webSocket.forget();
}
Exemple #21
0
void
MessagePort::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
                         const Sequence<JSObject*>& aTransferable,
                         ErrorResult& aRv)
{
  // We *must* clone the data here, or the JS::Value could be modified
  // by script

  // Here we want to check if the transerable object list contains
  // this port.
  for (uint32_t i = 0; i < aTransferable.Length(); ++i) {
    JS::Rooted<JSObject*> object(aCx, aTransferable[i]);
    if (!object) {
      continue;
    }

    MessagePort* port = nullptr;
    nsresult rv = UNWRAP_OBJECT(MessagePort, &object, port);
    if (NS_SUCCEEDED(rv) && port == this) {
      aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
      return;
    }
  }

  JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());

  aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(aCx, aTransferable,
                                                          &transferable);
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  RefPtr<SharedMessagePortMessage> data = new SharedMessagePortMessage();

  UniquePtr<AbstractTimelineMarker> start;
  UniquePtr<AbstractTimelineMarker> end;
  RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
  bool isTimelineRecording = timelines && !timelines->IsEmpty();

  if (isTimelineRecording) {
    start = MakeUnique<MessagePortTimelineMarker>(
      ProfileTimelineMessagePortOperationType::SerializeData,
      MarkerTracingType::START);
  }

  data->Write(aCx, aMessage, transferable, aRv);

  if (isTimelineRecording) {
    end = MakeUnique<MessagePortTimelineMarker>(
      ProfileTimelineMessagePortOperationType::SerializeData,
      MarkerTracingType::END);
    timelines->AddMarkerForAllObservedDocShells(start);
    timelines->AddMarkerForAllObservedDocShells(end);
  }

  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  // This message has to be ignored.
  if (mState > eStateEntangled) {
    return;
  }

  // If we are unshipped we are connected to the other port on the same thread.
  if (mState == eStateUnshippedEntangled) {
    MOZ_ASSERT(mUnshippedEntangledPort);
    mUnshippedEntangledPort->mMessages.AppendElement(data);
    mUnshippedEntangledPort->Dispatch();
    return;
  }

  // Not entangled yet, but already closed/disentangled.
  if (mState == eStateEntanglingForDisentangle ||
      mState == eStateEntanglingForClose) {
    return;
  }

  RemoveDocFromBFCache();

  // Not entangled yet.
  if (mState == eStateEntangling) {
    mMessagesForTheOtherPort.AppendElement(data);
    return;
  }

  MOZ_ASSERT(mActor);
  MOZ_ASSERT(mMessagesForTheOtherPort.IsEmpty());

  AutoTArray<RefPtr<SharedMessagePortMessage>, 1> array;
  array.AppendElement(data);

  AutoTArray<ClonedMessageData, 1> messages;
  // note: `messages` will borrow the underlying buffer, but this is okay
  // because reverse destruction order means `messages` will be destroyed prior
  // to `array`/`data`.
  SharedMessagePortMessage::FromSharedToMessagesChild(mActor, array, messages);
  mActor->SendPostMessages(messages);
}
Exemple #22
0
already_AddRefed<Promise>
WebAuthentication::MakeCredential(JSContext* aCx, const Account& aAccount,
                  const Sequence<ScopedCredentialParameters>& aCryptoParameters,
                  const ArrayBufferViewOrArrayBuffer& aChallenge,
                  const ScopedCredentialOptions& aOptions)
{
  MOZ_ASSERT(mParent);
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
  if (!global) {
    return nullptr;
  }

  ErrorResult rv;
  RefPtr<Promise> promise = Promise::Create(global, rv);

  nsresult initRv = InitLazily();
  if (NS_FAILED(initRv)) {
    promise->MaybeReject(initRv);
    return promise.forget();
  }

  // 4.1.1.1 If timeoutSeconds was specified, check if its value lies within a
  // reasonable range as defined by the platform and if not, correct it to the
  // closest value lying within that range.

  double adjustedTimeout = 30.0;
  if (aOptions.mTimeoutSeconds.WasPassed()) {
    adjustedTimeout = aOptions.mTimeoutSeconds.Value();
    adjustedTimeout = std::max(15.0, adjustedTimeout);
    adjustedTimeout = std::min(120.0, adjustedTimeout);
  }

  // 4.1.1.2 Let promise be a new Promise. Return promise and start a timer for
  // adjustedTimeout seconds.

  RefPtr<CredentialRequest> requestMonitor = new CredentialRequest();
  requestMonitor->SetDeadline(TimeDuration::FromSeconds(adjustedTimeout));

  if (mOrigin.EqualsLiteral("null")) {
    // 4.1.1.3 If callerOrigin is an opaque origin, reject promise with a
    // DOMException whose name is "NotAllowedError", and terminate this
    // algorithm
    MOZ_LOG(gWebauthLog, LogLevel::Debug, ("Rejecting due to opaque origin"));
    promise->MaybeReject(NS_ERROR_DOM_NOT_ALLOWED_ERR);
    return promise.forget();
  }

  nsCString rpId;
  if (!aOptions.mRpId.WasPassed()) {
    // 4.1.1.3.a If rpId is not specified, then set rpId to callerOrigin, and
    // rpIdHash to the SHA-256 hash of rpId.
    rpId.Assign(NS_ConvertUTF16toUTF8(mOrigin));
  } else {
    // 4.1.1.3.b If rpId is specified, then invoke the procedure used for
    // relaxing the same-origin restriction by setting the document.domain
    // attribute, using rpId as the given value but without changing the current
    // document’s domain. If no errors are thrown, set rpId to the value of host
    // as computed by this procedure, and rpIdHash to the SHA-256 hash of rpId.
    // Otherwise, reject promise with a DOMException whose name is
    // "SecurityError", and terminate this algorithm.

    if (NS_FAILED(RelaxSameOrigin(aOptions.mRpId.Value(), rpId))) {
      promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
      return promise.forget();
    }
  }

  CryptoBuffer rpIdHash;
  if (!rpIdHash.SetLength(SHA256_LENGTH, fallible)) {
    promise->MaybeReject(NS_ERROR_OUT_OF_MEMORY);
    return promise.forget();
  }

  nsresult srv;
  nsCOMPtr<nsICryptoHash> hashService =
    do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &srv);
  if (NS_WARN_IF(NS_FAILED(srv))) {
    promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
    return promise.forget();
  }

  srv = HashCString(hashService, rpId, rpIdHash);
  if (NS_WARN_IF(NS_FAILED(srv))) {
    promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
    return promise.forget();
  }

  // 4.1.1.4 Process each element of cryptoParameters using the following steps,
  // to produce a new sequence normalizedParameters.
  nsTArray<ScopedCredentialParameters> normalizedParams;
  for (size_t a = 0; a < aCryptoParameters.Length(); ++a) {
    // 4.1.1.4.a Let current be the currently selected element of
    // cryptoParameters.

    // 4.1.1.4.b If current.type does not contain a ScopedCredentialType
    // supported by this implementation, then stop processing current and move
    // on to the next element in cryptoParameters.
    if (aCryptoParameters[a].mType != ScopedCredentialType::ScopedCred) {
      continue;
    }

    // 4.1.1.4.c Let normalizedAlgorithm be the result of normalizing an
    // algorithm using the procedure defined in [WebCryptoAPI], with alg set to
    // current.algorithm and op set to 'generateKey'. If an error occurs during
    // this procedure, then stop processing current and move on to the next
    // element in cryptoParameters.

    nsString algName;
    if (NS_FAILED(GetAlgorithmName(aCx, aCryptoParameters[a].mAlgorithm,
                                   algName))) {
      continue;
    }

    // 4.1.1.4.d Add a new object of type ScopedCredentialParameters to
    // normalizedParameters, with type set to current.type and algorithm set to
    // normalizedAlgorithm.
    ScopedCredentialParameters normalizedObj;
    normalizedObj.mType = aCryptoParameters[a].mType;
    normalizedObj.mAlgorithm.SetAsString().Assign(algName);

    if (!normalizedParams.AppendElement(normalizedObj, mozilla::fallible)){
      promise->MaybeReject(NS_ERROR_OUT_OF_MEMORY);
      return promise.forget();
    }
  }

  // 4.1.1.5 If normalizedAlgorithm is empty and cryptoParameters was not empty,
  // cancel the timer started in step 2, reject promise with a DOMException
  // whose name is "NotSupportedError", and terminate this algorithm.
  if (normalizedParams.IsEmpty() && !aCryptoParameters.IsEmpty()) {
    promise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
    return promise.forget();
  }

  // 4.1.1.6 If excludeList is undefined, set it to the empty list.

  // 4.1.1.7 If extensions was specified, process any extensions supported by
  // this client platform, to produce the extension data that needs to be sent
  // to the authenticator. If an error is encountered while processing an
  // extension, skip that extension and do not produce any extension data for
  // it. Call the result of this processing clientExtensions.

  // Currently no extensions are supported

  // 4.1.1.8 Use attestationChallenge, callerOrigin and rpId, along with the
  // token binding key associated with callerOrigin (if any), to create a
  // ClientData structure representing this request. Choose a hash algorithm for
  // hashAlg and compute the clientDataJSON and clientDataHash.

  CryptoBuffer challenge;
  if (!challenge.Assign(aChallenge)) {
    promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
    return promise.forget();
  }

  nsAutoCString clientDataJSON;
  srv = AssembleClientData(mOrigin, challenge, clientDataJSON);
  if (NS_WARN_IF(NS_FAILED(srv))) {
    promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
    return promise.forget();
  }

  CryptoBuffer clientDataHash;
  if (!clientDataHash.SetLength(SHA256_LENGTH, fallible)) {
    promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
    return promise.forget();
  }

  srv = HashCString(hashService, clientDataJSON, clientDataHash);
  if (NS_WARN_IF(NS_FAILED(srv))) {
    promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
    return promise.forget();
  }

  // 4.1.1.9 Initialize issuedRequests to an empty list.
  RefPtr<CredentialPromise> monitorPromise = requestMonitor->Ensure();

  // 4.1.1.10 For each authenticator currently available on this platform:
  // asynchronously invoke the authenticatorMakeCredential operation on that
  // authenticator with rpIdHash, clientDataHash, accountInformation,
  // normalizedParameters, excludeList and clientExtensions as parameters. Add a
  // corresponding entry to issuedRequests.
  for (Authenticator u2ftoken : mAuthenticators) {
    // 4.1.1.10.a For each credential C in excludeList that has a non-empty
    // transports list, optionally use only the specified transports to test for
    // the existence of C.
    U2FAuthMakeCredential(requestMonitor, u2ftoken, rpIdHash, clientDataJSON,
                          clientDataHash, aAccount, normalizedParams,
                          aOptions.mExcludeList, aOptions.mExtensions);
  }

  requestMonitor->CompleteTask();

  monitorPromise->Then(AbstractThread::MainThread(), __func__,
    [promise] (CredentialPtr aInfo) {
      promise->MaybeResolve(aInfo);
    },
    [promise] (nsresult aErrorCode) {
      promise->MaybeReject(aErrorCode);
  });

  return promise.forget();
}
Exemple #23
0
#include <catch.hpp>

#include <nsearch/Sequence.h>
#include <nsearch/Alphabet/DNA.h>

TEST_CASE( "Sequence" ) { Sequence< DNA > seq( "Id", "ACCT", "JJ::" );

  REQUIRE( seq.Length() == 4 );
  REQUIRE( seq.identifier == "Id" );
  REQUIRE( seq.sequence == "ACCT" );
  REQUIRE( seq.quality == "JJ::" );

  SECTION( "subsequence" ) {
    Sequence< DNA > sub = seq.Subsequence( 2, 2 );
    REQUIRE( sub.sequence == "CT" );
    REQUIRE( sub.quality == "::" );

    REQUIRE( seq.Subsequence( 2 ).sequence == "CT" );
    REQUIRE( seq.Subsequence( 4 ).sequence == "" );

    Sequence< DNA > sub3 = Sequence< DNA >( "ATTG" ).Subsequence( 10, 10 );
    REQUIRE( sub3.sequence == "" );
  }

  SECTION( "operator +" ) {
    Sequence< DNA > m = seq + Sequence< DNA >( "Id2", "GCTT", "BBAJ" );

    REQUIRE( m.identifier == "Id" );
    REQUIRE( m.sequence == "ACCTGCTT" );
    REQUIRE( m.quality == "JJ::BBAJ" );
  }