mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-26 20:30:41 +00:00
Bug 1733490 - Migrate CSP error messages from extensions.properties to Fluent. r=zbraniecki,mixedpuppy,flod
The actual messages were migrated using https://github.com/mozilla/properties-to-ftl, while C++ changes use patterns established by https://bugzilla.mozilla.org/show_bug.cgi?id=1742106. Differential Revision: https://phabricator.services.mozilla.com/D131594
This commit is contained in:
parent
3113e4d131
commit
18caf861b1
@ -142,6 +142,9 @@ var whitelist = [
|
||||
{ file: "resource://gre/res/fonts/mathfontSTIXGeneral.properties" },
|
||||
{ file: "resource://gre/res/fonts/mathfontUnicode.properties" },
|
||||
|
||||
// toolkit/mozapps/extensions/AddonContentPolicy.cpp
|
||||
{ file: "resource://gre/localization/en-US/toolkit/global/cspErrors.ftl" },
|
||||
|
||||
// The l10n build system can't package string files only for some platforms.
|
||||
{
|
||||
file:
|
||||
|
82
python/l10n/fluent_migrations/bug_1733490_csp_errors.py
Normal file
82
python/l10n/fluent_migrations/bug_1733490_csp_errors.py
Normal file
@ -0,0 +1,82 @@
|
||||
# Any copyright is dedicated to the Public Domain.
|
||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
import fluent.syntax.ast as FTL
|
||||
from fluent.migrate.helpers import VARIABLE_REFERENCE
|
||||
from fluent.migrate.transforms import REPLACE
|
||||
|
||||
|
||||
def migrate(ctx):
|
||||
"""Bug 1733490 - Convert CSP errors from extensions.properties to Fluent, part {index}."""
|
||||
|
||||
source = "toolkit/chrome/global/extensions.properties"
|
||||
target = "toolkit/toolkit/global/cspErrors.ftl"
|
||||
ctx.add_transforms(
|
||||
target,
|
||||
target,
|
||||
[
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("csp-error-missing-directive"),
|
||||
value=REPLACE(
|
||||
source,
|
||||
"csp.error.missing-directive",
|
||||
{"%1$S": VARIABLE_REFERENCE("directive")},
|
||||
),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("csp-error-illegal-keyword"),
|
||||
value=REPLACE(
|
||||
source,
|
||||
"csp.error.illegal-keyword",
|
||||
{
|
||||
"%1$S": VARIABLE_REFERENCE("directive"),
|
||||
"%2$S": VARIABLE_REFERENCE("keyword"),
|
||||
},
|
||||
),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("csp-error-illegal-protocol"),
|
||||
value=REPLACE(
|
||||
source,
|
||||
"csp.error.illegal-protocol",
|
||||
{
|
||||
"%1$S": VARIABLE_REFERENCE("directive"),
|
||||
"%2$S": VARIABLE_REFERENCE("scheme"),
|
||||
},
|
||||
),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("csp-error-missing-host"),
|
||||
value=REPLACE(
|
||||
source,
|
||||
"csp.error.missing-host",
|
||||
{
|
||||
"%2$S": VARIABLE_REFERENCE("scheme"),
|
||||
"%1$S": VARIABLE_REFERENCE("directive"),
|
||||
},
|
||||
),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("csp-error-missing-source"),
|
||||
value=REPLACE(
|
||||
source,
|
||||
"csp.error.missing-source",
|
||||
{
|
||||
"%1$S": VARIABLE_REFERENCE("directive"),
|
||||
"%2$S": VARIABLE_REFERENCE("source"),
|
||||
},
|
||||
),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("csp-error-illegal-host-wildcard"),
|
||||
value=REPLACE(
|
||||
source,
|
||||
"csp.error.illegal-host-wildcard",
|
||||
{
|
||||
"%2$S": VARIABLE_REFERENCE("scheme"),
|
||||
"%1$S": VARIABLE_REFERENCE("directive"),
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
@ -2,23 +2,6 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
csp.error.missing-directive = Policy is missing a required ‘%S’ directive
|
||||
|
||||
#LOCALIZATION NOTE (csp.error.illegal-keyword) %1$S is the name of a CSP directive, such as "script-src". %2$S is the name of a CSP keyword, usually 'unsafe-inline'.
|
||||
csp.error.illegal-keyword = ‘%1$S’ directive contains a forbidden %2$S keyword
|
||||
|
||||
#LOCALIZATION NOTE (csp.error.illegal-protocol) %2$S a protocol name, such as "http", which appears as "http:", as it would in a URL.
|
||||
csp.error.illegal-protocol = ‘%1$S’ directive contains a forbidden %2$S: protocol source
|
||||
|
||||
#LOCALIZATION NOTE (csp.error.missing-host) %2$S a protocol name, such as "http", which appears as "http:", as it would in a URL.
|
||||
csp.error.missing-host = %2$S: protocol requires a host in ‘%1$S’ directives
|
||||
|
||||
#LOCALIZATION NOTE (csp.error.missing-source) %1$S is the name of a CSP directive, such as "script-src". %2$S is the name of a CSP source, usually 'self'.
|
||||
csp.error.missing-source = ‘%1$S’ must include the source %2$S
|
||||
|
||||
#LOCALIZATION NOTE (csp.error.illegal-host-wildcard) %2$S a protocol name, such as "http", which appears as "http:", as it would in a URL.
|
||||
csp.error.illegal-host-wildcard = %2$S: wildcard sources in ‘%1$S’ directives must include at least one non-generic sub-domain (e.g., *.example.com rather than *.com)
|
||||
|
||||
#LOCALIZATION NOTE (uninstall.confirmation.title) %S is the name of the extension which is about to be uninstalled.
|
||||
uninstall.confirmation.title = Uninstall %S
|
||||
|
||||
|
32
toolkit/locales/en-US/toolkit/global/cspErrors.ftl
Normal file
32
toolkit/locales/en-US/toolkit/global/cspErrors.ftl
Normal file
@ -0,0 +1,32 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# Variables:
|
||||
# $directive (String): the name of a CSP directive, such as "script-src".
|
||||
csp-error-missing-directive = Policy is missing a required ‘{ $directive }’ directive
|
||||
|
||||
# Variables:
|
||||
# $directive (String): the name of a CSP directive, such as "script-src".
|
||||
# $keyword (String): the name of a CSP keyword, usually 'unsafe-inline'.
|
||||
csp-error-illegal-keyword = ‘{ $directive }’ directive contains a forbidden { $keyword } keyword
|
||||
|
||||
# Variables:
|
||||
# $directive (String): the name of a CSP directive, such as "script-src".
|
||||
# $scheme (String): a protocol name, such as "http", which appears as "http:", as it would in a URL.
|
||||
csp-error-illegal-protocol = ‘{ $directive }’ directive contains a forbidden { $scheme }: protocol source
|
||||
|
||||
# Variables:
|
||||
# $directive (String): the name of a CSP directive, such as "script-src".
|
||||
# $scheme (String): a protocol name, such as "http", which appears as "http:", as it would in a URL.
|
||||
csp-error-missing-host = { $scheme }: protocol requires a host in ‘{ $directive }’ directives
|
||||
|
||||
# Variables:
|
||||
# $directive (String): the name of a CSP directive, such as "script-src".
|
||||
# $source (String): the name of a CSP source, usually 'self'.
|
||||
csp-error-missing-source = ‘{ $directive }’ must include the source { $source }
|
||||
|
||||
# Variables:
|
||||
# $directive (String): the name of a CSP directive, such as "script-src".
|
||||
# $scheme (String): a protocol name, such as "http", which appears as "http:", as it would in a URL.
|
||||
csp-error-illegal-host-wildcard = { $scheme }: wildcard sources in ‘{ $directive }’ directives must include at least one non-generic sub-domain (e.g., *.example.com rather than *.com)
|
@ -17,6 +17,7 @@
|
||||
#include "nsIContent.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/intl/Localization.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIStringBundle.h"
|
||||
@ -26,6 +27,7 @@
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::intl;
|
||||
|
||||
/* Enforces content policies for WebExtension scopes. Currently:
|
||||
*
|
||||
@ -189,7 +191,7 @@ class CSPValidator final : public nsCSPSrcVisitor {
|
||||
// visitors will be called if the directive isn't present.
|
||||
mError.SetIsVoid(true);
|
||||
if (aDirectiveRequired) {
|
||||
FormatError("csp.error.missing-directive");
|
||||
FormatError("csp-error-missing-directive"_ns);
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,11 +202,11 @@ class CSPValidator final : public nsCSPSrcVisitor {
|
||||
src.getScheme(scheme);
|
||||
|
||||
if (SchemeInList(scheme, allowedHostSchemes)) {
|
||||
FormatError("csp.error.missing-host", scheme);
|
||||
FormatError("csp-error-missing-host"_ns, "scheme"_ns, scheme);
|
||||
return false;
|
||||
}
|
||||
if (!SchemeInList(scheme, allowedSchemes)) {
|
||||
FormatError("csp.error.illegal-protocol", scheme);
|
||||
FormatError("csp-error-illegal-protocol"_ns, "scheme"_ns, scheme);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -222,7 +224,7 @@ class CSPValidator final : public nsCSPSrcVisitor {
|
||||
HostIsLocal(host)) {
|
||||
return true;
|
||||
}
|
||||
FormatError("csp.error.illegal-protocol", scheme);
|
||||
FormatError("csp-error-illegal-protocol"_ns, "scheme"_ns, scheme);
|
||||
return false;
|
||||
}
|
||||
if (scheme.LowerCaseEqualsLiteral("https")) {
|
||||
@ -231,11 +233,11 @@ class CSPValidator final : public nsCSPSrcVisitor {
|
||||
return true;
|
||||
}
|
||||
if (!(mPermittedPolicy & nsIAddonContentPolicy::CSP_ALLOW_REMOTE)) {
|
||||
FormatError("csp.error.illegal-protocol", scheme);
|
||||
FormatError("csp-error-illegal-protocol"_ns, "scheme"_ns, scheme);
|
||||
return false;
|
||||
}
|
||||
if (!HostIsAllowed(host)) {
|
||||
FormatError("csp.error.illegal-host-wildcard", scheme);
|
||||
FormatError("csp-error-illegal-host-wildcard"_ns, "scheme"_ns, scheme);
|
||||
return false;
|
||||
}
|
||||
} else if (scheme.LowerCaseEqualsLiteral("moz-extension")) {
|
||||
@ -249,11 +251,11 @@ class CSPValidator final : public nsCSPSrcVisitor {
|
||||
}
|
||||
|
||||
if (host.IsEmpty() || host.EqualsLiteral("*")) {
|
||||
FormatError("csp.error.missing-host", scheme);
|
||||
FormatError("csp-error-missing-host"_ns, "scheme"_ns, scheme);
|
||||
return false;
|
||||
}
|
||||
} else if (!SchemeInList(scheme, allowedSchemes)) {
|
||||
FormatError("csp.error.illegal-protocol", scheme);
|
||||
FormatError("csp-error-illegal-protocol"_ns, "scheme"_ns, scheme);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -273,14 +275,14 @@ class CSPValidator final : public nsCSPSrcVisitor {
|
||||
[[fallthrough]];
|
||||
default:
|
||||
FormatError(
|
||||
"csp.error.illegal-keyword",
|
||||
"csp-error-illegal-keyword"_ns, "keyword"_ns,
|
||||
nsDependentString(CSP_EnumToUTF16Keyword(src.getKeyword())));
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
bool visitNonceSrc(const nsCSPNonceSrc& src) override {
|
||||
FormatError("csp.error.illegal-keyword", u"'nonce-*'"_ns);
|
||||
FormatError("csp-error-illegal-keyword"_ns, "keyword"_ns, u"'nonce-*'"_ns);
|
||||
return false;
|
||||
};
|
||||
|
||||
@ -294,11 +296,35 @@ class CSPValidator final : public nsCSPSrcVisitor {
|
||||
|
||||
// Formatters
|
||||
|
||||
template <typename... T>
|
||||
inline void FormatError(const char* aName, const T... aParams) {
|
||||
AutoTArray<nsString, sizeof...(aParams) + 1> params = {mDirective,
|
||||
aParams...};
|
||||
FormatErrorParams(aName, params);
|
||||
inline void FormatError(const nsACString& l10nId,
|
||||
const nsACString& aKey = ""_ns,
|
||||
const nsAString& aValue = u""_ns) {
|
||||
nsTArray<nsCString> resIds = {"toolkit/global/cspErrors.ftl"_ns};
|
||||
RefPtr<intl::Localization> l10n = intl::Localization::Create(resIds, true);
|
||||
|
||||
auto l10nArgs = dom::Optional<intl::L10nArgs>();
|
||||
l10nArgs.Construct();
|
||||
|
||||
auto dirArg = l10nArgs.Value().Entries().AppendElement();
|
||||
dirArg->mKey = "directive";
|
||||
dirArg->mValue.SetValue().SetAsUTF8String().Assign(
|
||||
NS_ConvertUTF16toUTF8(mDirective));
|
||||
|
||||
if (!aKey.IsEmpty()) {
|
||||
auto optArg = l10nArgs.Value().Entries().AppendElement();
|
||||
optArg->mKey = aKey;
|
||||
optArg->mValue.SetValue().SetAsUTF8String().Assign(
|
||||
NS_ConvertUTF16toUTF8(aValue));
|
||||
}
|
||||
|
||||
nsAutoCString translation;
|
||||
IgnoredErrorResult rv;
|
||||
l10n->FormatValueSync(l10nId, l10nArgs, translation, rv);
|
||||
if (rv.Failed()) {
|
||||
mError.AssignLiteral("An unexpected error occurred");
|
||||
} else {
|
||||
mError = NS_ConvertUTF8toUTF16(translation);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
@ -342,34 +368,6 @@ class CSPValidator final : public nsCSPSrcVisitor {
|
||||
return false;
|
||||
};
|
||||
|
||||
// Formatters
|
||||
|
||||
already_AddRefed<nsIStringBundle> GetStringBundle() {
|
||||
nsCOMPtr<nsIStringBundleService> sbs =
|
||||
mozilla::components::StringBundle::Service();
|
||||
NS_ENSURE_TRUE(sbs, nullptr);
|
||||
|
||||
nsCOMPtr<nsIStringBundle> stringBundle;
|
||||
sbs->CreateBundle("chrome://global/locale/extensions.properties",
|
||||
getter_AddRefs(stringBundle));
|
||||
|
||||
return stringBundle.forget();
|
||||
};
|
||||
|
||||
void FormatErrorParams(const char* aName, const nsTArray<nsString>& aParams) {
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIStringBundle> stringBundle = GetStringBundle();
|
||||
|
||||
if (stringBundle) {
|
||||
rv = stringBundle->FormatStringFromName(aName, aParams, mError);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mError.AssignLiteral("An unexpected error occurred");
|
||||
}
|
||||
};
|
||||
|
||||
// Data members
|
||||
|
||||
nsAutoString mURL;
|
||||
@ -453,7 +451,8 @@ AddonContentPolicy::ValidateAddonCSP(const nsAString& aPolicyString,
|
||||
if (!policy->visitDirectiveSrcs(directive, &validator)) {
|
||||
aResult.Assign(validator.GetError());
|
||||
} else if (!validator.FoundSelf()) {
|
||||
validator.FormatError("csp.error.missing-source", u"'self'"_ns);
|
||||
validator.FormatError("csp-error-missing-source"_ns, "source"_ns,
|
||||
u"'self'"_ns);
|
||||
aResult.Assign(validator.GetError());
|
||||
}
|
||||
hasValidScriptSrc = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user