summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/general/browser_misused_characters_in_strings.js
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /browser/base/content/test/general/browser_misused_characters_in_strings.js
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'browser/base/content/test/general/browser_misused_characters_in_strings.js')
-rw-r--r--browser/base/content/test/general/browser_misused_characters_in_strings.js244
1 files changed, 244 insertions, 0 deletions
diff --git a/browser/base/content/test/general/browser_misused_characters_in_strings.js b/browser/base/content/test/general/browser_misused_characters_in_strings.js
new file mode 100644
index 000000000..fe8022662
--- /dev/null
+++ b/browser/base/content/test/general/browser_misused_characters_in_strings.js
@@ -0,0 +1,244 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/* This list allows pre-existing or 'unfixable' issues to remain, while we
+ * detect newly occurring issues in shipping files. It is a list of objects
+ * specifying conditions under which an error should be ignored.
+ *
+ * As each issue is found in the whitelist, it is removed from the list. At
+ * the end of the test, there is an assertion that all items have been
+ * removed from the whitelist, thus ensuring there are no stale entries. */
+let gWhitelist = [{
+ file: "search.properties",
+ key: "searchForSomethingWith",
+ type: "single-quote"
+ }, {
+ file: "netError.dtd",
+ key: "certerror.introPara",
+ type: "single-quote"
+ }, {
+ file: "netError.dtd",
+ key: "weakCryptoAdvanced.longDesc",
+ type: "single-quote"
+ }, {
+ file: "netError.dtd",
+ key: "weakCryptoAdvanced.override",
+ type: "single-quote"
+ }, {
+ file: "netError.dtd",
+ key: "inadequateSecurityError.longDesc",
+ type: "single-quote"
+ }, {
+ file: "netError.dtd",
+ key: "certerror.wrongSystemTime",
+ type: "single-quote"
+ }, {
+ file: "phishing-afterload-warning-message.dtd",
+ key: "safeb.blocked.malwarePage.shortDesc",
+ type: "single-quote"
+ }, {
+ file: "phishing-afterload-warning-message.dtd",
+ key: "safeb.blocked.unwantedPage.shortDesc",
+ type: "single-quote"
+ }, {
+ file: "phishing-afterload-warning-message.dtd",
+ key: "safeb.blocked.phishingPage.shortDesc2",
+ type: "single-quote"
+ }, {
+ file: "mathfont.properties",
+ key: "operator.\\u002E\\u002E\\u002E.postfix",
+ type: "ellipsis"
+ }, {
+ file: "layout_errors.properties",
+ key: "ImageMapRectBoundsError",
+ type: "double-quote"
+ }, {
+ file: "layout_errors.properties",
+ key: "ImageMapCircleWrongNumberOfCoords",
+ type: "double-quote"
+ }, {
+ file: "layout_errors.properties",
+ key: "ImageMapCircleNegativeRadius",
+ type: "double-quote"
+ }, {
+ file: "layout_errors.properties",
+ key: "ImageMapPolyWrongNumberOfCoords",
+ type: "double-quote"
+ }, {
+ file: "layout_errors.properties",
+ key: "ImageMapPolyOddNumberOfCoords",
+ type: "double-quote"
+ }, {
+ file: "xbl.properties",
+ key: "CommandNotInChrome",
+ type: "double-quote"
+ }, {
+ file: "dom.properties",
+ key: "PatternAttributeCompileFailure",
+ type: "single-quote"
+ }, {
+ file: "pipnss.properties",
+ key: "certErrorMismatchSingle2",
+ type: "double-quote"
+ }, {
+ file: "pipnss.properties",
+ key: "certErrorCodePrefix2",
+ type: "double-quote"
+ }, {
+ file: "aboutSupport.dtd",
+ key: "aboutSupport.pageSubtitle",
+ type: "single-quote"
+ }, {
+ file: "aboutSupport.dtd",
+ key: "aboutSupport.userJSDescription",
+ type: "single-quote"
+ }, {
+ file: "netError.dtd",
+ key: "inadequateSecurityError.longDesc",
+ type: "single-quote"
+ }, {
+ file: "netErrorApp.dtd",
+ key: "securityOverride.warningContent",
+ type: "single-quote"
+ }, {
+ file: "pocket.properties",
+ key: "tos",
+ type: "double-quote"
+ }, {
+ file: "pocket.properties",
+ key: "tos",
+ type: "apostrophe"
+ }, {
+ file: "aboutNetworking.dtd",
+ key: "aboutNetworking.logTutorial",
+ type: "single-quote"
+ }
+];
+
+var moduleLocation = gTestPath.replace(/\/[^\/]*$/i, "/parsingTestHelpers.jsm");
+var {generateURIsFromDirTree} = Cu.import(moduleLocation, {});
+
+/**
+ * Check if an error should be ignored due to matching one of the whitelist
+ * objects defined in gWhitelist.
+ *
+ * @param filepath The URI spec of the locale file
+ * @param key The key of the entity that is being checked
+ * @param type The type of error that has been found
+ * @return true if the error should be ignored, false otherwise.
+ */
+function ignoredError(filepath, key, type) {
+ for (let index in gWhitelist) {
+ let whitelistItem = gWhitelist[index];
+ if (filepath.endsWith(whitelistItem.file) &&
+ key == whitelistItem.key &&
+ type == whitelistItem.type) {
+ gWhitelist.splice(index, 1);
+ return true;
+ }
+ }
+ return false;
+}
+
+function fetchFile(uri) {
+ return new Promise((resolve, reject) => {
+ let xhr = new XMLHttpRequest();
+ xhr.open("GET", uri, true);
+ xhr.onreadystatechange = function() {
+ if (this.readyState != this.DONE) {
+ return;
+ }
+ try {
+ resolve(this.responseText);
+ } catch (ex) {
+ ok(false, `Script error reading ${uri}: ${ex}`);
+ resolve("");
+ }
+ };
+ xhr.onerror = error => {
+ ok(false, `XHR error reading ${uri}: ${error}`);
+ resolve("");
+ };
+ xhr.send(null);
+ });
+}
+
+function testForError(filepath, key, str, pattern, type, helpText) {
+ if (str.match(pattern) &&
+ !ignoredError(filepath, key, type)) {
+ ok(false, `${filepath} with key=${key} has a misused ${type}. ${helpText}`);
+ }
+}
+
+function testForErrors(filepath, key, str) {
+ testForError(filepath, key, str, /\w'\w/, "apostrophe", "Strings with apostrophes should use foo\u2019s instead of foo's.");
+ testForError(filepath, key, str, /\w\u2018\w/, "incorrect-apostrophe", "Strings with apostrophes should use foo\u2019s instead of foo\u2018s.");
+ testForError(filepath, key, str, /'.+'/, "single-quote", "Single-quoted strings should use Unicode \u2018foo\u2019 instead of 'foo'.");
+ testForError(filepath, key, str, /"/, "double-quote", "Double-quoted strings should use Unicode \u201cfoo\u201d instead of \"foo\".");
+ testForError(filepath, key, str, /\.\.\./, "ellipsis", "Strings with an ellipsis should use the Unicode \u2026 character instead of three periods.");
+}
+
+function* getAllTheFiles(extension) {
+ let appDirGreD = Services.dirsvc.get("GreD", Ci.nsIFile);
+ let appDirXCurProcD = Services.dirsvc.get("XCurProcD", Ci.nsIFile);
+ if (appDirGreD.contains(appDirXCurProcD)) {
+ return yield generateURIsFromDirTree(appDirGreD, [extension]);
+ }
+ if (appDirXCurProcD.contains(appDirGreD)) {
+ return yield generateURIsFromDirTree(appDirXCurProcD, [extension]);
+ }
+ let urisGreD = yield generateURIsFromDirTree(appDirGreD, [extension]);
+ let urisXCurProcD = yield generateURIsFromDirTree(appDirXCurProcD, [extension]);
+ return Array.from(new Set(urisGreD.concat(appDirXCurProcD)));
+}
+
+add_task(function* checkAllTheProperties() {
+ // This asynchronously produces a list of URLs (sadly, mostly sync on our
+ // test infrastructure because it runs against jarfiles there, and
+ // our zipreader APIs are all sync)
+ let uris = yield getAllTheFiles(".properties");
+ ok(uris.length, `Found ${uris.length} .properties files to scan for misused characters`);
+
+ for (let uri of uris) {
+ let bundle = new StringBundle(uri.spec);
+ let entities = bundle.getAll();
+ for (let entity of entities) {
+ testForErrors(uri.spec, entity.key, entity.value);
+ }
+ }
+});
+
+var checkDTD = Task.async(function* (aURISpec) {
+ let rawContents = yield fetchFile(aURISpec);
+ // The regular expression below is adapted from:
+ // https://hg.mozilla.org/mozilla-central/file/68c0b7d6f16ce5bb023e08050102b5f2fe4aacd8/python/compare-locales/compare_locales/parser.py#l233
+ let entities = rawContents.match(/<!ENTITY\s+([\w\.]*)\s+("[^"]*"|'[^']*')\s*>/g);
+ if (!entities) {
+ // Some files, such as requestAutocomplete.dtd, have no entities defined.
+ return;
+ }
+ for (let entity of entities) {
+ let [, key, str] = entity.match(/<!ENTITY\s+([\w\.]*)\s+("[^"]*"|'[^']*')\s*>/);
+ // The matched string includes the enclosing quotation marks,
+ // we need to slice them off.
+ str = str.slice(1, -1);
+ testForErrors(aURISpec, key, str);
+ }
+});
+
+add_task(function* checkAllTheDTDs() {
+ let uris = yield getAllTheFiles(".dtd");
+ ok(uris.length, `Found ${uris.length} .dtd files to scan for misused characters`);
+ for (let uri of uris) {
+ yield checkDTD(uri.spec);
+ }
+
+ // This support DTD file supplies a string with a newline to make sure
+ // the regex in checkDTD works correctly for that case.
+ let dtdLocation = gTestPath.replace(/\/[^\/]*$/i, "/bug1262648_string_with_newlines.dtd");
+ yield checkDTD(dtdLocation);
+});
+
+add_task(function* ensureWhiteListIsEmpty() {
+ is(gWhitelist.length, 0, "No remaining whitelist entries exist");
+});