From 4f45ea248fc484e02d7ab9d6627bcc879fce49bd Mon Sep 17 00:00:00 2001 From: dimi Date: Thu, 21 Jul 2016 15:40:03 +0800 Subject: [PATCH] Bug 1272239 - Part 3: Testcase, test gethash. r=francois MozReview-Commit-ID: 3IkrdJgZNP1 --- .../url-classifier/tests/mochitest/bad.css | 1 + .../tests/mochitest/classifierFrame.html | 11 +- .../tests/mochitest/classifierHelper.js | 34 ++++ .../tests/mochitest/gethash.sjs | 119 ++++++++++++++ .../tests/mochitest/gethashFrame.html | 62 ++++++++ .../url-classifier/tests/mochitest/import.css | 6 +- .../tests/mochitest/mochitest.ini | 4 + .../tests/mochitest/test_gethash.html | 150 ++++++++++++++++++ 8 files changed, 383 insertions(+), 4 deletions(-) create mode 100644 toolkit/components/url-classifier/tests/mochitest/bad.css create mode 100644 toolkit/components/url-classifier/tests/mochitest/gethash.sjs create mode 100644 toolkit/components/url-classifier/tests/mochitest/gethashFrame.html create mode 100644 toolkit/components/url-classifier/tests/mochitest/test_gethash.html diff --git a/toolkit/components/url-classifier/tests/mochitest/bad.css b/toolkit/components/url-classifier/tests/mochitest/bad.css new file mode 100644 index 000000000000..f57b36a77845 --- /dev/null +++ b/toolkit/components/url-classifier/tests/mochitest/bad.css @@ -0,0 +1 @@ +#styleBad { visibility: hidden; } diff --git a/toolkit/components/url-classifier/tests/mochitest/classifierFrame.html b/toolkit/components/url-classifier/tests/mochitest/classifierFrame.html index 1cd520284779..c7923f448411 100644 --- a/toolkit/components/url-classifier/tests/mochitest/classifierFrame.html +++ b/toolkit/components/url-classifier/tests/mochitest/classifierFrame.html @@ -15,6 +15,14 @@ function checkLoads() { var style = document.defaultView.getComputedStyle(elt, ""); window.parent.isnot(style.visibility, "hidden", "Should not load bad css"); + elt = document.getElementById("styleBad"); + style = document.defaultView.getComputedStyle(elt, ""); + window.parent.isnot(style.visibility, "hidden", "Should not load bad css"); + + elt = document.getElementById("styleImport"); + style = document.defaultView.getComputedStyle(elt, ""); + window.parent.isnot(style.visibility, "visible", "Should import clean css"); + // Call parent.loadTestFrame again to test classification metadata in HTTP // cache entries. if (window.parent.firstLoad) { @@ -36,7 +44,6 @@ function checkLoads() { - @@ -44,5 +51,7 @@ function checkLoads() { The following should not be hidden:
STYLE TEST
+
STYLE BAD
+
STYLE IMPORT
diff --git a/toolkit/components/url-classifier/tests/mochitest/classifierHelper.js b/toolkit/components/url-classifier/tests/mochitest/classifierHelper.js index fe025fb4114b..b70539838802 100644 --- a/toolkit/components/url-classifier/tests/mochitest/classifierHelper.js +++ b/toolkit/components/url-classifier/tests/mochitest/classifierHelper.js @@ -9,6 +9,12 @@ const ADD_CHUNKNUM = 524; const SUB_CHUNKNUM = 523; const HASHLEN = 32; +const PREFS = { + PROVIDER_LISTS : "browser.safebrowsing.provider.mozilla.lists", + DISALLOW_COMPLETIONS : "urlclassifier.disallow_completions", + PROVIDER_GETHASHURL : "browser.safebrowsing.provider.mozilla.gethashURL" +}; + // addUrlToDB & removeUrlFromDB are asynchronous, queue the task to ensure // the callback follow correct order. classifierHelper._updates = []; @@ -17,6 +23,27 @@ classifierHelper._updates = []; // removed after test complete. classifierHelper._updatesToCleanup = []; +// This function is used to allow completion for specific "list", +// some lists like "test-malware-simple" is default disabled to ask for complete. +// "list" is the db we would like to allow it +// "url" is the completion server +classifierHelper.allowCompletion = function(lists, url) { + for (var list of lists) { + // Add test db to provider + var pref = SpecialPowers.getCharPref(PREFS.PROVIDER_LISTS); + pref += "," + list; + SpecialPowers.setCharPref(PREFS.PROVIDER_LISTS, pref); + + // Rename test db so we will not disallow it from completions + pref = SpecialPowers.getCharPref(PREFS.DISALLOW_COMPLETIONS); + pref = pref.replace(list, list + "-backup"); + SpecialPowers.setCharPref(PREFS.DISALLOW_COMPLETIONS, pref); + } + + // Set get hash url + SpecialPowers.setCharPref(PREFS.PROVIDER_GETHASHURL, url); +} + // Pass { url: ..., db: ... } to add url to database, // onsuccess/onerror will be called when update complete. classifierHelper.addUrlToDB = function(updateData) { @@ -26,6 +53,7 @@ classifierHelper.addUrlToDB = function(updateData) { var LISTNAME = update.db; var CHUNKDATA = update.url; var CHUNKLEN = CHUNKDATA.length; + var HASHLEN = update.len ? update.len : 32; classifierHelper._updatesToCleanup.push(update); testUpdate += @@ -49,6 +77,7 @@ classifierHelper.removeUrlFromDB = function(updateData) { var LISTNAME = update.db; var CHUNKDATA = ADD_CHUNKNUM + ":" + update.url; var CHUNKLEN = CHUNKDATA.length; + var HASHLEN = update.len ? update.len : 32; testUpdate += "n:1000\n" + @@ -127,6 +156,11 @@ classifierHelper._setup = function() { }; classifierHelper._cleanup = function() { + // clean all the preferences may touch by helper + for (var pref in PREFS) { + SpecialPowers.clearUserPref(pref); + } + if (!classifierHelper._updatesToCleanup) { return Promise.resolve(); } diff --git a/toolkit/components/url-classifier/tests/mochitest/gethash.sjs b/toolkit/components/url-classifier/tests/mochitest/gethash.sjs new file mode 100644 index 000000000000..47f409bd5b8e --- /dev/null +++ b/toolkit/components/url-classifier/tests/mochitest/gethash.sjs @@ -0,0 +1,119 @@ +const CC = Components.Constructor; +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream"); + +function handleRequest(request, response) +{ + var query = {}; + request.queryString.split('&').forEach(function (val) { + var idx = val.indexOf('='); + query[val.slice(0, idx)] = unescape(val.slice(idx + 1)); + }); + + // Store fullhash in the server side. + if ("list" in query && "fullhash" in query) { + // In the server side we will store: + // 1. All the full hashes for a given list + // 2. All the lists we have right now + // data is separate by '\n' + let list = query["list"]; + let hashes = getState(list); + + let hash = base64ToString(query["fullhash"]); + hashes += hash + "\n"; + setState(list, hashes); + + let lists = getState("lists"); + if (lists.indexOf(list) == -1) { + lists += list + "\n"; + setState("lists", lists); + } + + return; + } + + var body = new BinaryInputStream(request.bodyInputStream); + var avail; + var bytes = []; + + while ((avail = body.available()) > 0) { + Array.prototype.push.apply(bytes, body.readByteArray(avail)); + } + + var responseBody = parseV2Request(bytes); + + response.setHeader("Content-Type", "text/plain", false); + response.write(responseBody); + +} + +function parseV2Request(bytes) { + var request = String.fromCharCode.apply(this, bytes); + var [HEADER, PREFIXES] = request.split("\n"); + var [PREFIXSIZE, LENGTH] = HEADER.split(":").map(val => { + return parseInt(val); + }); + + var ret = ""; + for(var start = 0; start < LENGTH; start += PREFIXSIZE) { + getState("lists").split("\n").forEach(function(list) { + var completions = getState(list).split("\n"); + + for (var completion of completions) { + if (completion.indexOf(PREFIXES.substr(start, PREFIXSIZE)) == 0) { + ret += list + ":" + "1" + ":" + "32" + "\n"; + ret += completion; + } + } + }); + } + + return ret; +} + +/* Convert Base64 data to a string */ +const toBinaryTable = [ + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +]; +const base64Pad = '='; + +function base64ToString(data) { + var result = ''; + var leftbits = 0; // number of bits decoded, but yet to be appended + var leftdata = 0; // bits decoded, but yet to be appended + + // Convert one by one. + for (var i = 0; i < data.length; i++) { + var c = toBinaryTable[data.charCodeAt(i) & 0x7f]; + var padding = (data[i] == base64Pad); + // Skip illegal characters and whitespace + if (c == -1) continue; + + // Collect data into leftdata, update bitcount + leftdata = (leftdata << 6) | c; + leftbits += 6; + + // If we have 8 or more bits, append 8 bits to the result + if (leftbits >= 8) { + leftbits -= 8; + // Append if not padding. + if (!padding) + result += String.fromCharCode((leftdata >> leftbits) & 0xff); + leftdata &= (1 << leftbits) - 1; + } + } + + // If there are any bits left, the base64 string was corrupted + if (leftbits) + throw Components.Exception('Corrupted base64 string'); + + return result; +} diff --git a/toolkit/components/url-classifier/tests/mochitest/gethashFrame.html b/toolkit/components/url-classifier/tests/mochitest/gethashFrame.html new file mode 100644 index 000000000000..560ddcde6ea2 --- /dev/null +++ b/toolkit/components/url-classifier/tests/mochitest/gethashFrame.html @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + +
+
STYLE EVIL
+
STYLE BAD
+
STYLE IMPORT
+ + diff --git a/toolkit/components/url-classifier/tests/mochitest/import.css b/toolkit/components/url-classifier/tests/mochitest/import.css index 4b5803a0a385..9b86c8216907 100644 --- a/toolkit/components/url-classifier/tests/mochitest/import.css +++ b/toolkit/components/url-classifier/tests/mochitest/import.css @@ -1,3 +1,3 @@ -/* malware.example.com is in the malware database. - classifierBad.css does not actually exist. */ -@import url("http://malware.example.com/tests/docshell/test/classifierBad.css"); +/* malware.example.com is in the malware database. */ +@import url("http://malware.example.com/tests/toolkit/components/url-classifier/tests/mochitest/bad.css"); +#styleImport { visibility: hidden; } diff --git a/toolkit/components/url-classifier/tests/mochitest/mochitest.ini b/toolkit/components/url-classifier/tests/mochitest/mochitest.ini index 6eaca54bf9c4..b9c4005911a4 100644 --- a/toolkit/components/url-classifier/tests/mochitest/mochitest.ini +++ b/toolkit/components/url-classifier/tests/mochitest/mochitest.ini @@ -23,9 +23,13 @@ support-files = dnt.html dnt.sjs update.sjs + bad.css + gethash.sjs + gethashFrame.html [test_classifier.html] skip-if = (os == 'linux' && debug) #Bug 1199778 [test_classifier_worker.html] [test_classify_ping.html] [test_classify_track.html] +[test_gethash.html] diff --git a/toolkit/components/url-classifier/tests/mochitest/test_gethash.html b/toolkit/components/url-classifier/tests/mochitest/test_gethash.html new file mode 100644 index 000000000000..93e7d40a470a --- /dev/null +++ b/toolkit/components/url-classifier/tests/mochitest/test_gethash.html @@ -0,0 +1,150 @@ + + + + Bug 1272239 - Test gethash. + + + + + + +

+ +
+
+
+
+
+
+ +