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; }
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); } }
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(); }
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); } }
RangedPtr<const char16_t> SVGContentUtils::GetEndRangedPtr(const nsAString& aString) { return RangedPtr<const char16_t>(aString.Data() + aString.Length(), aString.Data(), aString.Length()); }
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; }
RangedPtr<const PRUnichar> SVGContentUtils::GetStartRangedPtr(const nsAString& aString) { return RangedPtr<const PRUnichar>(aString.Data(), aString.Length()); }