commit 43d389c5d6e4450882d47a36bddc6e974c6113d5 Author: Alex Catarineu acat@torproject.org Date: Tue Aug 20 12:58:09 2019 +0200
Bug 30683: Prevent detection of locale via some *.properties
Spoofing dom/dom.properties, layout/xmlparser.properties, layout/MediaDocument.properties to en-US if needed. --- browser/installer/package-manifest.in | 3 +++ dom/base/nsContentUtils.cpp | 17 +++++++++++++---- dom/base/nsContentUtils.h | 4 ++++ dom/html/HTMLSelectElement.cpp | 2 +- dom/html/HTMLTextAreaElement.cpp | 6 +++--- dom/html/MediaDocument.cpp | 4 +++- dom/html/MediaDocument.h | 3 +++ dom/html/input/CheckableInputTypes.cpp | 4 ++-- dom/html/input/DateTimeInputTypes.cpp | 6 +++--- dom/html/input/FileInputType.cpp | 2 +- dom/html/input/InputType.cpp | 16 ++++++++-------- dom/html/input/NumericInputTypes.cpp | 8 ++++---- dom/html/input/SingleLineTextInputTypes.cpp | 6 +++--- dom/locales/moz.build | 6 ++++++ mobile/android/installer/package-manifest.in | 3 +++ parser/htmlparser/nsParserMsgUtils.cpp | 6 ++++++ parser/htmlparser/nsParserMsgUtils.h | 3 +++ 17 files changed, 69 insertions(+), 30 deletions(-)
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 1a2a24f9b5b9..1825397678d1 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -345,6 +345,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 diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index d7ab544f7274..2b416828e8c1 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -3524,7 +3524,9 @@ static const char* gPropertiesFiles[nsContentUtils::PropertiesFile_COUNT] = { "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", + "chrome://global/locale/dom/dom.properties", + "resource://gre/res/locale/dom/dom.properties"};
/* static */ nsresult nsContentUtils::EnsureStringBundle(PropertiesFile aFile) { @@ -3573,7 +3575,8 @@ void nsContentUtils::AsyncPrecreateStringBundles() { } }
-static bool SpoofLocaleEnglish() { +/* static */ +bool nsContentUtils::SpoofLocaleEnglish() { // 0 - will prompt // 1 - don't spoof // 2 - spoof @@ -3584,9 +3587,12 @@ static bool SpoofLocaleEnglish() { nsresult nsContentUtils::GetLocalizedString(PropertiesFile aFile, const char* aKey, nsAString& aResult) { - // When we spoof English, use en-US default strings in HTML forms. + // When we spoof English, use en-US properties in strings that are accessible + // by content. if (aFile == eFORMS_PROPERTIES_MAYBESPOOF && SpoofLocaleEnglish()) { aFile = eFORMS_PROPERTIES_en_US; + } else if (aFile == eDOM_PROPERTIES_MAYBESPOOF && SpoofLocaleEnglish()) { + aFile = eDOM_PROPERTIES_en_US; }
nsresult rv = EnsureStringBundle(aFile); @@ -3601,9 +3607,12 @@ nsresult nsContentUtils::FormatLocalizedString(PropertiesFile aFile, const char16_t** aParams, uint32_t aParamsLength, nsAString& aResult) { - // When we spoof English, use en-US default strings in HTML forms. + // When we spoof English, use en-US properties in strings that are accessible + // by content. if (aFile == eFORMS_PROPERTIES_MAYBESPOOF && SpoofLocaleEnglish()) { aFile = eFORMS_PROPERTIES_en_US; + } else if (aFile == eDOM_PROPERTIES_MAYBESPOOF && SpoofLocaleEnglish()) { + aFile = eDOM_PROPERTIES_en_US; }
nsresult rv = EnsureStringBundle(aFile); diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 67febf189c34..9c409099c9af 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -1119,6 +1119,8 @@ class nsContentUtils { eNECKO_PROPERTIES, eFORMS_PROPERTIES_MAYBESPOOF, eFORMS_PROPERTIES_en_US, + eDOM_PROPERTIES_MAYBESPOOF, + eDOM_PROPERTIES_en_US, PropertiesFile_COUNT }; static nsresult ReportToConsole( @@ -1132,6 +1134,8 @@ class nsContentUtils {
static void LogMessageToConsole(const char* aMsg);
+ static bool SpoofLocaleEnglish(); + /** * Get the localized string named |aKey| in properties file |aFile|. */ diff --git a/dom/html/HTMLSelectElement.cpp b/dom/html/HTMLSelectElement.cpp index 76f21db23b31..afa01ee224ba 100644 --- a/dom/html/HTMLSelectElement.cpp +++ b/dom/html/HTMLSelectElement.cpp @@ -1539,7 +1539,7 @@ nsresult HTMLSelectElement::GetValidationMessage(nsAString& aValidationMessage, case VALIDITY_STATE_VALUE_MISSING: { nsAutoString message; nsresult rv = nsContentUtils::GetLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationSelectMissing", + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationSelectMissing", message); aValidationMessage = message; return rv; diff --git a/dom/html/HTMLTextAreaElement.cpp b/dom/html/HTMLTextAreaElement.cpp index 0d1ba35c8b59..2844267b9bb8 100644 --- a/dom/html/HTMLTextAreaElement.cpp +++ b/dom/html/HTMLTextAreaElement.cpp @@ -1001,7 +1001,7 @@ nsresult HTMLTextAreaElement::GetValidationMessage(
const char16_t* params[] = {strMaxLength.get(), strTextLength.get()}; rv = nsContentUtils::FormatLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooLong", params, + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationTextTooLong", params, message); aValidationMessage = message; } break; @@ -1017,13 +1017,13 @@ nsresult HTMLTextAreaElement::GetValidationMessage(
const char16_t* params[] = {strMinLength.get(), strTextLength.get()}; rv = nsContentUtils::FormatLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooShort", params, + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationTextTooShort", params, message); aValidationMessage = message; } break; case VALIDITY_STATE_VALUE_MISSING: { nsAutoString message; - rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES, + rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationValueMissing", message); aValidationMessage = message; diff --git a/dom/html/MediaDocument.cpp b/dom/html/MediaDocument.cpp index 196adddc0f38..7ec66b31e63d 100644 --- a/dom/html/MediaDocument.cpp +++ b/dom/html/MediaDocument.cpp @@ -125,7 +125,9 @@ nsresult MediaDocument::Init() { nsCOMPtr<nsIStringBundleService> stringService = mozilla::services::GetStringBundleService(); if (stringService) { - stringService->CreateBundle(NSMEDIADOCUMENT_PROPERTIES_URI, + stringService->CreateBundle(nsContentUtils::SpoofLocaleEnglish() + ? NSMEDIADOCUMENT_PROPERTIES_URI_en_US + : NSMEDIADOCUMENT_PROPERTIES_URI, getter_AddRefs(mStringBundle)); }
diff --git a/dom/html/MediaDocument.h b/dom/html/MediaDocument.h index e11fd2ec8551..37e005c7fffa 100644 --- a/dom/html/MediaDocument.h +++ b/dom/html/MediaDocument.h @@ -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 {
diff --git a/dom/html/input/CheckableInputTypes.cpp b/dom/html/input/CheckableInputTypes.cpp index f55000c766ea..f0306b69cbd0 100644 --- a/dom/html/input/CheckableInputTypes.cpp +++ b/dom/html/input/CheckableInputTypes.cpp @@ -23,7 +23,7 @@ bool CheckboxInputType::IsValueMissing() const { }
nsresult CheckboxInputType::GetValueMissingMessage(nsAString& aMessage) { - return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES, + return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationCheckboxMissing", aMessage); } @@ -32,5 +32,5 @@ nsresult CheckboxInputType::GetValueMissingMessage(nsAString& aMessage) {
nsresult RadioInputType::GetValueMissingMessage(nsAString& aMessage) { return nsContentUtils::GetLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationRadioMissing", aMessage); + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationRadioMissing", aMessage); } diff --git a/dom/html/input/DateTimeInputTypes.cpp b/dom/html/input/DateTimeInputTypes.cpp index 11dfc9e541b9..0efbe9a9121a 100644 --- a/dom/html/input/DateTimeInputTypes.cpp +++ b/dom/html/input/DateTimeInputTypes.cpp @@ -138,7 +138,7 @@ nsresult DateTimeInputTypeBase::GetRangeOverflowMessage(nsAString& aMessage) {
const char16_t* params[] = {maxStr.get()}; return nsContentUtils::FormatLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationDateTimeRangeOverflow", + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationDateTimeRangeOverflow", params, aMessage); }
@@ -148,7 +148,7 @@ nsresult DateTimeInputTypeBase::GetRangeUnderflowMessage(nsAString& aMessage) {
const char16_t* params[] = {minStr.get()}; return nsContentUtils::FormatLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationDateTimeRangeUnderflow", + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationDateTimeRangeUnderflow", params, aMessage); }
@@ -194,7 +194,7 @@ nsresult DateInputType::GetBadInputMessage(nsAString& aMessage) { }
return nsContentUtils::GetLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidDate", aMessage); + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationInvalidDate", aMessage); }
bool DateInputType::ConvertStringToNumber( diff --git a/dom/html/input/FileInputType.cpp b/dom/html/input/FileInputType.cpp index 2536a875b2ca..82a4c2de8659 100644 --- a/dom/html/input/FileInputType.cpp +++ b/dom/html/input/FileInputType.cpp @@ -22,5 +22,5 @@ bool FileInputType::IsValueMissing() const {
nsresult FileInputType::GetValueMissingMessage(nsAString& aMessage) { return nsContentUtils::GetLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationFileMissing", aMessage); + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationFileMissing", aMessage); } diff --git a/dom/html/input/InputType.cpp b/dom/html/input/InputType.cpp index 210daeafad14..f7a28f4c1a3a 100644 --- a/dom/html/input/InputType.cpp +++ b/dom/html/input/InputType.cpp @@ -167,7 +167,7 @@ nsresult InputType::GetValidationMessage(
const char16_t* params[] = {strMaxLength.get(), strTextLength.get()}; rv = nsContentUtils::FormatLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooLong", params, + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationTextTooLong", params, message); aValidationMessage = message; break; @@ -185,7 +185,7 @@ nsresult InputType::GetValidationMessage(
const char16_t* params[] = {strMinLength.get(), strTextLength.get()}; rv = nsContentUtils::FormatLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooShort", params, + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationTextTooShort", params, message);
aValidationMessage = message; @@ -216,7 +216,7 @@ nsresult InputType::GetValidationMessage( nsAutoString title; mInputElement->GetAttr(kNameSpaceID_None, nsGkAtoms::title, title); if (title.IsEmpty()) { - rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES, + rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationPatternMismatch", message); } else { @@ -227,7 +227,7 @@ nsresult InputType::GetValidationMessage( } const char16_t* params[] = {title.get()}; rv = nsContentUtils::FormatLocalizedString( - nsContentUtils::eDOM_PROPERTIES, + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationPatternMismatchWithTitle", params, message); } aValidationMessage = message; @@ -279,12 +279,12 @@ nsresult InputType::GetValidationMessage( if (valueLowStr.Equals(valueHighStr)) { const char16_t* params[] = {valueLowStr.get()}; rv = nsContentUtils::FormatLocalizedString( - nsContentUtils::eDOM_PROPERTIES, + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationStepMismatchOneValue", params, message); } else { const char16_t* params[] = {valueLowStr.get(), valueHighStr.get()}; rv = nsContentUtils::FormatLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationStepMismatch", + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationStepMismatch", params, message); } } else { @@ -293,7 +293,7 @@ nsresult InputType::GetValidationMessage(
const char16_t* params[] = {valueLowStr.get()}; rv = nsContentUtils::FormatLocalizedString( - nsContentUtils::eDOM_PROPERTIES, + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationStepMismatchOneValue", params, message); }
@@ -319,7 +319,7 @@ nsresult InputType::GetValidationMessage(
nsresult InputType::GetValueMissingMessage(nsAString& aMessage) { return nsContentUtils::GetLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationValueMissing", aMessage); + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationValueMissing", aMessage); }
nsresult InputType::GetTypeMismatchMessage(nsAString& aMessage) { diff --git a/dom/html/input/NumericInputTypes.cpp b/dom/html/input/NumericInputTypes.cpp index 6332e028c17e..ab0f6f36eb95 100644 --- a/dom/html/input/NumericInputTypes.cpp +++ b/dom/html/input/NumericInputTypes.cpp @@ -73,7 +73,7 @@ nsresult NumericInputTypeBase::GetRangeOverflowMessage(nsAString& aMessage) {
const char16_t* params[] = {maxStr.get()}; return nsContentUtils::FormatLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationNumberRangeOverflow", + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationNumberRangeOverflow", params, aMessage); }
@@ -90,7 +90,7 @@ nsresult NumericInputTypeBase::GetRangeUnderflowMessage(nsAString& aMessage) {
const char16_t* params[] = {minStr.get()}; return nsContentUtils::FormatLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationNumberRangeUnderflow", + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationNumberRangeUnderflow", params, aMessage); }
@@ -150,13 +150,13 @@ bool NumberInputType::HasBadInput() const { }
nsresult NumberInputType::GetValueMissingMessage(nsAString& aMessage) { - return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES, + return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationBadInputNumber", aMessage); }
nsresult NumberInputType::GetBadInputMessage(nsAString& aMessage) { - return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES, + return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationBadInputNumber", aMessage); } diff --git a/dom/html/input/SingleLineTextInputTypes.cpp b/dom/html/input/SingleLineTextInputTypes.cpp index 15cbe65a1941..c879276c86da 100644 --- a/dom/html/input/SingleLineTextInputTypes.cpp +++ b/dom/html/input/SingleLineTextInputTypes.cpp @@ -117,7 +117,7 @@ bool URLInputType::HasTypeMismatch() const {
nsresult URLInputType::GetTypeMismatchMessage(nsAString& aMessage) { return nsContentUtils::GetLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidURL", aMessage); + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationInvalidURL", aMessage); }
/* input type=email */ @@ -155,12 +155,12 @@ bool EmailInputType::HasBadInput() const {
nsresult EmailInputType::GetTypeMismatchMessage(nsAString& aMessage) { return nsContentUtils::GetLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidEmail", aMessage); + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationInvalidEmail", aMessage); }
nsresult EmailInputType::GetBadInputMessage(nsAString& aMessage) { return nsContentUtils::GetLocalizedString( - nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidEmail", aMessage); + nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationInvalidEmail", aMessage); }
/* static */ diff --git a/dom/locales/moz.build b/dom/locales/moz.build index b2bcd271de7c..51f4b88ccd47 100644 --- a/dom/locales/moz.build +++ b/dom/locales/moz.build @@ -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', ] diff --git a/mobile/android/installer/package-manifest.in b/mobile/android/installer/package-manifest.in index 2002a894fc51..ae4319214fad 100644 --- a/mobile/android/installer/package-manifest.in +++ b/mobile/android/installer/package-manifest.in @@ -203,6 +203,9 @@ @BINPATH@/res/dtd/* @BINPATH@/res/language.properties @BINPATH@/res/locale/layout/HtmlForm.properties +@RESPATH@/res/locale/layout/MediaDocument.properties +@RESPATH@/res/locale/layout/xmlparser.properties +@RESPATH@/res/locale/dom/dom.properties
#ifndef MOZ_ANDROID_EXCLUDE_FONTS @BINPATH@/res/fonts/* diff --git a/parser/htmlparser/nsParserMsgUtils.cpp b/parser/htmlparser/nsParserMsgUtils.cpp index 3e369893d4f7..47749732839e 100644 --- a/parser/htmlparser/nsParserMsgUtils.cpp +++ b/parser/htmlparser/nsParserMsgUtils.cpp @@ -9,6 +9,7 @@ #include "nsParserMsgUtils.h" #include "nsNetCID.h" #include "mozilla/Services.h" +#include "nsContentUtils.h"
static nsresult GetBundle(const char* aPropFileName, nsIStringBundle** aBundle) { @@ -21,6 +22,11 @@ static nsresult GetBundle(const char* aPropFileName, mozilla::services::GetStringBundleService(); if (!stringService) return NS_ERROR_FAILURE;
+ if (nsContentUtils::SpoofLocaleEnglish() && + strcmp(aPropFileName, XMLPARSER_PROPERTIES) == 0) { + aPropFileName = XMLPARSER_PROPERTIES_en_US; + } + return stringService->CreateBundle(aPropFileName, aBundle); }
diff --git a/parser/htmlparser/nsParserMsgUtils.h b/parser/htmlparser/nsParserMsgUtils.h index b4ec4784d65f..3645610385c1 100644 --- a/parser/htmlparser/nsParserMsgUtils.h +++ b/parser/htmlparser/nsParserMsgUtils.h @@ -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