Example #1
0
bool
nsDOMTokenList::Toggle(const nsAString& aToken,
                       const Optional<bool>& aForce,
                       ErrorResult& aError)
{
  aError = CheckToken(aToken);
  if (aError.Failed()) {
    return false;
  }

  const nsAttrValue* attr = GetParsedAttr();
  const bool forceOn = aForce.WasPassed() && aForce.Value();
  const bool forceOff = aForce.WasPassed() && !aForce.Value();

  bool isPresent = attr && attr->Contains(aToken);
  nsAutoTArray<nsString, 1> tokens;
  (*tokens.AppendElement()).Rebind(aToken.Data(), aToken.Length());

  if (isPresent) {
    if (!forceOn) {
      RemoveInternal(attr, tokens);
      isPresent = false;
    }
  } else {
    if (!forceOff) {
      AddInternal(attr, tokens);
      isPresent = true;
    }
  }

  return isPresent;
}
Example #2
0
bool
SVGContentUtils::ParseInteger(const nsAString& aString,
                              int32_t& aValue)
{
  mozilla::RangedPtr<const PRUnichar> iter(aString.Data(), aString.Length());
  const mozilla::RangedPtr<const PRUnichar> end(aString.Data() + aString.Length(),
                                                aString.Data(), aString.Length());

  if (iter == end) {
    return false;
  }

  int32_t sign = *iter == '-' ? -1 : 1;

  if (*iter == '-' || *iter == '+') {
    ++iter;
    if (iter == end) {
      return false;
    }
  }

  int64_t value = 0;

  do {
    if (!IsDigit(*iter)) {
      return false;
    }
    if (value <= std::numeric_limits<int32_t>::max()) {
      value = 10 * value + DecimalDigitValue(*iter);
    }
    ++iter;
  } while (iter != end);

  aValue = int32_t(clamped(sign * value,
                           int64_t(std::numeric_limits<int32_t>::min()),
                           int64_t(std::numeric_limits<int32_t>::max())));
  return true;
}
void
DecoderDoctorDocumentWatcher::ReportAnalysis(
  const NotificationAndReportStringId& aNotification,
  bool aIsSolved,
  const nsAString& aParams)
{
  MOZ_ASSERT(NS_IsMainThread());

  if (!mDocument) {
    return;
  }

  // Report non-solved issues to console.
  if (!aIsSolved) {
    // 'params' will only be forwarded for non-empty strings.
    const char16_t* params[1] = { aParams.Data() };
    DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::ReportAnalysis() ReportToConsole - aMsg='%s' params[0]='%s'",
             this, mDocument, aNotification.mReportStringId,
             aParams.IsEmpty() ? "<no params>" : NS_ConvertUTF16toUTF8(params[0]).get());
    nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
                                    NS_LITERAL_CSTRING("Media"),
                                    mDocument,
                                    nsContentUtils::eDOM_PROPERTIES,
                                    aNotification.mReportStringId,
                                    aParams.IsEmpty() ? nullptr : params,
                                    aParams.IsEmpty() ? 0 : 1);
  }

  // "media.decoder-doctor.notifications-allowed" controls which notifications
  // may be dispatched to the front-end. It either contains:
  // - '*' -> Allow everything.
  // - Comma-separater list of ids -> Allow if aReportStringId (from
  //                                  dom.properties) is one of them.
  // - Nothing (missing or empty) -> Disable everything.
  nsAdoptingCString filter =
    Preferences::GetCString("media.decoder-doctor.notifications-allowed");
  filter.StripWhitespace();
  if (filter.EqualsLiteral("*")
      || StringListContains(filter, aNotification.mReportStringId)) {
    DispatchNotification(
      mDocument->GetInnerWindow(), aNotification, aIsSolved, aParams);
  }
}
Example #4
0
already_AddRefed<InternalRequest>
TypeUtils::ToInternalRequest(const nsAString& aIn, ErrorResult& aRv)
{
  RequestOrUSVString requestOrString;
  requestOrString.SetAsUSVString().Rebind(aIn.Data(), aIn.Length());

  // Re-create a GlobalObject stack object so we can use webidl Constructors.
  AutoJSAPI jsapi;
  if (NS_WARN_IF(!jsapi.Init(GetGlobalObject()))) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return nullptr;
  }
  JSContext* cx = jsapi.cx();
  GlobalObject global(cx, GetGlobalObject()->GetGlobalJSObject());
  MOZ_ASSERT(!global.Failed());

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

  return request->GetInternalRequest();
}
Example #5
0
nsresult
BackgroundFileSaver::ExtractSignatureInfo(const nsAString& filePath)
{
  MOZ_ASSERT(!NS_IsMainThread(), "Cannot extract signature on main thread");

  nsNSSShutDownPreventionLock nssLock;
  if (isAlreadyShutDown()) {
    return NS_ERROR_NOT_AVAILABLE;
  }
  {
    MutexAutoLock lock(mLock);
    if (!mSignatureInfoEnabled) {
      return NS_OK;
    }
  }
  nsresult rv;
  nsCOMPtr<nsIX509CertDB> certDB = do_GetService(NS_X509CERTDB_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);
#ifdef XP_WIN
  // Setup the file to check.
  WINTRUST_FILE_INFO fileToCheck = {0};
  fileToCheck.cbStruct = sizeof(WINTRUST_FILE_INFO);
  fileToCheck.pcwszFilePath = filePath.Data();
  fileToCheck.hFile = nullptr;
  fileToCheck.pgKnownSubject = nullptr;

  // We want to check it is signed and trusted.
  WINTRUST_DATA trustData = {0};
  trustData.cbStruct = sizeof(trustData);
  trustData.pPolicyCallbackData = nullptr;
  trustData.pSIPClientData = nullptr;
  trustData.dwUIChoice = WTD_UI_NONE;
  trustData.fdwRevocationChecks = WTD_REVOKE_NONE;
  trustData.dwUnionChoice = WTD_CHOICE_FILE;
  trustData.dwStateAction = WTD_STATEACTION_VERIFY;
  trustData.hWVTStateData = nullptr;
  trustData.pwszURLReference = nullptr;
  // Disallow revocation checks over the network
  trustData.dwProvFlags = WTD_CACHE_ONLY_URL_RETRIEVAL;
  // no UI
  trustData.dwUIContext = 0;
  trustData.pFile = &fileToCheck;

  // The WINTRUST_ACTION_GENERIC_VERIFY_V2 policy verifies that the certificate
  // chains up to a trusted root CA and has appropriate permissions to sign
  // code.
  GUID policyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
  // Check if the file is signed by something that is trusted. If the file is
  // not signed, this is a no-op.
  LONG ret = WinVerifyTrust(nullptr, &policyGUID, &trustData);
  CRYPT_PROVIDER_DATA* cryptoProviderData = nullptr;
  // According to the Windows documentation, we should check against 0 instead
  // of ERROR_SUCCESS, which is an HRESULT.
  if (ret == 0) {
    cryptoProviderData = WTHelperProvDataFromStateData(trustData.hWVTStateData);
  }
  if (cryptoProviderData) {
    // Lock because signature information is read on the main thread.
    MutexAutoLock lock(mLock);
    LOG(("Downloaded trusted and signed file [this = %p].", this));
    // A binary may have multiple signers. Each signer may have multiple certs
    // in the chain.
    for (DWORD i = 0; i < cryptoProviderData->csSigners; ++i) {
      const CERT_CHAIN_CONTEXT* certChainContext =
        cryptoProviderData->pasSigners[i].pChainContext;
      if (!certChainContext) {
        break;
      }
      for (DWORD j = 0; j < certChainContext->cChain; ++j) {
        const CERT_SIMPLE_CHAIN* certSimpleChain =
          certChainContext->rgpChain[j];
        if (!certSimpleChain) {
          break;
        }
        nsCOMPtr<nsIX509CertList> nssCertList =
          do_CreateInstance(NS_X509CERTLIST_CONTRACTID);
        if (!nssCertList) {
          break;
        }
        bool extractionSuccess = true;
        for (DWORD k = 0; k < certSimpleChain->cElement; ++k) {
          CERT_CHAIN_ELEMENT* certChainElement = certSimpleChain->rgpElement[k];
          if (certChainElement->pCertContext->dwCertEncodingType !=
            X509_ASN_ENCODING) {
              continue;
          }
          nsCOMPtr<nsIX509Cert> nssCert = nullptr;
          rv = certDB->ConstructX509(
            reinterpret_cast<char *>(
              certChainElement->pCertContext->pbCertEncoded),
            certChainElement->pCertContext->cbCertEncoded,
            getter_AddRefs(nssCert));
          if (!nssCert) {
            extractionSuccess = false;
            LOG(("Couldn't create NSS cert [this = %p]", this));
            break;
          }
          nssCertList->AddCert(nssCert);
          nsString subjectName;
          nssCert->GetSubjectName(subjectName);
          LOG(("Adding cert %s [this = %p]",
               NS_ConvertUTF16toUTF8(subjectName).get(), this));
        }
        if (extractionSuccess) {
          mSignatureInfo.AppendObject(nssCertList);
        }
      }
    }
    // Free the provider data if cryptoProviderData is not null.
    trustData.dwStateAction = WTD_STATEACTION_CLOSE;
    WinVerifyTrust(nullptr, &policyGUID, &trustData);
  } else {
    LOG(("Downloaded unsigned or untrusted file [this = %p].", this));
  }
#endif
  return NS_OK;
}
static void
ReportAnalysis(nsIDocument* aDocument,
               const NotificationAndReportStringId& aNotification,
               bool aIsSolved,
               const nsAString& aFormats = NS_LITERAL_STRING(""),
               const MediaResult& aDecodeIssue = NS_OK,
               bool aDecodeIssueIsError = true,
               const nsACString& aDocURL = NS_LITERAL_CSTRING(""),
               const nsAString& aResourceURL = NS_LITERAL_STRING(""))
{
  MOZ_ASSERT(NS_IsMainThread());

  if (!aDocument) {
    return;
  }

  nsString decodeIssueDescription;
  if (aDecodeIssue != NS_OK) {
    decodeIssueDescription.Assign(MediaResultDescription(aDecodeIssue,
                                                         aDecodeIssueIsError));
  }

  // Report non-solved issues to console.
  if (!aIsSolved) {
    // Build parameter array needed by console message.
    AutoTArray<const char16_t*,
               NotificationAndReportStringId::maxReportParams> params;
    for (int i = 0; i < NotificationAndReportStringId::maxReportParams; ++i) {
      if (aNotification.mReportParams[i] == ReportParam::None) {
        break;
      }
      switch (aNotification.mReportParams[i]) {
      case ReportParam::Formats:
        params.AppendElement(aFormats.Data());
        break;
      case ReportParam::DecodeIssue:
        params.AppendElement(decodeIssueDescription.Data());
        break;
      case ReportParam::DocURL:
        params.AppendElement(NS_ConvertUTF8toUTF16(aDocURL).Data());
        break;
      case ReportParam::ResourceURL:
        params.AppendElement(aResourceURL.Data());
        break;
      default:
        MOZ_ASSERT_UNREACHABLE("Bad notification parameter choice");
        break;
      }
    }
    ReportToConsole(aDocument, aNotification.mReportStringId, params);
  }

  if (AllowNotification(aNotification) &&
      AllowDecodeIssue(aDecodeIssue, aDecodeIssueIsError)) {
    DispatchNotification(
      aDocument->GetInnerWindow(), aNotification, aIsSolved,
      aFormats,
      decodeIssueDescription,
      aDocURL,
      aResourceURL);
  }
}
Example #7
0
RangedPtr<const char16_t>
SVGContentUtils::GetEndRangedPtr(const nsAString& aString)
{
    return RangedPtr<const char16_t>(aString.Data() + aString.Length(),
                                     aString.Data(), aString.Length());
}
Example #8
0
bool
SVGContentUtils::ParseNumber(const nsAString& aString, 
                             floatType& aValue,
                             nsAString& aLeftOver)
{
  mozilla::RangedPtr<const PRUnichar> iter(aString.Data(), aString.Length());
  const mozilla::RangedPtr<const PRUnichar> end(aString.Data() + aString.Length(),
                                                aString.Data(), aString.Length());

  if (iter == end) {
    return false;
  }

  // Sign of the mantissa (-1 or 1).
  int32_t sign = *iter == '-' ? -1 : 1;

  if (*iter == '-' || *iter == '+') {
    ++iter;
    if (iter == end) {
      return false;
    }
  }

  // Absolute value of the integer part of the mantissa.
  floatType intPart = floatType(0);

  bool gotDot = *iter == '.';

  if (!gotDot) {
    if (!IsDigit(*iter)) {
      return false;
    }
    do {
      intPart = floatType(10) * intPart + DecimalDigitValue(*iter);
      ++iter;
    } while (iter != end && IsDigit(*iter));

    if (iter != end) {
      gotDot = *iter == '.';
    }
  }

  // Fractional part of the mantissa.
  floatType fracPart = floatType(0);

  if (gotDot) {
    ++iter;
    if (iter == end || !IsDigit(*iter)) {
      return false;
    }
    // Power of ten by which we need to divide our next digit
    floatType divisor = floatType(10);
    do {
      fracPart += DecimalDigitValue(*iter) / divisor;
      divisor *= 10;
      ++iter;
    } while (iter != end && IsDigit(*iter));
  }

  bool gotE = false;
  int32_t exponent = 0;
  int32_t expSign;

  if (iter != end && (*iter == 'e' || *iter == 'E')) {

    mozilla::RangedPtr<const PRUnichar> expIter(iter);

    ++expIter;
    if (expIter != end) {
      expSign = *expIter == '-' ? -1 : 1;
      if (*expIter == '-' || *expIter == '+') {
        ++expIter;
      }
      if (expIter != end && IsDigit(*expIter)) {
        // At this point we're sure this is an exponent
        // and not the start of a unit such as em or ex.
        gotE = true;
      }
    }

    if (gotE) {
      iter = expIter;
      do {
        exponent = 10 * exponent + DecimalDigitValue(*iter);
        ++iter;
      } while (iter != end && IsDigit(*iter));
    }
  }

  // Assemble the number
  aValue = sign * (intPart + fracPart);
  if (gotE) {
    aValue *= pow(floatType(10), floatType(expSign * exponent));
  }
  
  aLeftOver = Substring(iter.get(), end.get());
  return NS_finite(aValue);
}
/* static */ void
KeyframeEffectParams::ParseSpacing(const nsAString& aSpacing,
                                   SpacingMode& aSpacingMode,
                                   nsCSSPropertyID& aPacedProperty,
                                   nsAString& aInvalidPacedProperty,
                                   ErrorResult& aRv)
{
  aInvalidPacedProperty.Truncate();

  // Ignore spacing if the core API is not enabled since it is not yet ready to
  // ship.
  if (!AnimationUtils::IsCoreAPIEnabledForCaller()) {
    aSpacingMode = SpacingMode::distribute;
    return;
  }

  // Parse spacing.
  // distribute | paced({ident})
  // https://w3c.github.io/web-animations/#dom-keyframeeffectreadonly-spacing
  // 1. distribute spacing.
  if (aSpacing.EqualsLiteral("distribute")) {
    aSpacingMode = SpacingMode::distribute;
    return;
  }

  // 2. paced spacing.
  static const nsLiteralString kPacedPrefix = NS_LITERAL_STRING("paced(");
  if (!StringBeginsWith(aSpacing, kPacedPrefix)) {
    aRv.ThrowTypeError<dom::MSG_INVALID_SPACING_MODE_ERROR>(aSpacing);
    return;
  }

  RangedPtr<const char16_t> iter(aSpacing.Data() + kPacedPrefix.Length(),
                                 aSpacing.Data(), aSpacing.Length());
  const char16_t* const end = aSpacing.EndReading();

  nsAutoString identToken;
  ConsumeIdentToken(iter, end, identToken);
  if (identToken.IsEmpty()) {
    aRv.ThrowTypeError<dom::MSG_INVALID_SPACING_MODE_ERROR>(aSpacing);
    return;
  }

  aPacedProperty =
    nsCSSProps::LookupProperty(identToken, CSSEnabledState::eForAllContent);
  if (aPacedProperty == eCSSProperty_UNKNOWN ||
      aPacedProperty == eCSSPropertyExtra_variable ||
      !KeyframeUtils::IsAnimatableProperty(aPacedProperty)) {
    aPacedProperty = eCSSProperty_UNKNOWN;
    aInvalidPacedProperty = identToken;
  }

  if (end - iter.get() != 1 || *iter != ')') {
    aRv.ThrowTypeError<dom::MSG_INVALID_SPACING_MODE_ERROR>(aSpacing);
    return;
  }

  aSpacingMode = aPacedProperty == eCSSProperty_UNKNOWN
                 ? SpacingMode::distribute
                 : SpacingMode::paced;
}
Example #10
0
RangedPtr<const PRUnichar>
SVGContentUtils::GetStartRangedPtr(const nsAString& aString)
{
  return RangedPtr<const PRUnichar>(aString.Data(), aString.Length());
}