commit 43d389c5d6e4450882d47a36bddc6e974c6113d5
Author: Alex Catarineu <acat(a)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