From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- .../browser_misused_characters_in_strings.js | 244 +++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 browser/base/content/test/general/browser_misused_characters_in_strings.js (limited to 'browser/base/content/test/general/browser_misused_characters_in_strings.js') 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(//g); + if (!entities) { + // Some files, such as requestAutocomplete.dtd, have no entities defined. + return; + } + for (let entity of entities) { + let [, key, str] = entity.match(//); + // 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"); +}); -- cgit v1.2.3