void
ThebesLayerD3D9::DrawRegion(nsIntRegion &aRegion, SurfaceMode aMode,
                            const nsTArray<ReadbackProcessor::Update>& aReadbackUpdates)
{
  HRESULT hr;
  nsIntRect visibleRect = mVisibleRegion.GetBounds();

  nsRefPtr<gfxASurface> destinationSurface;
  nsIntRect bounds = aRegion.GetBounds();
  nsRefPtr<IDirect3DTexture9> tmpTexture;
  OpaqueRenderer opaqueRenderer(aRegion);
  OpaqueRenderer opaqueRendererOnWhite(aRegion);

  switch (aMode)
  {
    case SurfaceMode::SURFACE_OPAQUE:
      destinationSurface = opaqueRenderer.Begin(this);
      break;

    case SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA: {
      hr = device()->CreateTexture(bounds.width, bounds.height, 1,
                                   0, D3DFMT_A8R8G8B8,
                                   D3DPOOL_SYSTEMMEM, getter_AddRefs(tmpTexture), nullptr);

      if (FAILED(hr)) {
        ReportFailure(NS_LITERAL_CSTRING("Failed to create temporary texture in system memory."), hr);
        return;
      }

      // XXX - We may consider retaining a SYSTEMMEM texture texture the size
      // of our DEFAULT texture and then use UpdateTexture and add dirty rects
      // to update in a single call.
      nsRefPtr<gfxWindowsSurface> dest = new gfxWindowsSurface(
          gfxIntSize(bounds.width, bounds.height), gfxImageFormat::ARGB32);
      // If the contents of this layer don't require component alpha in the
      // end of rendering, it's safe to enable Cleartype since all the Cleartype
      // glyphs must be over (or under) opaque pixels.
      dest->SetSubpixelAntialiasingEnabled(!(mContentFlags & CONTENT_COMPONENT_ALPHA));
      destinationSurface = dest.forget();
      break;
    }

    case SurfaceMode::SURFACE_COMPONENT_ALPHA: {
      nsRefPtr<gfxWindowsSurface> onBlack = opaqueRenderer.Begin(this);
      nsRefPtr<gfxWindowsSurface> onWhite = opaqueRendererOnWhite.Begin(this);
      if (onBlack && onWhite) {
        FillSurface(onBlack, aRegion, bounds.TopLeft(), gfxRGBA(0.0, 0.0, 0.0, 1.0));
        FillSurface(onWhite, aRegion, bounds.TopLeft(), gfxRGBA(1.0, 1.0, 1.0, 1.0));
        gfxASurface* surfaces[2] = { onBlack.get(), onWhite.get() };
        destinationSurface = new gfxTeeSurface(surfaces, ArrayLength(surfaces));
        // Using this surface as a source will likely go horribly wrong, since
        // only the onBlack surface will really be used, so alpha information will
        // be incorrect.
        destinationSurface->SetAllowUseAsSource(false);
      }
      break;
    }
  }

  if (!destinationSurface)
    return;

  nsRefPtr<gfxContext> context;
  if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(BackendType::CAIRO)) {
     RefPtr<DrawTarget> dt =
        gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(destinationSurface,
                                                               IntSize(destinationSurface->GetSize().width,
                                                                       destinationSurface->GetSize().height));

    context = new gfxContext(dt);
  } else {
    context = new gfxContext(destinationSurface);
  }

  context->Translate(gfxPoint(-bounds.x, -bounds.y));
  LayerManagerD3D9::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
  cbInfo.Callback(this, context, aRegion, DrawRegionClip::CLIP_NONE, nsIntRegion(), cbInfo.CallbackData);

  for (uint32_t i = 0; i < aReadbackUpdates.Length(); ++i) {
    NS_ASSERTION(aMode == SurfaceMode::SURFACE_OPAQUE,
                 "Transparent surfaces should not be used for readback");
    const ReadbackProcessor::Update& update = aReadbackUpdates[i];
    nsIntPoint offset = update.mLayer->GetBackgroundLayerOffset();
    nsRefPtr<gfxContext> ctx =
        update.mLayer->GetSink()->BeginUpdate(update.mUpdateRect + offset,
                                              update.mSequenceCounter);
    if (ctx) {
      ctx->Translate(gfxPoint(offset.x, offset.y));
      ctx->SetSource(destinationSurface, gfxPoint(bounds.x, bounds.y));
      ctx->Paint();
      update.mLayer->GetSink()->EndUpdate(ctx, update.mUpdateRect + offset);
    }
  }

  // Release the cairo d3d9 surface before we try to composite it
  context = nullptr;

  nsAutoTArray<IDirect3DTexture9*,2> srcTextures;
  nsAutoTArray<IDirect3DTexture9*,2> destTextures;
  switch (aMode)
  {
    case SurfaceMode::SURFACE_OPAQUE:
      // Must release reference to dest surface before ending drawing
      destinationSurface = nullptr;
      opaqueRenderer.End();
      srcTextures.AppendElement(opaqueRenderer.GetTexture());
      destTextures.AppendElement(mTexture);
      break;

    case SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA: {
      LockTextureRectD3D9 textureLock(tmpTexture);
      if (!textureLock.HasLock()) {
        NS_WARNING("Failed to lock ThebesLayer tmpTexture texture.");
        return;
      }

      D3DLOCKED_RECT r = textureLock.GetLockRect();

      nsRefPtr<gfxImageSurface> imgSurface =
        new gfxImageSurface((unsigned char *)r.pBits,
                            bounds.Size(),
                            r.Pitch,
                            gfxImageFormat::ARGB32);

      if (destinationSurface) {
        nsRefPtr<gfxContext> context = new gfxContext(imgSurface);
        context->SetSource(destinationSurface);
        context->SetOperator(gfxContext::OPERATOR_SOURCE);
        context->Paint();
      }

      // Must release reference to dest surface before ending drawing
      destinationSurface = nullptr;
      imgSurface = nullptr;

      srcTextures.AppendElement(tmpTexture);
      destTextures.AppendElement(mTexture);
      break;
    }

    case SurfaceMode::SURFACE_COMPONENT_ALPHA: {
      // Must release reference to dest surface before ending drawing
      destinationSurface = nullptr;
      opaqueRenderer.End();
      opaqueRendererOnWhite.End();
      srcTextures.AppendElement(opaqueRenderer.GetTexture());
      destTextures.AppendElement(mTexture);
      srcTextures.AppendElement(opaqueRendererOnWhite.GetTexture());
      destTextures.AppendElement(mTextureOnWhite);
      break;
    }
  }
  NS_ASSERTION(srcTextures.Length() == destTextures.Length(), "Mismatched lengths");
  

  // Copy to the texture.
  for (uint32_t i = 0; i < srcTextures.Length(); ++i) {
    nsRefPtr<IDirect3DSurface9> srcSurface;
    nsRefPtr<IDirect3DSurface9> dstSurface;

    destTextures[i]->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
    srcTextures[i]->GetSurfaceLevel(0, getter_AddRefs(srcSurface));

    nsIntRegionRectIterator iter(aRegion);
    const nsIntRect *iterRect;
    while ((iterRect = iter.Next())) {
      RECT rect;
      rect.left = iterRect->x - bounds.x;
      rect.top = iterRect->y - bounds.y;
      rect.right = iterRect->XMost() - bounds.x;
      rect.bottom = iterRect->YMost() - bounds.y;

      POINT point;
      point.x = iterRect->x - visibleRect.x;
      point.y = iterRect->y - visibleRect.y;
      device()->UpdateSurface(srcSurface, &rect, dstSurface, &point);
    }
  }
}
Example #2
0
bool
JavaScriptChild::AnswerCall(const ObjectId &objId, const nsTArray<JSParam> &argv, ReturnStatus *rs,
                            JSVariant *result, nsTArray<JSParam> *outparams)
{
    AutoSafeJSContext cx;
    JSAutoRequest request(cx);

    // The outparam will be written to the buffer, so it must be set even if
    // the parent won't read it.
    *result = void_t();

    RootedObject obj(cx, findObject(objId));
    if (!obj)
        return false;

    MOZ_ASSERT(argv.Length() >= 2);

    RootedValue objv(cx);
    if (!toValue(cx, argv[0], &objv))
        return fail(cx, rs);

    JSAutoCompartment comp(cx, &objv.toObject());

    *result = JSVariant(void_t());

    AutoValueVector vals(cx);
    AutoValueVector outobjects(cx);
    for (size_t i = 0; i < argv.Length(); i++) {
        if (argv[i].type() == JSParam::Tvoid_t) {
            // This is an outparam.
            JSCompartment *compartment = js::GetContextCompartment(cx);
            RootedObject global(cx, JS_GetGlobalForCompartmentOrNull(cx, compartment));
            RootedObject obj(cx, xpc::NewOutObject(cx, global));
            if (!obj)
                return fail(cx, rs);
            if (!outobjects.append(ObjectValue(*obj)))
                return fail(cx, rs);
            if (!vals.append(ObjectValue(*obj)))
                return fail(cx, rs);
        } else {
            RootedValue v(cx);
            if (!toValue(cx, argv[i].get_JSVariant(), &v))
                return fail(cx, rs);
            if (!vals.append(v))
                return fail(cx, rs);
        }
    }

    uint32_t oldOpts =
        JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT);

    RootedValue rval(cx);
    bool success = JS::Call(cx, vals[1], vals[0], vals.length() - 2, vals.begin() + 2, &rval);

    JS_SetOptions(cx, oldOpts);

    if (!success)
        return fail(cx, rs);

    if (!toVariant(cx, rval, result))
        return fail(cx, rs);

    // Prefill everything with a dummy jsval.
    for (size_t i = 0; i < outobjects.length(); i++)
        outparams->AppendElement(JSParam(void_t()));

    // Go through each argument that was an outparam, retrieve the "value"
    // field, and add it to a temporary list. We need to do this separately
    // because the outparams vector is not rooted.
    vals.clear();
    for (size_t i = 0; i < outobjects.length(); i++) {
        RootedObject obj(cx, &outobjects[i].toObject());

        jsval v;
        JSBool found;
        if (JS_HasProperty(cx, obj, "value", &found)) {
            if (!JS_GetProperty(cx, obj, "value", &v))
                return fail(cx, rs);
        } else {
            v = UndefinedValue();
        }
        if (!vals.append(v))
            return fail(cx, rs);
    }

    // Copy the outparams. If any outparam is already set to a void_t, we
    // treat this as the outparam never having been set.
    for (size_t i = 0; i < vals.length(); i++) {
        JSVariant variant;
        if (!toVariant(cx, vals[i], &variant))
            return fail(cx, rs);
        outparams->ReplaceElementAt(i, JSParam(variant));
    }

    return ok(rs);
}
Example #3
0
nsCString
ToHexString(const nsTArray<uint8_t>& aBytes)
{
  return ToHexString(aBytes.Elements(), aBytes.Length());
}
Example #4
0
bool
WrapperAnswer::AnswerCallOrConstruct(const ObjectId &objId,
                                     const nsTArray<JSParam> &argv,
                                     const bool &construct,
                                     ReturnStatus *rs,
                                     JSVariant *result,
                                     nsTArray<JSParam> *outparams)
{
    AutoSafeJSContext cx;
    JSAutoRequest request(cx);

    // The outparam will be written to the buffer, so it must be set even if
    // the parent won't read it.
    *result = UndefinedVariant();

    RootedObject obj(cx, findObjectById(cx, objId));
    if (!obj)
        return fail(cx, rs);

    JSAutoCompartment comp(cx, obj);

    MOZ_ASSERT(argv.Length() >= 2);

    RootedValue objv(cx);
    if (!fromVariant(cx, argv[0], &objv))
        return fail(cx, rs);

    *result = JSVariant(UndefinedVariant());

    AutoValueVector vals(cx);
    AutoValueVector outobjects(cx);
    for (size_t i = 0; i < argv.Length(); i++) {
        if (argv[i].type() == JSParam::Tvoid_t) {
            // This is an outparam.
            JSCompartment *compartment = js::GetContextCompartment(cx);
            RootedObject global(cx, JS_GetGlobalForCompartmentOrNull(cx, compartment));
            RootedObject obj(cx, xpc::NewOutObject(cx, global));
            if (!obj)
                return fail(cx, rs);
            if (!outobjects.append(ObjectValue(*obj)))
                return fail(cx, rs);
            if (!vals.append(ObjectValue(*obj)))
                return fail(cx, rs);
        } else {
            RootedValue v(cx);
            if (!fromVariant(cx, argv[i].get_JSVariant(), &v))
                return fail(cx, rs);
            if (!vals.append(v))
                return fail(cx, rs);
        }
    }

    RootedValue rval(cx);
    {
        AutoSaveContextOptions asco(cx);
        ContextOptionsRef(cx).setDontReportUncaught(true);

        HandleValueArray args = HandleValueArray::subarray(vals, 2, vals.length() - 2);
        bool success;
        if (construct)
            success = JS::Construct(cx, vals[0], args, &rval);
        else
            success = JS::Call(cx, vals[1], vals[0], args, &rval);
        if (!success)
            return fail(cx, rs);
    }

    if (!toVariant(cx, rval, result))
        return fail(cx, rs);

    // Prefill everything with a dummy jsval.
    for (size_t i = 0; i < outobjects.length(); i++)
        outparams->AppendElement(JSParam(void_t()));

    // Go through each argument that was an outparam, retrieve the "value"
    // field, and add it to a temporary list. We need to do this separately
    // because the outparams vector is not rooted.
    vals.clear();
    for (size_t i = 0; i < outobjects.length(); i++) {
        RootedObject obj(cx, &outobjects[i].toObject());

        RootedValue v(cx);
        bool found;
        if (JS_HasProperty(cx, obj, "value", &found)) {
            if (!JS_GetProperty(cx, obj, "value", &v))
                return fail(cx, rs);
        } else {
            v = UndefinedValue();
        }
        if (!vals.append(v))
            return fail(cx, rs);
    }

    // Copy the outparams. If any outparam is already set to a void_t, we
    // treat this as the outparam never having been set.
    for (size_t i = 0; i < vals.length(); i++) {
        JSVariant variant;
        if (!toVariant(cx, vals[i], &variant))
            return fail(cx, rs);
        outparams->ReplaceElementAt(i, JSParam(variant));
    }

    LOG("%s.call(%s) = %s", ReceiverObj(objId), argv, OutVariant(*result));

    return ok(rs);
}
nsresult
HTMLFormControlsCollection::GetSortedControls(
  nsTArray<nsGenericHTMLFormElement*>& aControls) const
{
#ifdef DEBUG
  HTMLFormElement::AssertDocumentOrder(mElements, mForm);
  HTMLFormElement::AssertDocumentOrder(mNotInElements, mForm);
#endif

  aControls.Clear();

  // Merge the elements list and the not in elements list. Both lists are
  // already sorted.
  uint32_t elementsLen = mElements.Length();
  uint32_t notInElementsLen = mNotInElements.Length();
  aControls.SetCapacity(elementsLen + notInElementsLen);

  uint32_t elementsIdx = 0;
  uint32_t notInElementsIdx = 0;

  while (elementsIdx < elementsLen || notInElementsIdx < notInElementsLen) {
    // Check whether we're done with mElements
    if (elementsIdx == elementsLen) {
      NS_ASSERTION(notInElementsIdx < notInElementsLen,
                   "Should have remaining not-in-elements");
      // Append the remaining mNotInElements elements
      if (!aControls.AppendElements(mNotInElements.Elements() +
                                      notInElementsIdx,
                                    notInElementsLen -
                                      notInElementsIdx)) {
        return NS_ERROR_OUT_OF_MEMORY;
      }
      break;
    }
    // Check whether we're done with mNotInElements
    if (notInElementsIdx == notInElementsLen) {
      NS_ASSERTION(elementsIdx < elementsLen,
                   "Should have remaining in-elements");
      // Append the remaining mElements elements
      if (!aControls.AppendElements(mElements.Elements() +
                                      elementsIdx,
                                    elementsLen -
                                      elementsIdx)) {
        return NS_ERROR_OUT_OF_MEMORY;
      }
      break;
    }
    // Both lists have elements left.
    NS_ASSERTION(mElements[elementsIdx] &&
                 mNotInElements[notInElementsIdx],
                 "Should have remaining elements");
    // Determine which of the two elements should be ordered
    // first and add it to the end of the list.
    nsGenericHTMLFormElement* elementToAdd;
    if (HTMLFormElement::CompareFormControlPosition(
          mElements[elementsIdx], mNotInElements[notInElementsIdx], mForm) < 0) {
      elementToAdd = mElements[elementsIdx];
      ++elementsIdx;
    } else {
      elementToAdd = mNotInElements[notInElementsIdx];
      ++notInElementsIdx;
    }
    // Add the first element to the list.
    if (!aControls.AppendElement(elementToAdd)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }

  NS_ASSERTION(aControls.Length() == elementsLen + notInElementsLen,
               "Not all form controls were added to the sorted list");
#ifdef DEBUG
  HTMLFormElement::AssertDocumentOrder(aControls, mForm);
#endif

  return NS_OK;
}
Example #6
0
nsresult
nsTextAttrsMgr::GetRange(const nsTArray<nsITextAttr*>& aTextAttrArray,
                         PRInt32 *aStartHTOffset, PRInt32 *aEndHTOffset)
{
  PRUint32 attrLen = aTextAttrArray.Length();

  // Navigate backward from anchor accessible to find start offset.
  for (PRInt32 childIdx = mOffsetAccIdx - 1; childIdx >= 0; childIdx--) {
    nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);

    // Stop on embedded accessible since embedded accessibles are combined into
    // own range.
    if (nsAccUtils::IsEmbeddedObject(currAcc))
      break;

    nsIContent *currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
    NS_ENSURE_STATE(currElm);

    bool offsetFound = false;
    for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
      nsITextAttr *textAttr = aTextAttrArray[attrIdx];
      if (!textAttr->Equal(currElm)) {
        offsetFound = true;
        break;
      }
    }

    if (offsetFound)
      break;

    *(aStartHTOffset) -= nsAccUtils::TextLength(currAcc);
  }

  // Navigate forward from anchor accessible to find end offset.
  PRInt32 childLen = mHyperTextAcc->GetChildCount();
  for (PRInt32 childIdx = mOffsetAccIdx + 1; childIdx < childLen; childIdx++) {
    nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
    if (nsAccUtils::IsEmbeddedObject(currAcc))
      break;

    nsIContent *currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
    NS_ENSURE_STATE(currElm);

    bool offsetFound = false;
    for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
      nsITextAttr *textAttr = aTextAttrArray[attrIdx];

      // Alter the end offset when text attribute changes its value and stop
      // the search.
      if (!textAttr->Equal(currElm)) {
        offsetFound = true;
        break;
      }
    }

    if (offsetFound)
      break;

    (*aEndHTOffset) += nsAccUtils::TextLength(currAcc);
  }

  return NS_OK;
}
Example #7
0
bool
nsCaseTransformTextRunFactory::TransformString(
    const nsAString& aString,
    nsString& aConvertedString,
    bool aAllUppercase,
    const nsIAtom* aLanguage,
    nsTArray<bool>& aCharsToMergeArray,
    nsTArray<bool>& aDeletedCharsArray,
    nsTransformedTextRun* aTextRun,
    nsTArray<uint8_t>* aCanBreakBeforeArray,
    nsTArray<nsStyleContext*>* aStyleArray)
{
  NS_PRECONDITION(!aTextRun || (aCanBreakBeforeArray && aStyleArray),
                  "either none or all three optional parameters required");

  uint32_t length = aString.Length();
  const char16_t* str = aString.BeginReading();

  bool mergeNeeded = false;

  bool capitalizeDutchIJ = false;
  bool prevIsLetter = false;
  bool ntPrefix = false; // true immediately after a word-initial 'n' or 't'
                         // when doing Irish lowercasing
  uint32_t sigmaIndex = uint32_t(-1);
  nsIUGenCategory::nsUGenCategory cat;

  uint8_t style = aAllUppercase ? NS_STYLE_TEXT_TRANSFORM_UPPERCASE : 0;
  const nsIAtom* lang = aLanguage;

  LanguageSpecificCasingBehavior languageSpecificCasing = GetCasingFor(lang);
  mozilla::GreekCasing::State greekState;
  mozilla::IrishCasing::State irishState;
  uint32_t irishMark = uint32_t(-1); // location of possible prefix letter(s)

  for (uint32_t i = 0; i < length; ++i) {
    uint32_t ch = str[i];

    nsStyleContext* styleContext;
    if (aTextRun) {
      styleContext = aTextRun->mStyles[i];
      style = aAllUppercase ? NS_STYLE_TEXT_TRANSFORM_UPPERCASE :
        styleContext->StyleText()->mTextTransform;

      const nsStyleFont* styleFont = styleContext->StyleFont();
      nsIAtom* newLang = styleFont->mExplicitLanguage
                         ? styleFont->mLanguage : nullptr;
      if (lang != newLang) {
        lang = newLang;
        languageSpecificCasing = GetCasingFor(lang);
        greekState.Reset();
        irishState.Reset();
        irishMark = uint32_t(-1);
      }
    }

    int extraChars = 0;
    const mozilla::unicode::MultiCharMapping *mcm;
    bool inhibitBreakBefore = false; // have we just deleted preceding hyphen?

    if (NS_IS_HIGH_SURROGATE(ch) && i < length - 1 &&
        NS_IS_LOW_SURROGATE(str[i + 1])) {
      ch = SURROGATE_TO_UCS4(ch, str[i + 1]);
    }

    switch (style) {
    case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
      if (languageSpecificCasing == eLSCB_Turkish) {
        if (ch == 'I') {
          ch = LATIN_SMALL_LETTER_DOTLESS_I;
          prevIsLetter = true;
          sigmaIndex = uint32_t(-1);
          break;
        }
        if (ch == LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE) {
          ch = 'i';
          prevIsLetter = true;
          sigmaIndex = uint32_t(-1);
          break;
        }
      }

      cat = mozilla::unicode::GetGenCategory(ch);

      if (languageSpecificCasing == eLSCB_Irish &&
          cat == nsIUGenCategory::kLetter) {
        // See bug 1018805 for Irish lowercasing requirements
        if (!prevIsLetter && (ch == 'n' || ch == 't')) {
          ntPrefix = true;
        } else {
          if (ntPrefix && mozilla::IrishCasing::IsUpperVowel(ch)) {
            aConvertedString.Append('-');
            ++extraChars;
          }
          ntPrefix = false;
        }
      } else {
        ntPrefix = false;
      }

      // Special lowercasing behavior for Greek Sigma: note that this is listed
      // as context-sensitive in Unicode's SpecialCasing.txt, but is *not* a
      // language-specific mapping; it applies regardless of the language of
      // the element.
      //
      // The lowercase mapping for CAPITAL SIGMA should be to SMALL SIGMA (i.e.
      // the non-final form) whenever there is a following letter, or when the
      // CAPITAL SIGMA occurs in isolation (neither preceded nor followed by a
      // LETTER); and to FINAL SIGMA when it is preceded by another letter but
      // not followed by one.
      //
      // To implement the context-sensitive nature of this mapping, we keep
      // track of whether the previous character was a letter. If not, CAPITAL
      // SIGMA will map directly to SMALL SIGMA. If the previous character
      // was a letter, CAPITAL SIGMA maps to FINAL SIGMA and we record the
      // position in the converted string; if we then encounter another letter,
      // that FINAL SIGMA is replaced with a standard SMALL SIGMA.

      // If sigmaIndex is not -1, it marks where we have provisionally mapped
      // a CAPITAL SIGMA to FINAL SIGMA; if we now find another letter, we
      // need to change it to SMALL SIGMA.
      if (sigmaIndex != uint32_t(-1)) {
        if (cat == nsIUGenCategory::kLetter) {
          aConvertedString.SetCharAt(GREEK_SMALL_LETTER_SIGMA, sigmaIndex);
        }
      }

      if (ch == GREEK_CAPITAL_LETTER_SIGMA) {
        // If preceding char was a letter, map to FINAL instead of SMALL,
        // and note where it occurred by setting sigmaIndex; we'll change it
        // to standard SMALL SIGMA later if another letter follows
        if (prevIsLetter) {
          ch = GREEK_SMALL_LETTER_FINAL_SIGMA;
          sigmaIndex = aConvertedString.Length();
        } else {
          // CAPITAL SIGMA not preceded by a letter is unconditionally mapped
          // to SMALL SIGMA
          ch = GREEK_SMALL_LETTER_SIGMA;
          sigmaIndex = uint32_t(-1);
        }
        prevIsLetter = true;
        break;
      }

      // ignore diacritics for the purpose of contextual sigma mapping;
      // otherwise, reset prevIsLetter appropriately and clear the
      // sigmaIndex marker
      if (cat != nsIUGenCategory::kMark) {
        prevIsLetter = (cat == nsIUGenCategory::kLetter);
        sigmaIndex = uint32_t(-1);
      }

      mcm = mozilla::unicode::SpecialLower(ch);
      if (mcm) {
        int j = 0;
        while (j < 2 && mcm->mMappedChars[j + 1]) {
          aConvertedString.Append(mcm->mMappedChars[j]);
          ++extraChars;
          ++j;
        }
        ch = mcm->mMappedChars[j];
        break;
      }

      ch = ToLowerCase(ch);
      break;

    case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
      if (languageSpecificCasing == eLSCB_Turkish && ch == 'i') {
        ch = LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE;
        break;
      }

      if (languageSpecificCasing == eLSCB_Greek) {
        ch = mozilla::GreekCasing::UpperCase(ch, greekState);
        break;
      }

      if (languageSpecificCasing == eLSCB_Irish) {
        bool mark;
        uint8_t action;
        ch = mozilla::IrishCasing::UpperCase(ch, irishState, mark, action);
        if (mark) {
          irishMark = aConvertedString.Length();
          break;
        } else if (action) {
          nsString& str = aConvertedString; // shorthand
          switch (action) {
          case 1:
            // lowercase a single prefix letter
            NS_ASSERTION(str.Length() > 0 && irishMark < str.Length(),
                         "bad irishMark!");
            str.SetCharAt(ToLowerCase(str[irishMark]), irishMark);
            irishMark = uint32_t(-1);
            break;
          case 2:
            // lowercase two prefix letters (immediately before current pos)
            NS_ASSERTION(str.Length() >= 2 && irishMark == str.Length() - 2,
                         "bad irishMark!");
            str.SetCharAt(ToLowerCase(str[irishMark]), irishMark);
            str.SetCharAt(ToLowerCase(str[irishMark + 1]), irishMark + 1);
            irishMark = uint32_t(-1);
            break;
          case 3:
            // lowercase one prefix letter, and delete following hyphen
            // (which must be the immediately-preceding char)
            NS_ASSERTION(str.Length() >= 2 && irishMark == str.Length() - 2,
                         "bad irishMark!");
            str.Replace(irishMark, 2, ToLowerCase(str[irishMark]));
            aDeletedCharsArray[irishMark + 1] = true;
            // Remove the trailing entries (corresponding to the deleted hyphen)
            // from the auxiliary arrays.
            aCharsToMergeArray.SetLength(aCharsToMergeArray.Length() - 1);
            if (aTextRun) {
              aStyleArray->SetLength(aStyleArray->Length() - 1);
              aCanBreakBeforeArray->SetLength(aCanBreakBeforeArray->Length() - 1);
              inhibitBreakBefore = true;
            }
            mergeNeeded = true;
            irishMark = uint32_t(-1);
            break;
          }
          // ch has been set to the uppercase for current char;
          // No need to check for SpecialUpper here as none of the characters
          // that could trigger an Irish casing action have special mappings.
          break;
        }
        // If we didn't have any special action to perform, fall through
        // to check for special uppercase (ß)
      }

      mcm = mozilla::unicode::SpecialUpper(ch);
      if (mcm) {
        int j = 0;
        while (j < 2 && mcm->mMappedChars[j + 1]) {
          aConvertedString.Append(mcm->mMappedChars[j]);
          ++extraChars;
          ++j;
        }
        ch = mcm->mMappedChars[j];
        break;
      }

      ch = ToUpperCase(ch);
      break;

    case NS_STYLE_TEXT_TRANSFORM_CAPITALIZE:
      if (aTextRun) {
        if (capitalizeDutchIJ && ch == 'j') {
          ch = 'J';
          capitalizeDutchIJ = false;
          break;
        }
        capitalizeDutchIJ = false;
        if (i < aTextRun->mCapitalize.Length() && aTextRun->mCapitalize[i]) {
          if (languageSpecificCasing == eLSCB_Turkish && ch == 'i') {
            ch = LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE;
            break;
          }
          if (languageSpecificCasing == eLSCB_Dutch && ch == 'i') {
            ch = 'I';
            capitalizeDutchIJ = true;
            break;
          }

          mcm = mozilla::unicode::SpecialTitle(ch);
          if (mcm) {
            int j = 0;
            while (j < 2 && mcm->mMappedChars[j + 1]) {
              aConvertedString.Append(mcm->mMappedChars[j]);
              ++extraChars;
              ++j;
            }
            ch = mcm->mMappedChars[j];
            break;
          }

          ch = ToTitleCase(ch);
        }
      }
      break;

    case NS_STYLE_TEXT_TRANSFORM_FULLWIDTH:
      ch = mozilla::unicode::GetFullWidth(ch);
      break;

    default:
      break;
    }

    if (ch == uint32_t(-1)) {
      aDeletedCharsArray.AppendElement(true);
      mergeNeeded = true;
    } else {
      aDeletedCharsArray.AppendElement(false);
      aCharsToMergeArray.AppendElement(false);
      if (aTextRun) {
        aStyleArray->AppendElement(styleContext);
        aCanBreakBeforeArray->AppendElement(inhibitBreakBefore ? false :
                                            aTextRun->CanBreakLineBefore(i));
      }

      if (IS_IN_BMP(ch)) {
        aConvertedString.Append(ch);
      } else {
        aConvertedString.Append(H_SURROGATE(ch));
        aConvertedString.Append(L_SURROGATE(ch));
        ++i;
        aDeletedCharsArray.AppendElement(true); // not exactly deleted, but the
                                                // trailing surrogate is skipped
        ++extraChars;
      }

      while (extraChars-- > 0) {
        mergeNeeded = true;
        aCharsToMergeArray.AppendElement(true);
        if (aTextRun) {
          aStyleArray->AppendElement(styleContext);
          aCanBreakBeforeArray->AppendElement(false);
        }
      }
    }
  }

  return mergeNeeded;
}
HRESULT STDMETHODCALLTYPE DWriteFontFileStream::GetFileSize(UINT64* fileSize) {
  *fileSize = mData.Length();
  return S_OK;
}
Example #9
0
void
nsEventTargetChainItem::HandleEventTargetChain(
                          nsTArray<nsEventTargetChainItem>& aChain,
                          nsEventChainPostVisitor& aVisitor,
                          nsDispatchingCallback* aCallback,
                          ELMCreationDetector& aCd)
{
  // Save the target so that it can be restored later.
  nsCOMPtr<EventTarget> firstTarget = aVisitor.mEvent->target;
  uint32_t chainLength = aChain.Length();

  // Capture
  aVisitor.mEvent->mFlags.mInCapturePhase = true;
  aVisitor.mEvent->mFlags.mInBubblingPhase = false;
  for (uint32_t i = chainLength - 1; i > 0; --i) {
    nsEventTargetChainItem& item = aChain[i];
    if ((!aVisitor.mEvent->mFlags.mNoContentDispatch ||
         item.ForceContentDispatch()) &&
        !aVisitor.mEvent->mFlags.mPropagationStopped) {
      item.HandleEvent(aVisitor, aCd);
    }

    if (item.GetNewTarget()) {
      // item is at anonymous boundary. Need to retarget for the child items.
      for (uint32_t j = i; j > 0; --j) {
        uint32_t childIndex = j - 1;
        EventTarget* newTarget = aChain[childIndex].GetNewTarget();
        if (newTarget) {
          aVisitor.mEvent->target = newTarget;
          break;
        }
      }
    }
  }

  // Target
  aVisitor.mEvent->mFlags.mInBubblingPhase = true;
  nsEventTargetChainItem& targetItem = aChain[0];
  if (!aVisitor.mEvent->mFlags.mPropagationStopped &&
      (!aVisitor.mEvent->mFlags.mNoContentDispatch ||
       targetItem.ForceContentDispatch())) {
    targetItem.HandleEvent(aVisitor, aCd);
  }
  if (aVisitor.mEvent->mFlags.mInSystemGroup) {
    targetItem.PostHandleEvent(aVisitor);
  }

  // Bubble
  aVisitor.mEvent->mFlags.mInCapturePhase = false;
  for (uint32_t i = 1; i < chainLength; ++i) {
    nsEventTargetChainItem& item = aChain[i];
    EventTarget* newTarget = item.GetNewTarget();
    if (newTarget) {
      // Item is at anonymous boundary. Need to retarget for the current item
      // and for parent items.
      aVisitor.mEvent->target = newTarget;
    }

    if (aVisitor.mEvent->mFlags.mBubbles || newTarget) {
      if ((!aVisitor.mEvent->mFlags.mNoContentDispatch ||
           item.ForceContentDispatch()) &&
          !aVisitor.mEvent->mFlags.mPropagationStopped) {
        item.HandleEvent(aVisitor, aCd);
      }
      if (aVisitor.mEvent->mFlags.mInSystemGroup) {
        item.PostHandleEvent(aVisitor);
      }
    }
  }
  aVisitor.mEvent->mFlags.mInBubblingPhase = false;

  if (!aVisitor.mEvent->mFlags.mInSystemGroup) {
    // Dispatch to the system event group.  Make sure to clear the
    // STOP_DISPATCH flag since this resets for each event group.
    aVisitor.mEvent->mFlags.mPropagationStopped = false;
    aVisitor.mEvent->mFlags.mImmediatePropagationStopped = false;

    // Setting back the original target of the event.
    aVisitor.mEvent->target = aVisitor.mEvent->originalTarget;

    // Special handling if PresShell (or some other caller)
    // used a callback object.
    if (aCallback) {
      aCallback->HandleEvent(aVisitor);
    }

    // Retarget for system event group (which does the default handling too).
    // Setting back the target which was used also for default event group.
    aVisitor.mEvent->target = firstTarget;
    aVisitor.mEvent->mFlags.mInSystemGroup = true;
    HandleEventTargetChain(aChain,
                           aVisitor,
                           aCallback,
                           aCd);
    aVisitor.mEvent->mFlags.mInSystemGroup = false;

    // After dispatch, clear all the propagation flags so that
    // system group listeners don't affect to the event.
    aVisitor.mEvent->mFlags.mPropagationStopped = false;
    aVisitor.mEvent->mFlags.mImmediatePropagationStopped = false;
  }
}
nsresult
AppleATDecoder::GetInputAudioDescription(AudioStreamBasicDescription& aDesc,
                                         const nsTArray<uint8_t>& aExtraData)
{
  // Request the properties from CoreAudio using the codec magic cookie
  AudioFormatInfo formatInfo;
  PodZero(&formatInfo.mASBD);
  formatInfo.mASBD.mFormatID = mFormatID;
  if (mFormatID == kAudioFormatMPEG4AAC) {
    formatInfo.mASBD.mFormatFlags = mConfig.extended_profile;
  }
  formatInfo.mMagicCookieSize = aExtraData.Length();
  formatInfo.mMagicCookie = aExtraData.Elements();

  UInt32 formatListSize;
  // Attempt to retrieve the default format using
  // kAudioFormatProperty_FormatInfo method.
  // This method only retrieves the FramesPerPacket information required
  // by the decoder, which depends on the codec type and profile.
  aDesc.mFormatID = mFormatID;
  aDesc.mChannelsPerFrame = mConfig.channel_count;
  aDesc.mSampleRate = mConfig.samples_per_second;
  UInt32 inputFormatSize = sizeof(aDesc);
  OSStatus rv = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo,
                                       0,
                                       NULL,
                                       &inputFormatSize,
                                       &aDesc);
  if (NS_WARN_IF(rv)) {
    return NS_ERROR_FAILURE;
  }

  // If any of the methods below fail, we will return the default format as
  // created using kAudioFormatProperty_FormatInfo above.
  rv = AudioFormatGetPropertyInfo(kAudioFormatProperty_FormatList,
                                  sizeof(formatInfo),
                                  &formatInfo,
                                  &formatListSize);
  if (rv || (formatListSize % sizeof(AudioFormatListItem))) {
    return NS_OK;
  }
  size_t listCount = formatListSize / sizeof(AudioFormatListItem);
  nsAutoArrayPtr<AudioFormatListItem> formatList(
    new AudioFormatListItem[listCount]);

  rv = AudioFormatGetProperty(kAudioFormatProperty_FormatList,
                              sizeof(formatInfo),
                              &formatInfo,
                              &formatListSize,
                              formatList);
  if (rv) {
    return NS_OK;
  }
  LOG("found %u available audio stream(s)",
      formatListSize / sizeof(AudioFormatListItem));
  // Get the index number of the first playable format.
  // This index number will be for the highest quality layer the platform
  // is capable of playing.
  UInt32 itemIndex;
  UInt32 indexSize = sizeof(itemIndex);
  rv = AudioFormatGetProperty(kAudioFormatProperty_FirstPlayableFormatFromList,
                              formatListSize,
                              formatList,
                              &indexSize,
                              &itemIndex);
  if (rv) {
    return NS_OK;
  }

  aDesc = formatList[itemIndex].mASBD;

  return NS_OK;
}
NS_IMETHODIMP
nsDOMMultipartBlob::MozSlice(PRInt64 aStart, PRInt64 aEnd,
                             const nsAString& aContentType,
                             PRUint8 optional_argc,
                             nsIDOMBlob **aBlob)
{
    nsresult rv;
    *aBlob = nsnull;

    // Truncate aStart and aEnd so that we stay within this file.
    PRUint64 thisLength;
    rv = GetSize(&thisLength);
    NS_ENSURE_SUCCESS(rv, rv);

    if (!optional_argc) {
        aEnd = (PRInt64)thisLength;
    }

    // Modifies aStart and aEnd.
    ParseSize((PRInt64)thisLength, aStart, aEnd);

    // If we clamped to nothing we create an empty blob
    nsTArray<nsCOMPtr<nsIDOMBlob> > blobs;

    PRUint64 length = aEnd - aStart;
    PRUint64 skipStart = aStart;

    NS_ABORT_IF_FALSE(PRUint64(aStart) + length <= thisLength, "Er, what?");

    // Prune the list of blobs if we can
    PRUint32 i;
    for (i = 0; length && skipStart && i < mBlobs.Length(); i++) {
        nsIDOMBlob* blob = mBlobs[i].get();

        PRUint64 l;
        rv = blob->GetSize(&l);
        NS_ENSURE_SUCCESS(rv, rv);

        if (skipStart < l) {
            PRUint64 upperBound = NS_MIN<PRUint64>(l - skipStart, length);

            nsCOMPtr<nsIDOMBlob> firstBlob;
            rv = mBlobs.ElementAt(i)->MozSlice(skipStart, skipStart + upperBound,
                                               aContentType, 2,
                                               getter_AddRefs(firstBlob));
            NS_ENSURE_SUCCESS(rv, rv);

            // Avoid wrapping a single blob inside an nsDOMMultipartBlob
            if (length == upperBound) {
                firstBlob.forget(aBlob);
                return NS_OK;
            }

            blobs.AppendElement(firstBlob);
            length -= upperBound;
            i++;
            break;
        }
        skipStart -= l;
    }

    // Now append enough blobs until we're done
    for (; length && i < mBlobs.Length(); i++) {
        nsIDOMBlob* blob = mBlobs[i].get();

        PRUint64 l;
        rv = blob->GetSize(&l);
        NS_ENSURE_SUCCESS(rv, rv);

        if (length < l) {
            nsCOMPtr<nsIDOMBlob> lastBlob;
            rv = mBlobs.ElementAt(i)->MozSlice(0, length, aContentType, 2,
                                               getter_AddRefs(lastBlob));
            NS_ENSURE_SUCCESS(rv, rv);

            blobs.AppendElement(lastBlob);
        } else {
            blobs.AppendElement(blob);
        }
        length -= NS_MIN<PRUint64>(l, length);
    }

    // we can create our blob now
    nsCOMPtr<nsIDOMBlob> blob = new nsDOMMultipartBlob(blobs, aContentType);
    blob.forget(aBlob);
    return NS_OK;
}
int32_t
GfxInfoBase::FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& info,
                                         nsAString& aSuggestedVersion,
                                         int32_t aFeature,
                                         OperatingSystem os)
{
  int32_t status = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;

  nsAutoString adapterVendorID;
  nsAutoString adapterDeviceID;
  nsAutoString adapterDriverVersionString;
  if (NS_FAILED(GetAdapterVendorID(adapterVendorID)) ||
      NS_FAILED(GetAdapterDeviceID(adapterDeviceID)) ||
      NS_FAILED(GetAdapterDriverVersion(adapterDriverVersionString)))
  {
    return 0;
  }

  uint64_t driverVersion;
  ParseDriverVersion(adapterDriverVersionString, &driverVersion);

  uint32_t i = 0;
  for (; i < info.Length(); i++) {
    if (info[i].mOperatingSystem != DRIVER_OS_ALL &&
        info[i].mOperatingSystem != os)
    {
      continue;
    }

    if (info[i].mOperatingSystemVersion && info[i].mOperatingSystemVersion != OperatingSystemVersion()) {
        continue;
    }

    if (!info[i].mAdapterVendor.Equals(GfxDriverInfo::GetDeviceVendor(VendorAll), nsCaseInsensitiveStringComparator()) &&
        !info[i].mAdapterVendor.Equals(adapterVendorID, nsCaseInsensitiveStringComparator())) {
      continue;
    }

    if (info[i].mDevices != GfxDriverInfo::allDevices && info[i].mDevices->Length()) {
        bool deviceMatches = false;
        for (uint32_t j = 0; j < info[i].mDevices->Length(); j++) {
            if ((*info[i].mDevices)[j].Equals(adapterDeviceID, nsCaseInsensitiveStringComparator())) {
                deviceMatches = true;
                break;
            }
        }

        if (!deviceMatches) {
            continue;
        }
    }

    bool match = false;

    if (!info[i].mHardware.IsEmpty() && !info[i].mHardware.Equals(Hardware())) {
        continue;
    }
    if (!info[i].mModel.IsEmpty() && !info[i].mModel.Equals(Model())) {
        continue;
    }
    if (!info[i].mProduct.IsEmpty() && !info[i].mProduct.Equals(Product())) {
        continue;
    }
    if (!info[i].mManufacturer.IsEmpty() && !info[i].mManufacturer.Equals(Manufacturer())) {
        continue;
    }

#if defined(XP_WIN) || defined(ANDROID)
    switch (info[i].mComparisonOp) {
    case DRIVER_LESS_THAN:
      match = driverVersion < info[i].mDriverVersion;
      break;
    case DRIVER_LESS_THAN_OR_EQUAL:
      match = driverVersion <= info[i].mDriverVersion;
      break;
    case DRIVER_GREATER_THAN:
      match = driverVersion > info[i].mDriverVersion;
      break;
    case DRIVER_GREATER_THAN_OR_EQUAL:
      match = driverVersion >= info[i].mDriverVersion;
      break;
    case DRIVER_EQUAL:
      match = driverVersion == info[i].mDriverVersion;
      break;
    case DRIVER_NOT_EQUAL:
      match = driverVersion != info[i].mDriverVersion;
      break;
    case DRIVER_BETWEEN_EXCLUSIVE:
      match = driverVersion > info[i].mDriverVersion && driverVersion < info[i].mDriverVersionMax;
      break;
    case DRIVER_BETWEEN_INCLUSIVE:
      match = driverVersion >= info[i].mDriverVersion && driverVersion <= info[i].mDriverVersionMax;
      break;
    case DRIVER_BETWEEN_INCLUSIVE_START:
      match = driverVersion >= info[i].mDriverVersion && driverVersion < info[i].mDriverVersionMax;
      break;
    case DRIVER_COMPARISON_IGNORED:
      // We don't have a comparison op, so we match everything.
      match = true;
      break;
    default:
      NS_WARNING("Bogus op in GfxDriverInfo");
      break;
    }
#else
    // We don't care what driver version it was. We only check OS version and if
    // the device matches.
    match = true;
#endif

    if (match || info[i].mDriverVersion == GfxDriverInfo::allDriverVersions) {
      if (info[i].mFeature == GfxDriverInfo::allFeatures ||
          info[i].mFeature == aFeature)
      {
        status = info[i].mFeatureStatus;
        break;
      }
    }
  }

  // Depends on Windows driver versioning. We don't pass a GfxDriverInfo object
  // back to the Windows handler, so we must handle this here.
#if defined(XP_WIN)
  if (status == FEATURE_BLOCKED_DRIVER_VERSION) {
    if (info[i].mSuggestedVersion) {
        aSuggestedVersion.AppendPrintf("%s", info[i].mSuggestedVersion);
    } else if (info[i].mComparisonOp == DRIVER_LESS_THAN &&
               info[i].mDriverVersion != GfxDriverInfo::allDriverVersions)
    {
        aSuggestedVersion.AppendPrintf("%lld.%lld.%lld.%lld",
                                      (info[i].mDriverVersion & 0xffff000000000000) >> 48,
                                      (info[i].mDriverVersion & 0x0000ffff00000000) >> 32,
                                      (info[i].mDriverVersion & 0x00000000ffff0000) >> 16,
                                      (info[i].mDriverVersion & 0x000000000000ffff));
    }
  }
Example #13
0
nsresult
nsDOMStoragePersistentDB::RemoveOwners(const nsTArray<nsString> &aOwners,
                                       bool aIncludeSubDomains,
                                       bool aMatch)
{
  if (aOwners.Length() == 0) {
    if (aMatch) {
      return NS_OK;
    }

    return RemoveAll();
  }

  // Using nsString here because it is going to be very long
  nsCString expression;

  if (aMatch) {
    expression.AppendLiteral("DELETE FROM webappsstore2_view WHERE scope IN (");
  } else {
    expression.AppendLiteral("DELETE FROM webappsstore2_view WHERE scope NOT IN (");
  }

  for (PRUint32 i = 0; i < aOwners.Length(); i++) {
    if (i)
      expression.AppendLiteral(" UNION ");

    expression.AppendLiteral(
      "SELECT DISTINCT scope FROM webappsstore2_temp WHERE scope GLOB :scope");
    expression.AppendInt(i);
    expression.AppendLiteral(" UNION ");
    expression.AppendLiteral(
      "SELECT DISTINCT scope FROM webappsstore2 WHERE scope GLOB :scope");
    expression.AppendInt(i);
  }
  expression.AppendLiteral(");");

  nsCOMPtr<mozIStorageStatement> statement;

  nsresult rv;

  rv = MaybeCommitInsertTransaction();
  NS_ENSURE_SUCCESS(rv, rv);

  rv = mConnection->CreateStatement(expression,
                                    getter_AddRefs(statement));
  NS_ENSURE_SUCCESS(rv, rv);

  for (PRUint32 i = 0; i < aOwners.Length(); i++) {
    nsCAutoString quotaKey;
    rv = nsDOMStorageDBWrapper::CreateDomainScopeDBKey(
      NS_ConvertUTF16toUTF8(aOwners[i]), quotaKey);

    if (DomainMaybeCached(quotaKey)) {
      mCachedUsage = 0;
      mCachedOwner.Truncate();
    }

    if (!aIncludeSubDomains)
      quotaKey.AppendLiteral(":");
    quotaKey.AppendLiteral("*");

    nsCAutoString paramName;
    paramName.Assign("scope");
    paramName.AppendInt(i);

    rv = statement->BindUTF8StringByName(paramName, quotaKey);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  rv = statement->Execute();
  NS_ENSURE_SUCCESS(rv, rv);

  MarkAllScopesDirty();

  return NS_OK;
}
nsresult
nsSVGFilterInstance::BuildPrimitives(nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
                                     nsTArray<RefPtr<SourceSurface>>& aInputImages)
{
  mSourceGraphicIndex = GetLastResultIndex(aPrimitiveDescrs);

  // Clip previous filter's output to this filter's filter region.
  if (mSourceGraphicIndex >= 0) {
    FilterPrimitiveDescription& sourceDescr = aPrimitiveDescrs[mSourceGraphicIndex];
    sourceDescr.SetPrimitiveSubregion(sourceDescr.PrimitiveSubregion().Intersect(mFilterSpaceBounds));
  }

  // Get the filter primitive elements.
  nsTArray<RefPtr<nsSVGFE> > primitives;
  for (nsIContent* child = mFilterElement->nsINode::GetFirstChild();
       child;
       child = child->GetNextSibling()) {
    RefPtr<nsSVGFE> primitive;
    CallQueryInterface(child, (nsSVGFE**)getter_AddRefs(primitive));
    if (primitive) {
      primitives.AppendElement(primitive);
    }
  }

  // Maps source image name to source index.
  nsDataHashtable<nsStringHashKey, int32_t> imageTable(8);

  // The principal that we check principals of any loaded images against.
  nsCOMPtr<nsIPrincipal> principal = mTargetContent->NodePrincipal();

  bool filterInputIsTainted = IsFilterInputTainted(mTargetContent);

  for (uint32_t primitiveElementIndex = 0;
       primitiveElementIndex < primitives.Length();
       ++primitiveElementIndex) {
    nsSVGFE* filter = primitives[primitiveElementIndex];

    AutoTArray<int32_t,2> sourceIndices;
    nsresult rv = GetSourceIndices(filter, aPrimitiveDescrs, imageTable, sourceIndices);
    if (NS_FAILED(rv)) {
      return rv;
    }

    IntRect primitiveSubregion =
      ComputeFilterPrimitiveSubregion(filter, aPrimitiveDescrs, sourceIndices);

    nsTArray<bool> sourcesAreTainted;
    GetInputsAreTainted(aPrimitiveDescrs, sourceIndices, filterInputIsTainted, sourcesAreTainted);

    FilterPrimitiveDescription descr =
      filter->GetPrimitiveDescription(this, primitiveSubregion, sourcesAreTainted, aInputImages);

    descr.SetIsTainted(filter->OutputIsTainted(sourcesAreTainted, principal));
    descr.SetFilterSpaceBounds(mFilterSpaceBounds);
    descr.SetPrimitiveSubregion(primitiveSubregion.Intersect(descr.FilterSpaceBounds()));

    for (uint32_t i = 0; i < sourceIndices.Length(); i++) {
      int32_t inputIndex = sourceIndices[i];
      descr.SetInputPrimitive(i, inputIndex);

      ColorSpace inputColorSpace = inputIndex >= 0
        ? aPrimitiveDescrs[inputIndex].OutputColorSpace()
        : ColorSpace(ColorSpace::SRGB);

      ColorSpace desiredInputColorSpace = filter->GetInputColorSpace(i, inputColorSpace);
      descr.SetInputColorSpace(i, desiredInputColorSpace);
      if (i == 0) {
        // the output color space is whatever in1 is if there is an in1
        descr.SetOutputColorSpace(desiredInputColorSpace);
      }
    }

    if (sourceIndices.Length() == 0) {
      descr.SetOutputColorSpace(filter->GetOutputColorSpace());
    }

    aPrimitiveDescrs.AppendElement(descr);
    uint32_t primitiveDescrIndex = aPrimitiveDescrs.Length() - 1;

    nsAutoString str;
    filter->GetResultImageName().GetAnimValue(str, filter);
    imageTable.Put(str, primitiveDescrIndex);
  }

  return NS_OK;
}
// A U2F Sign operation creates a signature over the "param" arguments (plus
// some other stuff) using the private key indicated in the key handle argument.
//
// The format of the signed data is as follows:
//
//  32    Application parameter
//  1     User presence (0x01)
//  4     Counter
//  32    Challenge parameter
//
// The format of the signature data is as follows:
//
//  1     User presence
//  4     Counter
//  *     Signature
//
nsresult
U2FSoftTokenManager::Sign(nsTArray<uint8_t>& aApplication,
                          nsTArray<uint8_t>& aChallenge,
                          nsTArray<uint8_t>& aKeyHandle,
                          nsTArray<uint8_t>& aSignature)
{
  nsNSSShutDownPreventionLock locker;
  if (NS_WARN_IF(isAlreadyShutDown())) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  MOZ_ASSERT(mInitialized);
  if (NS_WARN_IF(!mInitialized)) {
    nsresult rv = Init();
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
  }

  MOZ_ASSERT(mWrappingKey);

  UniquePK11SlotInfo slot(PK11_GetInternalSlot());
  MOZ_ASSERT(slot.get());

  if (NS_WARN_IF((aChallenge.Length() != kParamLen) || (aApplication.Length() != kParamLen))) {
    MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
            ("Parameter lengths are wrong! challenge=%d app=%d expected=%d",
             (uint32_t)aChallenge.Length(), (uint32_t)aApplication.Length(), kParamLen));

    return NS_ERROR_ILLEGAL_VALUE;
  }

  // Decode the key handle
  UniqueSECKEYPrivateKey privKey = PrivateKeyFromKeyHandle(slot, mWrappingKey,
                                                           aKeyHandle.Elements(),
                                                           aKeyHandle.Length(),
                                                           aApplication.Elements(),
                                                           aApplication.Length(),
                                                           locker);
  if (NS_WARN_IF(!privKey.get())) {
    MOZ_LOG(gNSSTokenLog, LogLevel::Warning, ("Couldn't get the priv key!"));
    return NS_ERROR_FAILURE;
  }

  // Increment the counter and turn it into a SECItem
  mCounter += 1;
  ScopedAutoSECItem counterItem(4);
  counterItem.data[0] = (mCounter >> 24) & 0xFF;
  counterItem.data[1] = (mCounter >> 16) & 0xFF;
  counterItem.data[2] = (mCounter >>  8) & 0xFF;
  counterItem.data[3] = (mCounter >>  0) & 0xFF;
  uint32_t counter = mCounter;
  AbstractThread::MainThread()->Dispatch(NS_NewRunnableFunction(
                                           [counter] () {
                                             MOZ_ASSERT(NS_IsMainThread());
                                             Preferences::SetUint(PREF_U2F_NSSTOKEN_COUNTER, counter);
                                           }));

  // Compute the signature
  mozilla::dom::CryptoBuffer signedDataBuf;
  if (NS_WARN_IF(!signedDataBuf.SetCapacity(1 + 4 + (2 * kParamLen), mozilla::fallible))) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  // It's OK to ignore the return values here because we're writing into
  // pre-allocated space
  signedDataBuf.AppendElements(aApplication.Elements(), aApplication.Length(),
                               mozilla::fallible);
  signedDataBuf.AppendElement(0x01, mozilla::fallible);
  signedDataBuf.AppendSECItem(counterItem);
  signedDataBuf.AppendElements(aChallenge.Elements(), aChallenge.Length(),
                               mozilla::fallible);

  if (MOZ_LOG_TEST(gNSSTokenLog, LogLevel::Debug)) {
    nsAutoCString base64;
    nsresult rv = Base64URLEncode(signedDataBuf.Length(), signedDataBuf.Elements(),
                                  Base64URLEncodePaddingPolicy::Omit, base64);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return NS_ERROR_FAILURE;
    }

    MOZ_LOG(gNSSTokenLog, LogLevel::Debug,
            ("U2F Token signing bytes (base64): %s", base64.get()));
  }

  ScopedAutoSECItem signatureItem;
  SECStatus srv = SEC_SignData(&signatureItem, signedDataBuf.Elements(),
                               signedDataBuf.Length(), privKey.get(),
                               SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE);
  if (NS_WARN_IF(srv != SECSuccess)) {
    MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
            ("Signature failure: %d", PORT_GetError()));
    return NS_ERROR_FAILURE;
  }

  // Assemble the signature data into a buffer for return
  mozilla::dom::CryptoBuffer signatureBuf;
  if (NS_WARN_IF(!signatureBuf.SetCapacity(1 + counterItem.len + signatureItem.len,
                                           mozilla::fallible))) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  // It's OK to ignore the return values here because we're writing into
  // pre-allocated space
  signatureBuf.AppendElement(0x01, mozilla::fallible);
  signatureBuf.AppendSECItem(counterItem);
  signatureBuf.AppendSECItem(signatureItem);

  aSignature = signatureBuf;
  return NS_OK;
}
Example #16
0
void SortLayersBy3DZOrder(nsTArray<Layer*>& aLayers)
{
  uint32_t nodeCount = aLayers.Length();
  if (nodeCount > MAX_SORTABLE_LAYERS) {
    return;
  }
  DirectedGraph<Layer*> graph;

#ifdef DEBUG
  if (gDumpLayerSortList) {
    for (uint32_t i = 0; i < nodeCount; i++) {
      if (aLayers.ElementAt(i)->GetDebugColorIndex() == 0) {
        aLayers.ElementAt(i)->SetDebugColorIndex(gColorIndex++);
        if (gColorIndex > 7) {
          gColorIndex = 1;
        }
      }
    }
    fprintf(stderr, " --- Layers before sorting: --- \n");
    DumpLayerList(aLayers);
  }
#endif

  // Iterate layers and determine edges.
  for (uint32_t i = 0; i < nodeCount; i++) {
    for (uint32_t j = i + 1; j < nodeCount; j++) {
      Layer* a = aLayers.ElementAt(i);
      Layer* b = aLayers.ElementAt(j);
      LayerSortOrder order = CompareDepth(a, b);
      if (order == ABeforeB) {
        graph.AddEdge(a, b);
      } else if (order == BBeforeA) {
        graph.AddEdge(b, a);
      }
    }
  }

#ifdef DEBUG
  if (gDumpLayerSortList) {
    fprintf(stderr, " --- Edge List: --- \n");
    DumpEdgeList(graph);
  }
#endif

  // Build a new array using the graph.
  nsTArray<Layer*> noIncoming;
  nsTArray<Layer*> sortedList;

  // Make a list of all layers with no incoming edges.
  noIncoming.AppendElements(aLayers);
  const nsTArray<DirectedGraph<Layer*>::Edge>& edges = graph.GetEdgeList();
  for (uint32_t i = 0; i < edges.Length(); i++) {
    noIncoming.RemoveElement(edges.ElementAt(i).mTo);
  }

  // Move each item without incoming edges into the sorted list,
  // and remove edges from it.
  do {
    if (!noIncoming.IsEmpty()) {
      uint32_t last = noIncoming.Length() - 1;

      Layer* layer = noIncoming.ElementAt(last);
      MOZ_ASSERT(layer); // don't let null layer pointers sneak into sortedList

      noIncoming.RemoveElementAt(last);
      sortedList.AppendElement(layer);

      nsTArray<DirectedGraph<Layer*>::Edge> outgoing;
      graph.GetEdgesFrom(layer, outgoing);
      for (uint32_t i = 0; i < outgoing.Length(); i++) {
        DirectedGraph<Layer*>::Edge edge = outgoing.ElementAt(i);
        graph.RemoveEdge(edge);
        if (!graph.NumEdgesTo(edge.mTo)) {
          // If this node also has no edges now, add it to the list
          noIncoming.AppendElement(edge.mTo);
        }
      }
    }

    // If there are no nodes without incoming edges, but there
    // are still edges, then we have a cycle.
    if (noIncoming.IsEmpty() && graph.GetEdgeCount()) {
      // Find the node with the least incoming edges.
      uint32_t minEdges = UINT_MAX;
      Layer* minNode = nullptr;
      for (uint32_t i = 0; i < aLayers.Length(); i++) {
        uint32_t edgeCount = graph.NumEdgesTo(aLayers.ElementAt(i));
        if (edgeCount && edgeCount < minEdges) {
          minEdges = edgeCount;
          minNode = aLayers.ElementAt(i);
          if (minEdges == 1) {
            break;
          }
        }
      }

      if (minNode) {
        // Remove all of them!
        graph.RemoveEdgesTo(minNode);
        noIncoming.AppendElement(minNode);
      }
    }
  } while (!noIncoming.IsEmpty());
  NS_ASSERTION(!graph.GetEdgeCount(), "Cycles detected!");
#ifdef DEBUG
  if (gDumpLayerSortList) {
    fprintf(stderr, " --- Layers after sorting: --- \n");
    DumpLayerList(sortedList);
  }
#endif

  aLayers.Clear();
  aLayers.AppendElements(sortedList);
}
Example #17
0
bool
DBusWatcher::Poll()
{
  int res = TEMP_FAILURE_RETRY(poll(mPollData.Elements(),
                                    mPollData.Length(), -1));
  NS_ENSURE_TRUE(res > 0, false);

  bool continueThread = true;

  nsTArray<pollfd>::size_type i = 0;

  while (i < mPollData.Length()) {
    if (mPollData[i].revents == POLLIN) {
      if (mPollData[i].fd == mControlFdR.get()) {
        char data;
        res = TEMP_FAILURE_RETRY(read(mControlFdR.get(), &data, sizeof(data)));
        NS_ENSURE_TRUE(res > 0, false);

        switch (data) {
          case DBUS_EVENT_LOOP_EXIT:
            continueThread = false;
            break;
          case DBUS_EVENT_LOOP_ADD:
            HandleWatchAdd();
            break;
          case DBUS_EVENT_LOOP_REMOVE:
            HandleWatchRemove();
            // don't increment i, or we'll skip one element
            continue;
          case DBUS_EVENT_LOOP_WAKEUP:
            NS_ProcessPendingEvents(NS_GetCurrentThread(),
                                    PR_INTERVAL_NO_TIMEOUT);
            break;
          default:
#if DEBUG
            nsCString warning("unknown command ");
            warning.AppendInt(data);
            NS_WARNING(warning.get());
#endif
            break;
        }
      } else {
        short events = mPollData[i].revents;
        mPollData[i].revents = 0;

        dbus_watch_handle(mWatchData[i], UnixEventsToDBusFlags(events));

        DBusDispatchStatus dbusDispatchStatus;
        do {
          dbusDispatchStatus = dbus_connection_dispatch(GetConnection());
        } while (dbusDispatchStatus == DBUS_DISPATCH_DATA_REMAINS);

        // Break at this point since we don't know if the operation
        // was destructive
        break;
      }
    }

    ++i;
  }

  return continueThread;
}
Example #18
0
NS_IMETHODIMP
nsCommandLine::GetLength(int32_t *aResult)
{
  *aResult = int32_t(mArgs.Length());
  return NS_OK;
}
Example #19
0
int32_t
GfxInfoBase::FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& info,
                                         nsAString& aSuggestedVersion,
                                         int32_t aFeature,
                                         nsACString& aFailureId,
                                         OperatingSystem os)
{
  int32_t status = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;

  uint32_t i = 0;
  for (; i < info.Length(); i++) {
    // Do the operating system check first, no point in getting the driver
    // info if we won't need to use it.  If the OS of the system we are running
    // on is unknown, we still let DRIVER_OS_ALL catch and disable it; 
    // if the OS of the downloadable entry is unknown, we skip the entry
    // as invalid.
    if (info[i].mOperatingSystem == DRIVER_OS_UNKNOWN ||
        (info[i].mOperatingSystem != DRIVER_OS_ALL &&
         info[i].mOperatingSystem != os))
    {
      continue;
    }

    if (info[i].mOperatingSystemVersion && info[i].mOperatingSystemVersion != OperatingSystemVersion()) {
        continue;
    }

    // XXX: it would be better not to do this everytime round the loop
    nsAutoString adapterVendorID;
    nsAutoString adapterDeviceID;
    nsAutoString adapterDriverVersionString;
    if (info[i].mGpu2) {
      if (NS_FAILED(GetAdapterVendorID2(adapterVendorID)) ||
          NS_FAILED(GetAdapterDeviceID2(adapterDeviceID)) ||
          NS_FAILED(GetAdapterDriverVersion2(adapterDriverVersionString)))
      {
        return 0;
      }
    } else {
      if (NS_FAILED(GetAdapterVendorID(adapterVendorID)) ||
          NS_FAILED(GetAdapterDeviceID(adapterDeviceID)) ||
          NS_FAILED(GetAdapterDriverVersion(adapterDriverVersionString)))
      {
        return 0;
      }
    }

#if defined(XP_WIN) || defined(ANDROID)
    uint64_t driverVersion;
    ParseDriverVersion(adapterDriverVersionString, &driverVersion);
#endif

    if (!info[i].mAdapterVendor.Equals(GfxDriverInfo::GetDeviceVendor(VendorAll), nsCaseInsensitiveStringComparator()) &&
        !info[i].mAdapterVendor.Equals(adapterVendorID, nsCaseInsensitiveStringComparator())) {
      continue;
    }

    if (info[i].mDevices != GfxDriverInfo::allDevices && info[i].mDevices->Length()) {
        bool deviceMatches = false;
        for (uint32_t j = 0; j < info[i].mDevices->Length(); j++) {
            if ((*info[i].mDevices)[j].Equals(adapterDeviceID, nsCaseInsensitiveStringComparator())) {
                deviceMatches = true;
                break;
            }
        }

        if (!deviceMatches) {
            continue;
        }
    }

    bool match = false;

    if (!info[i].mHardware.IsEmpty() && !info[i].mHardware.Equals(Hardware())) {
        continue;
    }
    if (!info[i].mModel.IsEmpty() && !info[i].mModel.Equals(Model())) {
        continue;
    }
    if (!info[i].mProduct.IsEmpty() && !info[i].mProduct.Equals(Product())) {
        continue;
    }
    if (!info[i].mManufacturer.IsEmpty() && !info[i].mManufacturer.Equals(Manufacturer())) {
        continue;
    }

#if defined(XP_WIN) || defined(ANDROID)
    switch (info[i].mComparisonOp) {
    case DRIVER_LESS_THAN:
      match = driverVersion < info[i].mDriverVersion;
      break;
    case DRIVER_LESS_THAN_OR_EQUAL:
      match = driverVersion <= info[i].mDriverVersion;
      break;
    case DRIVER_GREATER_THAN:
      match = driverVersion > info[i].mDriverVersion;
      break;
    case DRIVER_GREATER_THAN_OR_EQUAL:
      match = driverVersion >= info[i].mDriverVersion;
      break;
    case DRIVER_EQUAL:
      match = driverVersion == info[i].mDriverVersion;
      break;
    case DRIVER_NOT_EQUAL:
      match = driverVersion != info[i].mDriverVersion;
      break;
    case DRIVER_BETWEEN_EXCLUSIVE:
      match = driverVersion > info[i].mDriverVersion && driverVersion < info[i].mDriverVersionMax;
      break;
    case DRIVER_BETWEEN_INCLUSIVE:
      match = driverVersion >= info[i].mDriverVersion && driverVersion <= info[i].mDriverVersionMax;
      break;
    case DRIVER_BETWEEN_INCLUSIVE_START:
      match = driverVersion >= info[i].mDriverVersion && driverVersion < info[i].mDriverVersionMax;
      break;
    case DRIVER_COMPARISON_IGNORED:
      // We don't have a comparison op, so we match everything.
      match = true;
      break;
    default:
      NS_WARNING("Bogus op in GfxDriverInfo");
      break;
    }
#else
    // We don't care what driver version it was. We only check OS version and if
    // the device matches.
    match = true;
#endif

    if (match || info[i].mDriverVersion == GfxDriverInfo::allDriverVersions) {
      if (info[i].mFeature == GfxDriverInfo::allFeatures ||
          info[i].mFeature == aFeature)
      {
        status = info[i].mFeatureStatus;
        if (!info[i].mRuleId.IsEmpty()) {
          aFailureId = info[i].mRuleId.get();
        } else {
          aFailureId = "FEATURE_FAILURE_DL_BLACKLIST_NO_ID";
        }
        break;
      }
    }
  }

#if defined(XP_WIN)
  // As a very special case, we block D2D on machines with an NVidia 310M GPU
  // as either the primary or secondary adapter.  D2D is also blocked when the
  // NV 310M is the primary adapter (using the standard blocklisting mechanism).
  // If the primary GPU already matched something in the blocklist then we
  // ignore this special rule.  See bug 1008759.
  if (status == nsIGfxInfo::FEATURE_STATUS_UNKNOWN &&
    (aFeature == nsIGfxInfo::FEATURE_DIRECT2D)) {
    nsAutoString adapterVendorID2;
    nsAutoString adapterDeviceID2;
    if ((!NS_FAILED(GetAdapterVendorID2(adapterVendorID2))) &&
      (!NS_FAILED(GetAdapterDeviceID2(adapterDeviceID2))))
    {
      nsAString &nvVendorID = (nsAString &)GfxDriverInfo::GetDeviceVendor(VendorNVIDIA);
      const nsString nv310mDeviceId = NS_LITERAL_STRING("0x0A70");
      if (nvVendorID.Equals(adapterVendorID2, nsCaseInsensitiveStringComparator()) &&
        nv310mDeviceId.Equals(adapterDeviceID2, nsCaseInsensitiveStringComparator())) {
        status = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
        aFailureId = "FEATURE_FAILURE_D2D_NV310M_BLOCK";
      }
    }
  }

  // Depends on Windows driver versioning. We don't pass a GfxDriverInfo object
  // back to the Windows handler, so we must handle this here.
  if (status == FEATURE_BLOCKED_DRIVER_VERSION) {
    if (info[i].mSuggestedVersion) {
        aSuggestedVersion.AppendPrintf("%s", info[i].mSuggestedVersion);
    } else if (info[i].mComparisonOp == DRIVER_LESS_THAN &&
               info[i].mDriverVersion != GfxDriverInfo::allDriverVersions)
    {
        aSuggestedVersion.AppendPrintf("%lld.%lld.%lld.%lld",
                                      (info[i].mDriverVersion & 0xffff000000000000) >> 48,
                                      (info[i].mDriverVersion & 0x0000ffff00000000) >> 32,
                                      (info[i].mDriverVersion & 0x00000000ffff0000) >> 16,
                                      (info[i].mDriverVersion & 0x000000000000ffff));
    }
  }
nsresult
nsDOMWorkerScriptLoader::LoadScripts(JSContext* aCx,
                                     const nsTArray<nsString>& aURLs,
                                     PRBool aForWorker)
{
  NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
  NS_ASSERTION(aCx, "Null context!");

  mTarget = NS_GetCurrentThread();
  NS_ASSERTION(mTarget, "This should never be null!");

  if (mCanceled) {
    return NS_ERROR_ABORT;
  }

  mForWorker = aForWorker;

  mScriptCount = aURLs.Length();
  if (!mScriptCount) {
    return NS_ERROR_INVALID_ARG;
  }

  // Do all the memory work for these arrays now rather than checking for
  // failures all along the way.
  PRBool success = mLoadInfos.SetCapacity(mScriptCount);
  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);

  // Need one runnable per script and then an extra for the finished
  // notification.
  success = mPendingRunnables.SetCapacity(mScriptCount + 1);
  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);

  for (PRUint32 index = 0; index < mScriptCount; index++) {
    ScriptLoadInfo* newInfo = mLoadInfos.AppendElement();
    NS_ASSERTION(newInfo, "Shouldn't fail if SetCapacity succeeded above!");

    newInfo->url.Assign(aURLs[index]);
    if (newInfo->url.IsEmpty()) {
      return NS_ERROR_INVALID_ARG;
    }

    success = newInfo->scriptObj.Hold(aCx);
    NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
  }

  // Don't want timeouts, etc., from queuing up while we're waiting on the
  // network or compiling.
  AutoSuspendWorkerEvents aswe(this);

  nsresult rv = DoRunLoop(aCx);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // Verify that all scripts downloaded and compiled.
  rv = VerifyScripts(aCx);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = ExecuteScripts(aCx);
  if (NS_FAILED(rv)) {
    return rv;
  }

  return NS_OK;
}
Example #21
0
nsresult
nsHyphenator::Hyphenate(const nsAString& aString,
                        nsTArray<bool>& aHyphens)
{
  if (!aHyphens.SetLength(aString.Length())) {
    return NS_ERROR_OUT_OF_MEMORY;
  }
  memset(aHyphens.Elements(), false, aHyphens.Length());

  bool inWord = false;
  uint32_t wordStart = 0, wordLimit = 0;
  uint32_t chLen;
  for (uint32_t i = 0; i < aString.Length(); i += chLen) {
    uint32_t ch = aString[i];
    chLen = 1;

    if (NS_IS_HIGH_SURROGATE(ch)) {
      if (i + 1 < aString.Length() && NS_IS_LOW_SURROGATE(aString[i+1])) {
        ch = SURROGATE_TO_UCS4(ch, aString[i+1]);
        chLen = 2;
      } else {
        NS_WARNING("unpaired surrogate found during hyphenation");
      }
    }

    nsIUGenCategory::nsUGenCategory cat = mozilla::unicode::GetGenCategory(ch);
    if (cat == nsIUGenCategory::kLetter || cat == nsIUGenCategory::kMark) {
      if (!inWord) {
        inWord = true;
        wordStart = i;
      }
      wordLimit = i + chLen;
      if (i + chLen < aString.Length()) {
        continue;
      }
    }

    if (inWord) {
      const PRUnichar *begin = aString.BeginReading();
      NS_ConvertUTF16toUTF8 utf8(begin + wordStart,
                                 wordLimit - wordStart);
      nsAutoTArray<char,200> utf8hyphens;
      utf8hyphens.SetLength(utf8.Length() + 5);
      char **rep = nullptr;
      int *pos = nullptr;
      int *cut = nullptr;
      int err = hnj_hyphen_hyphenate2((HyphenDict*)mDict,
                                      utf8.BeginReading(), utf8.Length(),
                                      utf8hyphens.Elements(), nullptr,
                                      &rep, &pos, &cut);
      if (!err) {
        // Surprisingly, hnj_hyphen_hyphenate2 converts the 'hyphens' buffer
        // from utf8 code unit indexing (which would match the utf8 input
        // string directly) to Unicode character indexing.
        // We then need to convert this to utf16 code unit offsets for Gecko.
        const char *hyphPtr = utf8hyphens.Elements();
        const PRUnichar *cur = begin + wordStart;
        const PRUnichar *end = begin + wordLimit;
        while (cur < end) {
          if (*hyphPtr & 0x01) {
            aHyphens[cur - begin] = true;
          }
          cur++;
          if (cur < end && NS_IS_LOW_SURROGATE(*cur) &&
              NS_IS_HIGH_SURROGATE(*(cur-1)))
          {
            cur++;
          }
          hyphPtr++;
        }
      }
    }
    
    inWord = false;
  }

  return NS_OK;
}
Example #22
0
static void ValidateTreePointers(nsTArray<RefPtr<Layer> >& aLayers) {
  for (uint32_t i = 0; i < aLayers.Length(); i++) {
    ValidateTreePointers(aLayers[i]);
  }
}
Example #23
0
// NOTE: This method represents a theoretical way to use a U2F-compliant token
// to produce the result of the WebAuthn MakeCredential method. The exact
// mapping of U2F data fields to WebAuthn data fields is still a matter of
// ongoing discussion, and this should not be taken as anything but a point-in-
// time possibility.
void
WebAuthentication::U2FAuthMakeCredential(
             const RefPtr<CredentialRequest>& aRequest,
             const Authenticator& aToken, CryptoBuffer& aRpIdHash,
             const nsACString& aClientData, CryptoBuffer& aClientDataHash,
             const Account& aAccount,
             const nsTArray<ScopedCredentialParameters>& aNormalizedParams,
             const Optional<Sequence<ScopedCredentialDescriptor>>& aExcludeList,
             const WebAuthnExtensions& aExtensions)
{
  MOZ_LOG(gWebauthLog, LogLevel::Debug, ("U2FAuthMakeCredential"));
  aRequest->AddActiveToken(__func__);

  // 5.1.1 When this operation is invoked, the authenticator must perform the
  // following procedure:

  // 5.1.1.a Check if all the supplied parameters are syntactically well-
  // formed and of the correct length. If not, return an error code equivalent
  // to UnknownError and terminate the operation.

  if ((aRpIdHash.Length() != SHA256_LENGTH) ||
      (aClientDataHash.Length() != SHA256_LENGTH)) {
    aRequest->SetFailure(NS_ERROR_DOM_UNKNOWN_ERR);
    return;
  }

  // 5.1.1.b Check if at least one of the specified combinations of
  // ScopedCredentialType and cryptographic parameters is supported. If not,
  // return an error code equivalent to NotSupportedError and terminate the
  // operation.

  bool isValidCombination = false;

  for (size_t a = 0; a < aNormalizedParams.Length(); ++a) {
    if (aNormalizedParams[a].mType == ScopedCredentialType::ScopedCred &&
        aNormalizedParams[a].mAlgorithm.IsString() &&
        aNormalizedParams[a].mAlgorithm.GetAsString().EqualsLiteral(
          WEBCRYPTO_NAMED_CURVE_P256)) {
      isValidCombination = true;
      break;
    }
  }
  if (!isValidCombination) {
    aRequest->SetFailure(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
    return;
  }

  // 5.1.1.c Check if a credential matching any of the supplied
  // ScopedCredential identifiers is present on this authenticator. If so,
  // return an error code equivalent to NotAllowedError and terminate the
  // operation.

  if (aExcludeList.WasPassed()) {
    const Sequence<ScopedCredentialDescriptor>& list = aExcludeList.Value();

    for (const ScopedCredentialDescriptor& scd : list) {
      bool isRegistered = false;

      uint8_t *data;
      uint32_t len;

      // data is owned by the Descriptor, do don't free it here.
      if (NS_FAILED(ScopedCredentialGetData(scd, &data, &len))) {
        aRequest->SetFailure(NS_ERROR_DOM_UNKNOWN_ERR);
        return;
      }

      nsresult rv = aToken->IsRegistered(data, len, &isRegistered);
      if (NS_WARN_IF(NS_FAILED(rv))) {
        aRequest->SetFailure(rv);
        return;
      }

      if (isRegistered) {
        aRequest->SetFailure(NS_ERROR_DOM_NOT_ALLOWED_ERR);
        return;
      }
    }
  }

  // 5.1.1.d Prompt the user for consent to create a new credential. The
  // prompt for obtaining this consent is shown by the authenticator if it has
  // its own output capability, or by the user agent otherwise. If the user
  // denies consent, return an error code equivalent to NotAllowedError and
  // terminate the operation.

  // 5.1.1.d Once user consent has been obtained, generate a new credential
  // object

  // 5.1.1.e If any error occurred while creating the new credential object,
  // return an error code equivalent to UnknownError and terminate the
  // operation.

  // 5.1.1.f Process all the supported extensions requested by the client, and
  // generate an attestation statement. If no authority key is available to
  // sign such an attestation statement, then the authenticator performs self
  // attestation of the credential with its own private key. For more details
  // on attestation, see §5.3 Credential Attestation Statements.

  // No extensions are supported

  // 4.1.1.11 While issuedRequests is not empty, perform the following actions
  // depending upon the adjustedTimeout timer and responses from the
  // authenticators:

  // 4.1.1.11.a If the adjustedTimeout timer expires, then for each entry in
  // issuedRequests invoke the authenticatorCancel operation on that
  // authenticator and remove its entry from the list.

  uint8_t* buffer;
  uint32_t bufferlen;

  nsresult rv = aToken->Register(aRpIdHash.Elements(), aRpIdHash.Length(),
                                 aClientDataHash.Elements(),
                                 aClientDataHash.Length(), &buffer, &bufferlen);

  // 4.1.1.11.b If any authenticator returns a status indicating that the user
  // cancelled the operation, delete that authenticator’s entry from
  // issuedRequests. For each remaining entry in issuedRequests invoke the
  // authenticatorCancel operation on that authenticator and remove its entry
  // from the list.

  // 4.1.1.11.c If any authenticator returns an error status, delete the
  // corresponding entry from issuedRequests.
  if (NS_WARN_IF(NS_FAILED(rv))) {
    aRequest->SetFailure(NS_ERROR_DOM_UNKNOWN_ERR);
    return;
  }

  MOZ_ASSERT(buffer);
  CryptoBuffer regData;
  if (NS_WARN_IF(!regData.Assign(buffer, bufferlen))) {
    free(buffer);
    aRequest->SetFailure(NS_ERROR_OUT_OF_MEMORY);
    return;
  }
  free(buffer);

  // Decompose the U2F registration packet
  CryptoBuffer pubKeyBuf;
  CryptoBuffer keyHandleBuf;
  CryptoBuffer attestationCertBuf;
  CryptoBuffer signatureBuf;

  rv = U2FDecomposeRegistrationResponse(regData, pubKeyBuf, keyHandleBuf,
                                        attestationCertBuf, signatureBuf);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    aRequest->SetFailure(rv);
    return;
  }

  // Sign the aClientDataHash explicitly to get the format needed for
  // the AuthenticatorData parameter of WebAuthnAttestation. This might
  // be temporary while the spec settles down how to incorporate U2F.
  rv = aToken->Sign(aRpIdHash.Elements(), aRpIdHash.Length(),
                    aClientDataHash.Elements(), aClientDataHash.Length(),
                    keyHandleBuf.Elements(), keyHandleBuf.Length(), &buffer,
                    &bufferlen);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    aRequest->SetFailure(rv);
    return;
  }

  MOZ_ASSERT(buffer);
  CryptoBuffer signatureData;
  if (NS_WARN_IF(!signatureData.Assign(buffer, bufferlen))) {
    free(buffer);
    aRequest->SetFailure(NS_ERROR_OUT_OF_MEMORY);
    return;
  }
  free(buffer);

  CryptoBuffer clientDataBuf;
  if (!clientDataBuf.Assign(aClientData)) {
    aRequest->SetFailure(NS_ERROR_OUT_OF_MEMORY);
    return;
  }

  CryptoBuffer authenticatorDataBuf;
  rv = U2FAssembleAuthenticatorData(authenticatorDataBuf, aRpIdHash,
                                    signatureData);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    aRequest->SetFailure(rv);
    return;
  }

  // 4.1.1.11.d If any authenticator indicates success:

  // 4.1.1.11.d.1 Remove this authenticator’s entry from issuedRequests.

  // 4.1.1.11.d.2 Create a new ScopedCredentialInfo object named value and
  // populate its fields with the values returned from the authenticator as well
  // as the clientDataJSON computed earlier.

  RefPtr<ScopedCredential> credential = new ScopedCredential(this);
  credential->SetType(ScopedCredentialType::ScopedCred);
  credential->SetId(keyHandleBuf);

  RefPtr<WebAuthnAttestation> attestation = new WebAuthnAttestation(this);
  attestation->SetFormat(NS_LITERAL_STRING("u2f"));
  attestation->SetClientData(clientDataBuf);
  attestation->SetAuthenticatorData(authenticatorDataBuf);
  attestation->SetAttestation(regData);

  CredentialPtr info = new ScopedCredentialInfo(this);
  info->SetCredential(credential);
  info->SetAttestation(attestation);

  // 4.1.1.11.d.3 For each remaining entry in issuedRequests invoke the
  // authenticatorCancel operation on that authenticator and remove its entry
  // from the list.

  // 4.1.1.11.d.4 Resolve promise with value and terminate this algorithm.
  aRequest->SetSuccess(info);
}
nsresult
nsCORSPreflightListener::CheckPreflightRequestApproved(nsIRequest* aRequest)
{
  nsresult status;
  nsresult rv = aRequest->GetStatus(&status);
  NS_ENSURE_SUCCESS(rv, rv);
  NS_ENSURE_SUCCESS(status, status);

  // Test that things worked on a HTTP level
  nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aRequest);
  nsCOMPtr<nsIHttpChannelInternal> internal = do_QueryInterface(aRequest);
  NS_ENSURE_STATE(internal);

  bool succeedded;
  rv = http->GetRequestSucceeded(&succeedded);
  if (NS_FAILED(rv) || !succeedded) {
    LogBlockedRequest(aRequest, "CORSPreflightDidNotSucceed", nullptr);
    return NS_ERROR_DOM_BAD_URI;
  }

  nsAutoCString headerVal;
  // The "Access-Control-Allow-Methods" header contains a comma separated
  // list of method names.
  http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Methods"),
                          headerVal);
  bool foundMethod = mPreflightMethod.EqualsLiteral("GET") ||
                       mPreflightMethod.EqualsLiteral("HEAD") ||
                       mPreflightMethod.EqualsLiteral("POST");
  nsCCharSeparatedTokenizer methodTokens(headerVal, ',');
  while(methodTokens.hasMoreTokens()) {
    const nsDependentCSubstring& method = methodTokens.nextToken();
    if (method.IsEmpty()) {
      continue;
    }
    if (!NS_IsValidHTTPToken(method)) {
      LogBlockedRequest(aRequest, "CORSInvalidAllowMethod",
                        NS_ConvertUTF8toUTF16(method).get());
      return NS_ERROR_DOM_BAD_URI;
    }
    foundMethod |= mPreflightMethod.Equals(method);
  }
  if (!foundMethod) {
    LogBlockedRequest(aRequest, "CORSMethodNotFound", nullptr);
    return NS_ERROR_DOM_BAD_URI;
  }

  // The "Access-Control-Allow-Headers" header contains a comma separated
  // list of header names.
  http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Headers"),
                          headerVal);
  nsTArray<nsCString> headers;
  nsCCharSeparatedTokenizer headerTokens(headerVal, ',');
  while(headerTokens.hasMoreTokens()) {
    const nsDependentCSubstring& header = headerTokens.nextToken();
    if (header.IsEmpty()) {
      continue;
    }
    if (!NS_IsValidHTTPToken(header)) {
      LogBlockedRequest(aRequest, "CORSInvalidAllowHeader",
                        NS_ConvertUTF8toUTF16(header).get());
      return NS_ERROR_DOM_BAD_URI;
    }
    headers.AppendElement(header);
  }
  for (uint32_t i = 0; i < mPreflightHeaders.Length(); ++i) {
    if (!headers.Contains(mPreflightHeaders[i],
                          nsCaseInsensitiveCStringArrayComparator())) {
      LogBlockedRequest(aRequest, "CORSMissingAllowHeaderFromPreflight",
                        NS_ConvertUTF8toUTF16(mPreflightHeaders[i]).get());
      return NS_ERROR_DOM_BAD_URI;
    }
  }

  return NS_OK;
}
Example #25
0
nsresult
GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
                              int32_t *aStatus, 
                              nsAString & aSuggestedDriverVersion, 
                              const nsTArray<GfxDriverInfo>& aDriverInfo,
                              OperatingSystem* aOS /* = nullptr */)
{
  NS_ENSURE_ARG_POINTER(aStatus);
  aSuggestedDriverVersion.SetIsVoid(true);
  OperatingSystem os = WindowsVersionToOperatingSystem(mWindowsVersion);
  *aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
  if (aOS)
    *aOS = os;

  // Don't evaluate special cases if we're checking the downloaded blocklist.
  if (!aDriverInfo.Length()) {
    nsAutoString adapterVendorID;
    nsAutoString adapterDeviceID;
    nsAutoString adapterDriverVersionString;
    if (NS_FAILED(GetAdapterVendorID(adapterVendorID)) ||
        NS_FAILED(GetAdapterDeviceID(adapterDeviceID)) ||
        NS_FAILED(GetAdapterDriverVersion(adapterDriverVersionString)))
    {
      return NS_ERROR_FAILURE;
    }

    if (!adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorIntel), nsCaseInsensitiveStringComparator()) &&
        !adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), nsCaseInsensitiveStringComparator()) &&
        !adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorAMD), nsCaseInsensitiveStringComparator()) &&
        !adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorATI), nsCaseInsensitiveStringComparator()) &&
        !adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorMicrosoft), nsCaseInsensitiveStringComparator()) &&
        // FIXME - these special hex values are currently used in xpcshell tests introduced by
        // bug 625160 patch 8/8. Maybe these tests need to be adjusted now that we're only whitelisting
        // intel/ati/nvidia.
        !adapterVendorID.LowerCaseEqualsLiteral("0xabcd") &&
        !adapterVendorID.LowerCaseEqualsLiteral("0xdcba") &&
        !adapterVendorID.LowerCaseEqualsLiteral("0xabab") &&
        !adapterVendorID.LowerCaseEqualsLiteral("0xdcdc"))
    {
      *aStatus = FEATURE_BLOCKED_DEVICE;
      return NS_OK;
    }

    uint64_t driverVersion;
    if (!ParseDriverVersion(adapterDriverVersionString, &driverVersion)) {
      return NS_ERROR_FAILURE;
    }

    // special-case the WinXP test slaves: they have out-of-date drivers, but we still want to
    // whitelist them, actually we do know that this combination of device and driver version
    // works well.
    if (mWindowsVersion == kWindowsXP &&
        adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), nsCaseInsensitiveStringComparator()) &&
        adapterDeviceID.LowerCaseEqualsLiteral("0x0861") && // GeForce 9400
        driverVersion == V(6,14,11,7756))
    {
      *aStatus = FEATURE_STATUS_OK;
      return NS_OK;
    }

    // Windows Server 2003 should be just like Windows XP for present purpose, but still has a different version number.
    // OTOH Windows Server 2008 R1 and R2 already have the same version numbers as Vista and Seven respectively
    if (os == DRIVER_OS_WINDOWS_SERVER_2003)
      os = DRIVER_OS_WINDOWS_XP;

    if (mHasDriverVersionMismatch) {
      if (aFeature == nsIGfxInfo::FEATURE_DIRECT3D_10_LAYERS ||
          aFeature == nsIGfxInfo::FEATURE_DIRECT3D_10_1_LAYERS ||
          aFeature == nsIGfxInfo::FEATURE_DIRECT2D ||
          aFeature == nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS)
      {
        *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION;
        return NS_OK;
      }
    }
  }

  return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os);
}
nsresult
nsCORSListenerProxy::StartCORSPreflight(nsIChannel* aRequestChannel,
                                        nsICorsPreflightCallback* aCallback,
                                        nsTArray<nsCString>& aUnsafeHeaders,
                                        nsIChannel** aPreflightChannel)
{
  *aPreflightChannel = nullptr;

  if (gDisableCORS) {
    LogBlockedRequest(aRequestChannel, "CORSDisabled", nullptr);
    return NS_ERROR_DOM_BAD_URI;
  }

  nsAutoCString method;
  nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequestChannel));
  NS_ENSURE_TRUE(httpChannel, NS_ERROR_UNEXPECTED);
  httpChannel->GetRequestMethod(method);

  nsCOMPtr<nsIURI> uri;
  nsresult rv = NS_GetFinalChannelURI(aRequestChannel, getter_AddRefs(uri));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsILoadInfo> originalLoadInfo = aRequestChannel->GetLoadInfo();
  MOZ_ASSERT(originalLoadInfo, "can not perform CORS preflight without a loadInfo");
  if (!originalLoadInfo) {
    return NS_ERROR_FAILURE;
  }

  MOZ_ASSERT(originalLoadInfo->GetSecurityMode() ==
             nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS,
             "how did we end up here?");

  nsCOMPtr<nsIPrincipal> principal = originalLoadInfo->LoadingPrincipal();
  bool withCredentials = originalLoadInfo->GetCookiePolicy() ==
    nsILoadInfo::SEC_COOKIES_INCLUDE;

  nsPreflightCache::CacheEntry* entry =
    sPreflightCache ?
    sPreflightCache->GetEntry(uri, principal, withCredentials, false) :
    nullptr;

  if (entry && entry->CheckRequest(method, aUnsafeHeaders)) {
    aCallback->OnPreflightSucceeded();
    return NS_OK;
  }

  // Either it wasn't cached or the cached result has expired. Build a
  // channel for the OPTIONS request.

  nsCOMPtr<nsILoadInfo> loadInfo = static_cast<mozilla::LoadInfo*>
    (originalLoadInfo.get())->CloneForNewRequest();
  static_cast<mozilla::LoadInfo*>(loadInfo.get())->SetIsPreflight();

  nsCOMPtr<nsILoadGroup> loadGroup;
  rv = aRequestChannel->GetLoadGroup(getter_AddRefs(loadGroup));
  NS_ENSURE_SUCCESS(rv, rv);

  nsLoadFlags loadFlags;
  rv = aRequestChannel->GetLoadFlags(&loadFlags);
  NS_ENSURE_SUCCESS(rv, rv);

  // Preflight requests should never be intercepted by service workers and
  // are always anonymous.
  // NOTE: We ignore CORS checks on synthesized responses (see the CORS
  // preflights, then we need to extend the GetResponseSynthesized() check in
  // nsCORSListenerProxy::CheckRequestApproved()). If we change our behavior
  // here and allow service workers to intercept CORS preflights, then that
  // check won't be safe any more.
  loadFlags |= nsIChannel::LOAD_BYPASS_SERVICE_WORKER |
               nsIRequest::LOAD_ANONYMOUS;

  nsCOMPtr<nsIChannel> preflightChannel;
  rv = NS_NewChannelInternal(getter_AddRefs(preflightChannel),
                             uri,
                             loadInfo,
                             loadGroup,
                             nullptr,   // aCallbacks
                             loadFlags);
  NS_ENSURE_SUCCESS(rv, rv);

  // Set method and headers
  nsCOMPtr<nsIHttpChannel> preHttp = do_QueryInterface(preflightChannel);
  NS_ASSERTION(preHttp, "Failed to QI to nsIHttpChannel!");

  rv = preHttp->SetRequestMethod(NS_LITERAL_CSTRING("OPTIONS"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = preHttp->
    SetRequestHeader(NS_LITERAL_CSTRING("Access-Control-Request-Method"),
                     method, false);
  NS_ENSURE_SUCCESS(rv, rv);

  nsTArray<nsCString> preflightHeaders;
  if (!aUnsafeHeaders.IsEmpty()) {
    for (uint32_t i = 0; i < aUnsafeHeaders.Length(); ++i) {
      preflightHeaders.AppendElement();
      ToLowerCase(aUnsafeHeaders[i], preflightHeaders[i]);
    }
    preflightHeaders.Sort();
    nsAutoCString headers;
    for (uint32_t i = 0; i < preflightHeaders.Length(); ++i) {
      if (i != 0) {
        headers += ',';
      }
      headers += preflightHeaders[i];
    }
    rv = preHttp->
      SetRequestHeader(NS_LITERAL_CSTRING("Access-Control-Request-Headers"),
                       headers, false);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // Set up listener which will start the original channel
  RefPtr<nsCORSPreflightListener> preflightListener =
    new nsCORSPreflightListener(principal, aCallback, withCredentials,
                                method, preflightHeaders);

  rv = preflightChannel->SetNotificationCallbacks(preflightListener);
  NS_ENSURE_SUCCESS(rv, rv);

  // Start preflight
  rv = preflightChannel->AsyncOpen2(preflightListener);
  NS_ENSURE_SUCCESS(rv, rv);
  
  // Return newly created preflight channel
  preflightChannel.forget(aPreflightChannel);

  return NS_OK;
}
Example #27
0
void
nsCSSExpandedDataBlock::Compress(nsCSSCompressedDataBlock **aNormalBlock,
                                 nsCSSCompressedDataBlock **aImportantBlock,
                                 const nsTArray<uint32_t>& aOrder)
{
    nsAutoPtr<nsCSSCompressedDataBlock> result_normal, result_important;
    uint32_t i_normal = 0, i_important = 0;

    uint32_t numPropsNormal, numPropsImportant;
    ComputeNumProps(&numPropsNormal, &numPropsImportant);

    result_normal =
        new(numPropsNormal) nsCSSCompressedDataBlock(numPropsNormal);

    if (numPropsImportant != 0) {
        result_important =
            new(numPropsImportant) nsCSSCompressedDataBlock(numPropsImportant);
    } else {
        result_important = nullptr;
    }

    /*
     * Save needless copying and allocation by copying the memory
     * corresponding to the stored data in the expanded block, and then
     * clearing the data in the expanded block.
     */
    for (size_t i = 0; i < aOrder.Length(); i++) {
        nsCSSProperty iProp = static_cast<nsCSSProperty>(aOrder[i]);
        if (iProp >= eCSSProperty_COUNT) {
            // a custom property
            continue;
        }
        MOZ_ASSERT(mPropertiesSet.HasProperty(iProp),
                   "aOrder identifies a property not in the expanded "
                   "data block");
        MOZ_ASSERT(!nsCSSProps::IsShorthand(iProp), "out of range");
        bool important = mPropertiesImportant.HasProperty(iProp);
        nsCSSCompressedDataBlock *result =
            important ? result_important : result_normal;
        uint32_t* ip = important ? &i_important : &i_normal;
        nsCSSValue* val = PropertyAt(iProp);
        MOZ_ASSERT(val->GetUnit() != eCSSUnit_Null,
                   "Null value while compressing");
        result->SetPropertyAtIndex(*ip, iProp);
        result->RawCopyValueToIndex(*ip, val);
        new (val) nsCSSValue();
        (*ip)++;
        result->mStyleBits |=
            nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]);
    }

    MOZ_ASSERT(numPropsNormal == i_normal, "bad numProps");

    if (result_important) {
        MOZ_ASSERT(numPropsImportant == i_important, "bad numProps");
    }

#ifdef DEBUG
    {
      // assert that we didn't have any other properties on this expanded data
      // block that we didn't find in aOrder
      uint32_t numPropsInSet = 0;
      for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; iHigh++) {
          if (!mPropertiesSet.HasPropertyInChunk(iHigh)) {
              continue;
          }
          for (size_t iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; iLow++) {
              if (mPropertiesSet.HasPropertyAt(iHigh, iLow)) {
                  numPropsInSet++;
              }
          }
      }
      MOZ_ASSERT(numPropsNormal + numPropsImportant == numPropsInSet,
                 "aOrder missing properties from the expanded data block");
    }
#endif

    ClearSets();
    AssertInitialState();
    *aNormalBlock = result_normal.forget();
    *aImportantBlock = result_important.forget();
}
// A U2F Register operation causes a new key pair to be generated by the token.
// The token then returns the public key of the key pair, and a handle to the
// private key, which is a fancy way of saying "key wrapped private key", as
// well as the generated attestation certificate and a signature using that
// certificate's private key.
//
// The KeyHandleFromPrivateKey and PrivateKeyFromKeyHandle methods perform
// the actual key wrap/unwrap operations.
//
// The format of the return registration data is as follows:
//
// Bytes  Value
// 1      0x05
// 65     public key
// 1      key handle length
// *      key handle
// ASN.1  attestation certificate
// *      attestation signature
//
nsresult
U2FSoftTokenManager::Register(nsTArray<uint8_t>& aApplication,
                              nsTArray<uint8_t>& aChallenge,
                              /* out */ nsTArray<uint8_t>& aRegistration,
                              /* out */ nsTArray<uint8_t>& aSignature)
{
  nsNSSShutDownPreventionLock locker;
  if (NS_WARN_IF(isAlreadyShutDown())) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  if (!mInitialized) {
    nsresult rv = Init();
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
  }

  // We should already have a wrapping key
  MOZ_ASSERT(mWrappingKey);

  UniquePK11SlotInfo slot(PK11_GetInternalSlot());
  MOZ_ASSERT(slot.get());

  // Construct a one-time-use Attestation Certificate
  UniqueSECKEYPrivateKey attestPrivKey;
  UniqueCERTCertificate attestCert;
  nsresult rv = GetAttestationCertificate(slot, attestPrivKey, attestCert,
                                          locker);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return NS_ERROR_FAILURE;
  }
  MOZ_ASSERT(attestCert);
  MOZ_ASSERT(attestPrivKey);

  // Generate a new keypair; the private will be wrapped into a Key Handle
  UniqueSECKEYPrivateKey privKey;
  UniqueSECKEYPublicKey pubKey;
  rv = GenEcKeypair(slot, privKey, pubKey, locker);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return NS_ERROR_FAILURE;
  }

  // The key handle will be the result of keywrap(privKey, key=mWrappingKey)
  UniqueSECItem keyHandleItem = KeyHandleFromPrivateKey(slot, mWrappingKey,
                                                        aApplication.Elements(),
                                                        aApplication.Length(),
                                                        privKey, locker);
  if (NS_WARN_IF(!keyHandleItem.get())) {
    return NS_ERROR_FAILURE;
  }

  // Sign the challenge using the Attestation privkey (from attestCert)
  mozilla::dom::CryptoBuffer signedDataBuf;
  if (NS_WARN_IF(!signedDataBuf.SetCapacity(1 + aApplication.Length() + aChallenge.Length() +
                                            keyHandleItem->len + kPublicKeyLen,
                                            mozilla::fallible))) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  // // It's OK to ignore the return values here because we're writing into
  // // pre-allocated space
  signedDataBuf.AppendElement(0x00, mozilla::fallible);
  signedDataBuf.AppendElements(aApplication, mozilla::fallible);
  signedDataBuf.AppendElements(aChallenge, mozilla::fallible);
  signedDataBuf.AppendSECItem(keyHandleItem.get());
  signedDataBuf.AppendSECItem(pubKey->u.ec.publicValue);

  ScopedAutoSECItem signatureItem;
  SECStatus srv = SEC_SignData(&signatureItem, signedDataBuf.Elements(),
                               signedDataBuf.Length(), attestPrivKey.get(),
                               SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE);
  if (NS_WARN_IF(srv != SECSuccess)) {
    MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
            ("Signature failure: %d", PORT_GetError()));
    return NS_ERROR_FAILURE;
  }

  // Serialize the registration data
  mozilla::dom::CryptoBuffer registrationBuf;
  if (NS_WARN_IF(!registrationBuf.SetCapacity(1 + kPublicKeyLen + 1 + keyHandleItem->len +
                                              attestCert.get()->derCert.len +
                                              signatureItem.len, mozilla::fallible))) {
    return NS_ERROR_OUT_OF_MEMORY;
  }
  registrationBuf.AppendElement(0x05, mozilla::fallible);
  registrationBuf.AppendSECItem(pubKey->u.ec.publicValue);
  registrationBuf.AppendElement(keyHandleItem->len, mozilla::fallible);
  registrationBuf.AppendSECItem(keyHandleItem.get());
  registrationBuf.AppendSECItem(attestCert.get()->derCert);
  registrationBuf.AppendSECItem(signatureItem);
  aRegistration = registrationBuf;

  return NS_OK;
}
Example #29
0
/**
 * This Init method should only be called by C++ consumers.
 */
NS_IMETHODIMP
nsWebSocket::Init(nsIPrincipal* aPrincipal,
                  nsIScriptContext* aScriptContext,
                  nsPIDOMWindow* aOwnerWindow,
                  const nsAString& aURL,
                  nsTArray<nsString> & protocolArray)
{
  NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
  nsresult rv;

  NS_ENSURE_ARG(aPrincipal);

  if (!PrefEnabled()) {
    return NS_ERROR_DOM_SECURITY_ERR;
  }

  mPrincipal = aPrincipal;
  mScriptContext = aScriptContext;
  if (aOwnerWindow) {
    mOwner = aOwnerWindow->IsOuterWindow() ?
      aOwnerWindow->GetCurrentInnerWindow() : aOwnerWindow;
  } else {
    mOwner = nsnull;
  }

  nsCOMPtr<nsIJSContextStack> stack =
    do_GetService("@mozilla.org/js/xpc/ContextStack;1");
  JSContext* cx = nsnull;
  if (stack && NS_SUCCEEDED(stack->Peek(&cx)) && cx) {
    JSStackFrame *fp = JS_GetScriptedCaller(cx, NULL);
    if (fp) {
      JSScript *script = JS_GetFrameScript(cx, fp);
      if (script) {
        mScriptFile = JS_GetScriptFilename(cx, script);
      }

      jsbytecode *pc = JS_GetFramePC(cx, fp);
      if (script && pc) {
        mScriptLine = JS_PCToLineNumber(cx, script, pc);
      }
    }

    mInnerWindowID = nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx);
  }

  // parses the url
  rv = ParseURL(PromiseFlatString(aURL));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIDocument> originDoc =
    nsContentUtils::GetDocumentFromScriptContext(mScriptContext);

  // Don't allow https:// to open ws://
  if (!mSecure &&
      !Preferences::GetBool("network.websocket.allowInsecureFromHTTPS",
                            false)) {
    // Confirmed we are opening plain ws:// and want to prevent this from a
    // secure context (e.g. https). Check the security context of the document
    // associated with this script, which is the same as associated with mOwner.
    if (originDoc && originDoc->GetSecurityInfo())
      return NS_ERROR_DOM_SECURITY_ERR;
  }

  // Assign the sub protocol list and scan it for illegal values
  for (PRUint32 index = 0; index < protocolArray.Length(); ++index) {
    for (PRUint32 i = 0; i < protocolArray[index].Length(); ++i) {
      if (protocolArray[index][i] < static_cast<PRUnichar>(0x0021) ||
          protocolArray[index][i] > static_cast<PRUnichar>(0x007E))
        return NS_ERROR_DOM_SYNTAX_ERR;
    }

    if (!mRequestedProtocolList.IsEmpty())
      mRequestedProtocolList.Append(NS_LITERAL_CSTRING(", "));
    AppendUTF16toUTF8(protocolArray[index], mRequestedProtocolList);
  }

  // Check content policy.
  PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
  rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_WEBSOCKET,
                                 mURI,
                                 mPrincipal,
                                 originDoc,
                                 EmptyCString(),
                                 nsnull,
                                 &shouldLoad,
                                 nsContentUtils::GetContentPolicy(),
                                 nsContentUtils::GetSecurityManager());
  NS_ENSURE_SUCCESS(rv, rv);
  if (NS_CP_REJECTED(shouldLoad)) {
    // Disallowed by content policy.
    return NS_ERROR_CONTENT_BLOCKED;
  }

  // the constructor should throw a SYNTAX_ERROR only if it fails to parse the
  // url parameter, so we don't care about the EstablishConnection result.
  EstablishConnection();

  return NS_OK;
}
void nsMsgLocalStoreUtils::ChangeKeywordsHelper(
    nsIMsgDBHdr *message, uint64_t desiredOffset,
    nsLineBuffer<char> *lineBuffer, nsTArray<nsCString> &keywordArray,
    bool aAdd, nsIOutputStream *outputStream, nsISeekableStream *seekableStream,
    nsIInputStream *inputStream) {
  uint32_t bytesWritten;

  for (uint32_t i = 0; i < keywordArray.Length(); i++) {
    nsAutoCString header;
    nsAutoCString keywords;
    bool done = false;
    uint32_t len = 0;
    nsAutoCString keywordToWrite(" ");

    keywordToWrite.Append(keywordArray[i]);
    seekableStream->Seek(nsISeekableStream::NS_SEEK_SET, desiredOffset);
    // need to reset lineBuffer, which is cheaper than creating a new one.
    lineBuffer->start = lineBuffer->end = lineBuffer->buf;
    bool inKeywordHeader = false;
    bool foundKeyword = false;
    int64_t offsetToAddKeyword = 0;
    bool more;
    message->GetMessageSize(&len);
    // loop through
    while (!done) {
      int64_t lineStartPos;
      seekableStream->Tell(&lineStartPos);
      // we need to adjust the linestart pos by how much extra the line
      // buffer has read from the stream.
      lineStartPos -= (lineBuffer->end - lineBuffer->start);
      // NS_ReadLine doesn't return line termination chars.
      nsCString keywordHeaders;
      nsresult rv = NS_ReadLine(inputStream, lineBuffer, keywordHeaders, &more);
      if (NS_SUCCEEDED(rv)) {
        if (keywordHeaders.IsEmpty())
          break;  // passed headers; no x-mozilla-keywords header; give up.
        if (StringBeginsWith(keywordHeaders,
                             NS_LITERAL_CSTRING(HEADER_X_MOZILLA_KEYWORDS)))
          inKeywordHeader = true;
        else if (inKeywordHeader && (keywordHeaders.CharAt(0) == ' ' ||
                                     keywordHeaders.CharAt(0) == '\t'))
          ;  // continuation header line
        else if (inKeywordHeader)
          break;
        else
          continue;
        uint32_t keywordHdrLength = keywordHeaders.Length();
        int32_t startOffset, keywordLength;
        // check if we have the keyword
        if (MsgFindKeyword(keywordArray[i], keywordHeaders, &startOffset,
                           &keywordLength)) {
          foundKeyword = true;
          if (!aAdd)  // if we're removing, remove it, and break;
          {
            keywordHeaders.Cut(startOffset, keywordLength);
            for (int32_t j = keywordLength; j > 0; j--)
              keywordHeaders.Append(' ');
            seekableStream->Seek(nsISeekableStream::NS_SEEK_SET, lineStartPos);
            outputStream->Write(keywordHeaders.get(), keywordHeaders.Length(),
                                &bytesWritten);
          }
          offsetToAddKeyword = 0;
          // if adding and we already have the keyword, done
          done = true;
          break;
        }
        // argh, we need to check all the lines to see if we already have the
        // keyword, but if we don't find it, we want to remember the line and
        // position where we have room to add the keyword.
        if (aAdd) {
          nsAutoCString curKeywordHdr(keywordHeaders);
          // strip off line ending spaces.
          curKeywordHdr.Trim(" ", false, true);
          if (!offsetToAddKeyword &&
              curKeywordHdr.Length() + keywordToWrite.Length() <
                  keywordHdrLength)
            offsetToAddKeyword = lineStartPos + curKeywordHdr.Length();
        }
      }
    }
    if (aAdd && !foundKeyword) {
      if (!offsetToAddKeyword)
        message->SetUint32Property("growKeywords", 1);
      else {
        seekableStream->Seek(nsISeekableStream::NS_SEEK_SET,
                             offsetToAddKeyword);
        outputStream->Write(keywordToWrite.get(), keywordToWrite.Length(),
                            &bytesWritten);
      }
    }
  }
}