Bug 1581537 - Avoid several browser language leaks r=smaug

Spoof dom/dom.properties, layout/xmlparser.properties,
layout/MediaDocument.properties to en-US if needed.

Differential Revision: https://phabricator.services.mozilla.com/D46034

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Alex Catarineu 2019-11-04 11:27:59 +00:00
parent fe10c35ad2
commit ea206b140d
25 changed files with 290 additions and 149 deletions

View File

@ -326,6 +326,9 @@
@RESPATH@/res/dtd/*
@RESPATH@/res/language.properties
@RESPATH@/res/locale/layout/HtmlForm.properties
@RESPATH@/res/locale/layout/MediaDocument.properties
@RESPATH@/res/locale/layout/xmlparser.properties
@RESPATH@/res/locale/dom/dom.properties
#ifdef XP_MACOSX
@RESPATH@/res/MainMenu.nib/
#endif

View File

@ -3653,7 +3653,7 @@ bool Document::DocumentSupportsL10n(JSContext* aCx, JSObject* aObject) {
}
void Document::LocalizationLinkAdded(Element* aLinkElement) {
if (!nsContentUtils::PrincipalAllowsL10n(NodePrincipal(), GetDocumentURI())) {
if (!AllowsL10n()) {
return;
}
@ -3691,7 +3691,7 @@ void Document::LocalizationLinkAdded(Element* aLinkElement) {
}
void Document::LocalizationLinkRemoved(Element* aLinkElement) {
if (!nsContentUtils::PrincipalAllowsL10n(NodePrincipal(), GetDocumentURI())) {
if (!AllowsL10n()) {
return;
}
@ -3757,6 +3757,10 @@ void Document::InitialDocumentTranslationCompleted() {
}
}
bool Document::AllowsL10n() const {
return nsContentUtils::PrincipalAllowsL10n(NodePrincipal(), GetDocumentURI());
}
bool Document::IsWebAnimationsEnabled(JSContext* aCx, JSObject* /*unused*/) {
MOZ_ASSERT(NS_IsMainThread());

View File

@ -4038,6 +4038,11 @@ class Document : public nsINode,
*/
void InitialDocumentTranslationCompleted();
/**
* Returns whether the document allows localization.
*/
bool AllowsL10n() const;
protected:
RefPtr<DocumentL10n> mDocumentL10n;

View File

@ -3570,8 +3570,8 @@ static const char* gPropertiesFiles[nsContentUtils::PropertiesFile_COUNT] = {
"chrome://global/locale/mathml/mathml.properties",
"chrome://global/locale/security/security.properties",
"chrome://necko/locale/necko.properties",
"chrome://global/locale/layout/HtmlForm.properties",
"resource://gre/res/locale/layout/HtmlForm.properties"};
"resource://gre/res/locale/layout/HtmlForm.properties",
"resource://gre/res/locale/dom/dom.properties"};
/* static */
nsresult nsContentUtils::EnsureStringBundle(PropertiesFile aFile) {
@ -3620,37 +3620,66 @@ void nsContentUtils::AsyncPrecreateStringBundles() {
}
}
static bool SpoofLocaleEnglish() {
/* static */
bool nsContentUtils::SpoofLocaleEnglish() {
// 0 - will prompt
// 1 - don't spoof
// 2 - spoof
return StaticPrefs::privacy_spoof_english() == 2;
}
static nsContentUtils::PropertiesFile GetMaybeSpoofedPropertiesFile(
nsContentUtils::PropertiesFile aFile, const char* aKey,
Document* aDocument) {
// When we spoof English, use en-US properties in strings that are accessible
// by content.
bool spoofLocale = nsContentUtils::SpoofLocaleEnglish() &&
(!aDocument || !aDocument->AllowsL10n());
if (spoofLocale) {
switch (aFile) {
case nsContentUtils::eFORMS_PROPERTIES:
return nsContentUtils::eFORMS_PROPERTIES_en_US;
case nsContentUtils::eDOM_PROPERTIES:
return nsContentUtils::eDOM_PROPERTIES_en_US;
default:
break;
}
}
return aFile;
}
/* static */
nsresult nsContentUtils::GetMaybeLocalizedString(PropertiesFile aFile,
const char* aKey,
Document* aDocument,
nsAString& aResult) {
return GetLocalizedString(
GetMaybeSpoofedPropertiesFile(aFile, aKey, aDocument), aKey, aResult);
}
/* static */
nsresult nsContentUtils::GetLocalizedString(PropertiesFile aFile,
const char* aKey,
nsAString& aResult) {
// When we spoof English, use en-US default strings in HTML forms.
if (aFile == eFORMS_PROPERTIES_MAYBESPOOF && SpoofLocaleEnglish()) {
aFile = eFORMS_PROPERTIES_en_US;
}
nsresult rv = EnsureStringBundle(aFile);
NS_ENSURE_SUCCESS(rv, rv);
nsIStringBundle* bundle = sStringBundles[aFile];
return bundle->GetStringFromName(aKey, aResult);
}
/* static */
nsresult nsContentUtils::FormatMaybeLocalizedString(
PropertiesFile aFile, const char* aKey, Document* aDocument,
const nsTArray<nsString>& aParams, nsAString& aResult) {
return FormatLocalizedString(
GetMaybeSpoofedPropertiesFile(aFile, aKey, aDocument), aKey, aParams,
aResult);
}
/* static */
nsresult nsContentUtils::FormatLocalizedString(
PropertiesFile aFile, const char* aKey, const nsTArray<nsString>& aParams,
nsAString& aResult) {
// When we spoof English, use en-US default strings in HTML forms.
if (aFile == eFORMS_PROPERTIES_MAYBESPOOF && SpoofLocaleEnglish()) {
aFile = eFORMS_PROPERTIES_en_US;
}
nsresult rv = EnsureStringBundle(aFile);
NS_ENSURE_SUCCESS(rv, rv);
nsIStringBundle* bundle = sStringBundles[aFile];

View File

@ -1098,8 +1098,8 @@ class nsContentUtils {
eMATHML_PROPERTIES,
eSECURITY_PROPERTIES,
eNECKO_PROPERTIES,
eFORMS_PROPERTIES_MAYBESPOOF,
eFORMS_PROPERTIES_en_US,
eDOM_PROPERTIES_en_US,
PropertiesFile_COUNT
};
static nsresult ReportToConsole(
@ -1113,12 +1113,23 @@ class nsContentUtils {
static void LogMessageToConsole(const char* aMsg);
static bool SpoofLocaleEnglish();
/**
* Get the localized string named |aKey| in properties file |aFile|.
*/
static nsresult GetLocalizedString(PropertiesFile aFile, const char* aKey,
nsAString& aResult);
/**
* Same as GetLocalizedString, except that it might use en-US locale depending
* on SpoofLocaleEnglish() and whether the document is a built-in browser
* page.
*/
static nsresult GetMaybeLocalizedString(PropertiesFile aFile,
const char* aKey, Document* aDocument,
nsAString& aResult);
/**
* A helper function that parses a sandbox attribute (of an <iframe> or a CSP
* directive) and converts it to the set of flags used internally.
@ -1203,6 +1214,24 @@ class nsContentUtils {
return FormatLocalizedString(aFile, aKey, params, aResult);
}
/**
* Same as FormatLocalizedString template version, except that it might use
* en-US locale depending on SpoofLocaleEnglish() and whether the document is
* a built-in browser page.
*/
template <typename... T>
static nsresult FormatMaybeLocalizedString(nsAString& aResult,
PropertiesFile aFile,
const char* aKey,
Document* aDocument,
const T&... aParams) {
static_assert(sizeof...(aParams) != 0, "Use GetMaybeLocalizedString()");
AutoTArray<nsString, sizeof...(aParams)> params = {
aParams...,
};
return FormatMaybeLocalizedString(aFile, aKey, aDocument, params, aResult);
}
/**
* Fill (with the parameters given) the localized string named |aKey| in
* properties file |aFile| consuming an nsTArray of nsString parameters rather
@ -1213,6 +1242,15 @@ class nsContentUtils {
const nsTArray<nsString>& aParamArray,
nsAString& aResult);
/**
* Same as FormatLocalizedString, except that it might use en-US locale
* depending on SpoofLocaleEnglish() and whether the document is a built-in
* browser page.
*/
static nsresult FormatMaybeLocalizedString(
PropertiesFile aFile, const char* aKey, Document* aDocument,
const nsTArray<nsString>& aParamArray, nsAString& aResult);
/**
* Returns true if aDocument is a chrome document
*/

View File

@ -742,15 +742,16 @@ nsresult HTMLInputElement::InitFilePicker(FilePickerType aType) {
nsAutoString title;
nsAutoString okButtonLabel;
if (aType == FILE_PICKER_DIRECTORY) {
nsContentUtils::GetLocalizedString(
nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "DirectoryUpload", title);
nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"DirectoryUpload", OwnerDoc(),
title);
nsContentUtils::GetLocalizedString(
nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF,
"DirectoryPickerOkButtonLabel", okButtonLabel);
nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"DirectoryPickerOkButtonLabel",
OwnerDoc(), okButtonLabel);
} else {
nsContentUtils::GetLocalizedString(
nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "FileUpload", title);
nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"FileUpload", OwnerDoc(), title);
}
nsCOMPtr<nsIFilePicker> filePicker =
@ -2366,23 +2367,24 @@ void HTMLInputElement::GetDisplayFileName(nsAString& aValue) const {
if ((StaticPrefs::dom_input_dirpicker() && Allowdirs()) ||
(StaticPrefs::dom_webkitBlink_dirPicker_enabled() &&
HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory))) {
nsContentUtils::GetLocalizedString(
nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "NoDirSelected", value);
nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"NoDirSelected", OwnerDoc(),
value);
} else if (HasAttr(kNameSpaceID_None, nsGkAtoms::multiple)) {
nsContentUtils::GetLocalizedString(
nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "NoFilesSelected",
value);
nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"NoFilesSelected", OwnerDoc(),
value);
} else {
nsContentUtils::GetLocalizedString(
nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "NoFileSelected",
value);
nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"NoFileSelected", OwnerDoc(),
value);
}
} else {
nsString count;
count.AppendInt(int(mFileData->mFilesOrDirectories.Length()));
nsContentUtils::FormatLocalizedString(
value, nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "XFilesSelected",
nsContentUtils::FormatMaybeLocalizedString(
value, nsContentUtils::eFORMS_PROPERTIES, "XFilesSelected", OwnerDoc(),
count);
}
@ -5819,8 +5821,8 @@ HTMLInputElement::SubmitNamesValues(HTMLFormSubmission* aFormSubmission) {
!HasAttr(kNameSpaceID_None, nsGkAtoms::value)) {
// Get our default value, which is the same as our default label
nsAutoString defaultValue;
nsContentUtils::GetLocalizedString(
nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "Submit", defaultValue);
nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"Submit", OwnerDoc(), defaultValue);
value = defaultValue;
}

View File

@ -1520,9 +1520,9 @@ nsresult HTMLSelectElement::GetValidationMessage(nsAString& aValidationMessage,
switch (aType) {
case VALIDITY_STATE_VALUE_MISSING: {
nsAutoString message;
nsresult rv = nsContentUtils::GetLocalizedString(
nsresult rv = nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationSelectMissing",
message);
OwnerDoc(), message);
aValidationMessage = message;
return rv;
}

View File

@ -1047,9 +1047,9 @@ nsresult HTMLTextAreaElement::GetValidationMessage(
strMaxLength.AppendInt(maxLength);
strTextLength.AppendInt(textLength);
rv = nsContentUtils::FormatLocalizedString(
rv = nsContentUtils::FormatMaybeLocalizedString(
message, nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooLong",
strMaxLength, strTextLength);
OwnerDoc(), strMaxLength, strTextLength);
aValidationMessage = message;
} break;
case VALIDITY_STATE_TOO_SHORT: {
@ -1062,16 +1062,17 @@ nsresult HTMLTextAreaElement::GetValidationMessage(
strMinLength.AppendInt(minLength);
strTextLength.AppendInt(textLength);
rv = nsContentUtils::FormatLocalizedString(
rv = nsContentUtils::FormatMaybeLocalizedString(
message, nsContentUtils::eDOM_PROPERTIES,
"FormValidationTextTooShort", strMinLength, strTextLength);
"FormValidationTextTooShort", OwnerDoc(), strMinLength,
strTextLength);
aValidationMessage = message;
} break;
case VALIDITY_STATE_VALUE_MISSING: {
nsAutoString message;
rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
"FormValidationValueMissing",
message);
rv = nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationValueMissing",
OwnerDoc(), message);
aValidationMessage = message;
} break;
default:

View File

@ -577,13 +577,13 @@ nsresult ImageDocument::OnLoadComplete(imgIRequest* aRequest,
UpdateTitleAndCharset();
// mImageContent can be null if the document is already destroyed
if (NS_FAILED(aStatus) && mStringBundle && mImageContent) {
if (NS_FAILED(aStatus) && mImageContent) {
nsAutoCString src;
mDocumentURI->GetSpec(src);
AutoTArray<nsString, 1> formatString;
CopyUTF8toUTF16(src, *formatString.AppendElement());
nsAutoString errorMsg;
mStringBundle->FormatStringFromName("InvalidImage", formatString, errorMsg);
FormatStringFromName("InvalidImage", formatString, errorMsg);
mImageContent->SetAttr(kNameSpaceID_None, nsGkAtoms::alt, errorMsg, false);
}
@ -786,7 +786,7 @@ void ImageDocument::UpdateTitleAndCharset() {
AutoTArray<nsString, 1> formatString;
formatString.AppendElement()->AppendInt(NSToCoordFloor(GetRatio() * 100));
mStringBundle->FormatStringFromName("ScaledImage", formatString, status);
FormatStringFromName("ScaledImage", formatString, status);
}
static const char* const formatNames[4] = {

View File

@ -121,14 +121,6 @@ nsresult MediaDocument::Init() {
nsresult rv = nsHTMLDocument::Init();
NS_ENSURE_SUCCESS(rv, rv);
// Create a bundle for the localization
nsCOMPtr<nsIStringBundleService> stringService =
mozilla::services::GetStringBundleService();
if (stringService) {
stringService->CreateBundle(NSMEDIADOCUMENT_PROPERTIES_URI,
getter_AddRefs(mStringBundle));
}
mIsSyntheticDocument = true;
return NS_OK;
@ -327,6 +319,37 @@ nsresult MediaDocument::LinkScript(const nsAString& aScript) {
return head->AppendChildTo(script, false);
}
void MediaDocument::FormatStringFromName(const char* aName,
const nsTArray<nsString>& aParams,
nsAString& aResult) {
bool spoofLocale = nsContentUtils::SpoofLocaleEnglish() && !AllowsL10n();
if (!spoofLocale) {
if (!mStringBundle) {
nsCOMPtr<nsIStringBundleService> stringService =
mozilla::services::GetStringBundleService();
if (stringService) {
stringService->CreateBundle(NSMEDIADOCUMENT_PROPERTIES_URI,
getter_AddRefs(mStringBundle));
}
}
if (mStringBundle) {
mStringBundle->FormatStringFromName(aName, aParams, aResult);
}
} else {
if (!mStringBundleEnglish) {
nsCOMPtr<nsIStringBundleService> stringService =
mozilla::services::GetStringBundleService();
if (stringService) {
stringService->CreateBundle(NSMEDIADOCUMENT_PROPERTIES_URI_en_US,
getter_AddRefs(mStringBundleEnglish));
}
}
if (mStringBundleEnglish) {
mStringBundleEnglish->FormatStringFromName(aName, aParams, aResult);
}
}
}
void MediaDocument::UpdateTitleAndCharset(const nsACString& aTypeStr,
nsIChannel* aChannel,
const char* const* aFormatNames,
@ -338,35 +361,29 @@ void MediaDocument::UpdateTitleAndCharset(const nsACString& aTypeStr,
NS_ConvertASCIItoUTF16 typeStr(aTypeStr);
nsAutoString title;
if (mStringBundle) {
// if we got a valid size (not all media have a size)
if (aWidth != 0 && aHeight != 0) {
nsAutoString widthStr;
nsAutoString heightStr;
widthStr.AppendInt(aWidth);
heightStr.AppendInt(aHeight);
// If we got a filename, display it
if (!fileStr.IsEmpty()) {
AutoTArray<nsString, 4> formatStrings = {fileStr, typeStr, widthStr,
heightStr};
mStringBundle->FormatStringFromName(aFormatNames[eWithDimAndFile],
formatStrings, title);
} else {
AutoTArray<nsString, 3> formatStrings = {typeStr, widthStr, heightStr};
mStringBundle->FormatStringFromName(aFormatNames[eWithDim],
formatStrings, title);
}
// if we got a valid size (not all media have a size)
if (aWidth != 0 && aHeight != 0) {
nsAutoString widthStr;
nsAutoString heightStr;
widthStr.AppendInt(aWidth);
heightStr.AppendInt(aHeight);
// If we got a filename, display it
if (!fileStr.IsEmpty()) {
AutoTArray<nsString, 4> formatStrings = {fileStr, typeStr, widthStr,
heightStr};
FormatStringFromName(aFormatNames[eWithDimAndFile], formatStrings, title);
} else {
// If we got a filename, display it
if (!fileStr.IsEmpty()) {
AutoTArray<nsString, 2> formatStrings = {fileStr, typeStr};
mStringBundle->FormatStringFromName(aFormatNames[eWithFile],
formatStrings, title);
} else {
AutoTArray<nsString, 1> formatStrings = {typeStr};
mStringBundle->FormatStringFromName(aFormatNames[eWithNoInfo],
formatStrings, title);
}
AutoTArray<nsString, 3> formatStrings = {typeStr, widthStr, heightStr};
FormatStringFromName(aFormatNames[eWithDim], formatStrings, title);
}
} else {
// If we got a filename, display it
if (!fileStr.IsEmpty()) {
AutoTArray<nsString, 2> formatStrings = {fileStr, typeStr};
FormatStringFromName(aFormatNames[eWithFile], formatStrings, title);
} else {
AutoTArray<nsString, 1> formatStrings = {typeStr};
FormatStringFromName(aFormatNames[eWithNoInfo], formatStrings, title);
}
}
@ -379,8 +396,7 @@ void MediaDocument::UpdateTitleAndCharset(const nsACString& aTypeStr,
AutoTArray<nsString, 2> formatStrings;
formatStrings.AppendElement(title);
formatStrings.AppendElement(aStatus);
mStringBundle->FormatStringFromName("TitleWithStatus", formatStrings,
titleWithStatus);
FormatStringFromName("TitleWithStatus", formatStrings, titleWithStatus);
SetTitle(titleWithStatus, IgnoreErrors());
}
}

View File

@ -16,6 +16,9 @@
#define NSMEDIADOCUMENT_PROPERTIES_URI \
"chrome://global/locale/layout/MediaDocument.properties"
#define NSMEDIADOCUMENT_PROPERTIES_URI_en_US \
"resource://gre/res/locale/layout/MediaDocument.properties"
namespace mozilla {
namespace dom {
@ -60,6 +63,10 @@ class MediaDocument : public nsHTMLDocument {
nsresult LinkStylesheet(const nsAString& aStylesheet);
nsresult LinkScript(const nsAString& aScript);
void FormatStringFromName(const char* aName,
const nsTArray<nsString>& aParams,
nsAString& aResult);
// |aFormatNames[]| needs to have four elements in the following order:
// a format name with neither dimension nor file, a format name with
// filename but w/o dimension, a format name with dimension but w/o filename,
@ -77,6 +84,7 @@ class MediaDocument : public nsHTMLDocument {
const nsAString& aStatus = EmptyString());
nsCOMPtr<nsIStringBundle> mStringBundle;
nsCOMPtr<nsIStringBundle> mStringBundleEnglish;
static const char* const sFormatNames[4];
private:

View File

@ -23,14 +23,15 @@ bool CheckboxInputType::IsValueMissing() const {
}
nsresult CheckboxInputType::GetValueMissingMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
"FormValidationCheckboxMissing",
aMessage);
return nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationCheckboxMissing",
mInputElement->OwnerDoc(), aMessage);
}
/* input type=radio */
nsresult RadioInputType::GetValueMissingMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationRadioMissing", aMessage);
return nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationRadioMissing",
mInputElement->OwnerDoc(), aMessage);
}

View File

@ -124,18 +124,19 @@ nsresult DateTimeInputTypeBase::GetRangeOverflowMessage(nsAString& aMessage) {
nsAutoString maxStr;
mInputElement->GetAttr(kNameSpaceID_None, nsGkAtoms::max, maxStr);
return nsContentUtils::FormatLocalizedString(
return nsContentUtils::FormatMaybeLocalizedString(
aMessage, nsContentUtils::eDOM_PROPERTIES,
"FormValidationDateTimeRangeOverflow", maxStr);
"FormValidationDateTimeRangeOverflow", mInputElement->OwnerDoc(), maxStr);
}
nsresult DateTimeInputTypeBase::GetRangeUnderflowMessage(nsAString& aMessage) {
nsAutoString minStr;
mInputElement->GetAttr(kNameSpaceID_None, nsGkAtoms::min, minStr);
return nsContentUtils::FormatLocalizedString(
return nsContentUtils::FormatMaybeLocalizedString(
aMessage, nsContentUtils::eDOM_PROPERTIES,
"FormValidationDateTimeRangeUnderflow", minStr);
"FormValidationDateTimeRangeUnderflow", mInputElement->OwnerDoc(),
minStr);
}
nsresult DateTimeInputTypeBase::MinMaxStepAttrChanged() {
@ -179,8 +180,9 @@ nsresult DateInputType::GetBadInputMessage(nsAString& aMessage) {
return NS_ERROR_UNEXPECTED;
}
return nsContentUtils::GetLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidDate", aMessage);
return nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidDate",
mInputElement->OwnerDoc(), aMessage);
}
bool DateInputType::ConvertStringToNumber(

View File

@ -21,6 +21,7 @@ bool FileInputType::IsValueMissing() const {
}
nsresult FileInputType::GetValueMissingMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationFileMissing", aMessage);
return nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationFileMissing",
mInputElement->OwnerDoc(), aMessage);
}

View File

@ -165,9 +165,9 @@ nsresult InputType::GetValidationMessage(
strMaxLength.AppendInt(maxLength);
strTextLength.AppendInt(textLength);
rv = nsContentUtils::FormatLocalizedString(
rv = nsContentUtils::FormatMaybeLocalizedString(
message, nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooLong",
strMaxLength, strTextLength);
mInputElement->OwnerDoc(), strMaxLength, strTextLength);
aValidationMessage = message;
break;
}
@ -182,9 +182,10 @@ nsresult InputType::GetValidationMessage(
strMinLength.AppendInt(minLength);
strTextLength.AppendInt(textLength);
rv = nsContentUtils::FormatLocalizedString(
rv = nsContentUtils::FormatMaybeLocalizedString(
message, nsContentUtils::eDOM_PROPERTIES,
"FormValidationTextTooShort", strMinLength, strTextLength);
"FormValidationTextTooShort", mInputElement->OwnerDoc(), strMinLength,
strTextLength);
aValidationMessage = message;
break;
@ -214,18 +215,19 @@ nsresult InputType::GetValidationMessage(
nsAutoString title;
mInputElement->GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
if (title.IsEmpty()) {
rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
"FormValidationPatternMismatch",
message);
rv = nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationPatternMismatch",
mInputElement->OwnerDoc(), message);
} else {
if (title.Length() >
nsIConstraintValidation::sContentSpecifiedMaxLengthMessage) {
title.Truncate(
nsIConstraintValidation::sContentSpecifiedMaxLengthMessage);
}
rv = nsContentUtils::FormatLocalizedString(
rv = nsContentUtils::FormatMaybeLocalizedString(
message, nsContentUtils::eDOM_PROPERTIES,
"FormValidationPatternMismatchWithTitle", title);
"FormValidationPatternMismatchWithTitle", mInputElement->OwnerDoc(),
title);
}
aValidationMessage = message;
break;
@ -274,21 +276,24 @@ nsresult InputType::GetValidationMessage(
ConvertNumberToString(valueHigh, valueHighStr);
if (valueLowStr.Equals(valueHighStr)) {
rv = nsContentUtils::FormatLocalizedString(
rv = nsContentUtils::FormatMaybeLocalizedString(
message, nsContentUtils::eDOM_PROPERTIES,
"FormValidationStepMismatchOneValue", valueLowStr);
"FormValidationStepMismatchOneValue", mInputElement->OwnerDoc(),
valueLowStr);
} else {
rv = nsContentUtils::FormatLocalizedString(
rv = nsContentUtils::FormatMaybeLocalizedString(
message, nsContentUtils::eDOM_PROPERTIES,
"FormValidationStepMismatch", valueLowStr, valueHighStr);
"FormValidationStepMismatch", mInputElement->OwnerDoc(),
valueLowStr, valueHighStr);
}
} else {
nsAutoString valueLowStr;
ConvertNumberToString(valueLow, valueLowStr);
rv = nsContentUtils::FormatLocalizedString(
rv = nsContentUtils::FormatMaybeLocalizedString(
message, nsContentUtils::eDOM_PROPERTIES,
"FormValidationStepMismatchOneValue", valueLowStr);
"FormValidationStepMismatchOneValue", mInputElement->OwnerDoc(),
valueLowStr);
}
aValidationMessage = message;
@ -312,8 +317,9 @@ nsresult InputType::GetValidationMessage(
}
nsresult InputType::GetValueMissingMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationValueMissing", aMessage);
return nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationValueMissing",
mInputElement->OwnerDoc(), aMessage);
}
nsresult InputType::GetTypeMismatchMessage(nsAString& aMessage) {

View File

@ -71,9 +71,9 @@ nsresult NumericInputTypeBase::GetRangeOverflowMessage(nsAString& aMessage) {
maxStr.AssignASCII(buf);
MOZ_ASSERT(ok, "buf not big enough");
return nsContentUtils::FormatLocalizedString(
return nsContentUtils::FormatMaybeLocalizedString(
aMessage, nsContentUtils::eDOM_PROPERTIES,
"FormValidationNumberRangeOverflow", maxStr);
"FormValidationNumberRangeOverflow", mInputElement->OwnerDoc(), maxStr);
}
nsresult NumericInputTypeBase::GetRangeUnderflowMessage(nsAString& aMessage) {
@ -87,9 +87,9 @@ nsresult NumericInputTypeBase::GetRangeUnderflowMessage(nsAString& aMessage) {
minStr.AssignASCII(buf);
MOZ_ASSERT(ok, "buf not big enough");
return nsContentUtils::FormatLocalizedString(
return nsContentUtils::FormatMaybeLocalizedString(
aMessage, nsContentUtils::eDOM_PROPERTIES,
"FormValidationNumberRangeUnderflow", minStr);
"FormValidationNumberRangeUnderflow", mInputElement->OwnerDoc(), minStr);
}
bool NumericInputTypeBase::ConvertStringToNumber(
@ -148,15 +148,15 @@ bool NumberInputType::HasBadInput() const {
}
nsresult NumberInputType::GetValueMissingMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
"FormValidationBadInputNumber",
aMessage);
return nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationBadInputNumber",
mInputElement->OwnerDoc(), aMessage);
}
nsresult NumberInputType::GetBadInputMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
"FormValidationBadInputNumber",
aMessage);
return nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationBadInputNumber",
mInputElement->OwnerDoc(), aMessage);
}
bool NumberInputType::IsMutable() const {

View File

@ -116,8 +116,9 @@ bool URLInputType::HasTypeMismatch() const {
}
nsresult URLInputType::GetTypeMismatchMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidURL", aMessage);
return nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidURL",
mInputElement->OwnerDoc(), aMessage);
}
/* input type=email */
@ -154,13 +155,15 @@ bool EmailInputType::HasBadInput() const {
}
nsresult EmailInputType::GetTypeMismatchMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidEmail", aMessage);
return nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidEmail",
mInputElement->OwnerDoc(), aMessage);
}
nsresult EmailInputType::GetBadInputMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidEmail", aMessage);
return nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidEmail",
mInputElement->OwnerDoc(), aMessage);
}
/* static */

View File

@ -62,4 +62,10 @@ JAR_MANIFESTS += ['jar.mn']
RESOURCE_FILES.locale.layout += [
'en-US/chrome/layout/HtmlForm.properties',
'en-US/chrome/layout/MediaDocument.properties',
'en-US/chrome/layout/xmlparser.properties',
]
RESOURCE_FILES.locale.dom += [
'en-US/chrome/dom/dom.properties',
]

View File

@ -1582,8 +1582,8 @@ already_AddRefed<nsIContent> nsCSSFrameConstructor::CreateGeneratedContent(
}
nsAutoString temp;
nsContentUtils::GetLocalizedString(
nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "Submit", temp);
nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eFORMS_PROPERTIES, "Submit", mDocument, temp);
return CreateGenConTextNode(aState, temp, nullptr);
}
@ -7871,8 +7871,9 @@ void nsCSSFrameConstructor::GetAlternateTextFor(Element* aElement, nsAtom* aTag,
// If there's no "value" attribute either, then use the localized string for
// "Submit" as the alternate text.
nsContentUtils::GetLocalizedString(
nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "Submit", aAltText);
nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"Submit", aElement->OwnerDoc(),
aAltText);
}
}

View File

@ -215,8 +215,8 @@ static already_AddRefed<Element> MakeAnonButton(Document* aDoc,
// Set the file picking button text depending on the current locale.
nsAutoString buttonTxt;
nsContentUtils::GetLocalizedString(
nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, labelKey, buttonTxt);
nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
labelKey, aDoc, buttonTxt);
// Set the browse button text. It's a bit of a pain to do because we want to
// make sure we are not notifying.

View File

@ -88,8 +88,8 @@ nsresult nsGfxButtonControlFrame::GetDefaultLabel(nsAString& aString) const {
return NS_OK;
}
return nsContentUtils::GetLocalizedString(
nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, prop, aString);
return nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eFORMS_PROPERTIES, prop, mContent->OwnerDoc(), aString);
}
nsresult nsGfxButtonControlFrame::GetLabel(nsString& aLabel) {

View File

@ -98,9 +98,9 @@ nsresult DetailsFrame::CreateAnonymousContent(
mDefaultSummary = new HTMLSummaryElement(nodeInfo.forget());
nsAutoString defaultSummaryText;
nsContentUtils::GetLocalizedString(
nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "DefaultSummary",
defaultSummaryText);
nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eFORMS_PROPERTIES, "DefaultSummary",
GetContent()->OwnerDoc(), defaultSummaryText);
RefPtr<nsTextNode> description = new nsTextNode(nodeInfoManager);
description->SetText(defaultSummaryText, false);
mDefaultSummary->AppendChildTo(description, false);

View File

@ -206,6 +206,9 @@
@BINPATH@/res/dtd/*
@BINPATH@/res/language.properties
@BINPATH@/res/locale/layout/HtmlForm.properties
@BINPATH@/res/locale/layout/MediaDocument.properties
@BINPATH@/res/locale/layout/xmlparser.properties
@BINPATH@/res/locale/dom/dom.properties
#ifndef MOZ_ANDROID_EXCLUDE_FONTS
@BINPATH@/res/fonts/*

View File

@ -683,12 +683,13 @@ static nsresult CreateErrorText(const char16_t* aDescription,
const char16_t* aSourceURL,
const uint32_t aLineNumber,
const uint32_t aColNumber,
nsString& aErrorString) {
nsString& aErrorString, bool spoofEnglish) {
aErrorString.Truncate();
nsAutoString msg;
nsresult rv = nsParserMsgUtils::GetLocalizedStringByName(
XMLPARSER_PROPERTIES, "XMLParsingError", msg);
spoofEnglish ? XMLPARSER_PROPERTIES_en_US : XMLPARSER_PROPERTIES,
"XMLParsingError", msg);
NS_ENSURE_SUCCESS(rv, rv);
// XML Parsing Error: %1$S\nLocation: %2$S\nLine Number %3$u, Column %4$u:
@ -729,8 +730,15 @@ nsresult nsExpatDriver::HandleError() {
// Map Expat error code to an error string
// XXX Deal with error returns.
nsAutoString description;
nsParserMsgUtils::GetLocalizedStringByID(XMLPARSER_PROPERTIES, code,
description);
nsCOMPtr<Document> doc;
if (mOriginalSink) {
doc = do_QueryInterface(mOriginalSink->GetTarget());
}
bool spoofEnglish =
nsContentUtils::SpoofLocaleEnglish() && (!doc || !doc->AllowsL10n());
nsParserMsgUtils::GetLocalizedStringByID(
spoofEnglish ? XMLPARSER_PROPERTIES_en_US : XMLPARSER_PROPERTIES, code,
description);
if (code == XML_ERROR_TAG_MISMATCH) {
/**
@ -766,8 +774,9 @@ nsresult nsExpatDriver::HandleError() {
tagName.Append(nameStart, (nameEnd ? nameEnd : pos) - nameStart);
nsAutoString msg;
nsParserMsgUtils::GetLocalizedStringByName(XMLPARSER_PROPERTIES, "Expected",
msg);
nsParserMsgUtils::GetLocalizedStringByName(
spoofEnglish ? XMLPARSER_PROPERTIES_en_US : XMLPARSER_PROPERTIES,
"Expected", msg);
// . Expected: </%S>.
nsAutoString message;
@ -781,7 +790,7 @@ nsresult nsExpatDriver::HandleError() {
nsAutoString errorText;
CreateErrorText(description.get(), XML_GetBase(mExpatParser), lineNumber,
colNumber, errorText);
colNumber, errorText, spoofEnglish);
nsAutoString sourceText(mLastLine);
AppendErrorPointer(colNumber, mLastLine.get(), sourceText);

View File

@ -11,6 +11,9 @@
#define XMLPARSER_PROPERTIES \
"chrome://global/locale/layout/xmlparser.properties"
#define XMLPARSER_PROPERTIES_en_US \
"resource://gre/res/locale/layout/xmlparser.properties"
class nsParserMsgUtils {
nsParserMsgUtils(); // Currently this is not meant to be created, use the
// static methods