diff --git a/add-on/lib/proxyblock.js b/add-on/lib/proxyblock.js
index 2897879..74b7828 100644
--- a/add-on/lib/proxyblock.js
+++ b/add-on/lib/proxyblock.js
@@ -104,10 +104,22 @@
}
};
+ // Every time the proxy has been called 1000 times, return
+ // undefined instead of the proxy object, to ensure that the
+ // proxy doesn't get stuck in an infinite loop.
+ let recursionGuardCounter = 0;
+
const blockingProxy = new Proxy(defaultFunction, {
get: function (ignore, property) {
logKeyPath();
+ if (recursionGuardCounter === 1000) {
+ recursionGuardCounter = 0;
+ return undefined;
+ }
+
+ recursionGuardCounter += 1;
+
if (property === Symbol.toPrimitive) {
return toPrimitiveFunc;
}
diff --git a/gulpfile.js b/gulpfile.js
index 4a5e271..b32caea 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -15,7 +15,13 @@ gulp.task("default", function () {
}
const fileContents = fs.readFileSync(standardsDefDir + "/" + next, {encoding: "utf8"});
- const standardContents = JSON.parse(fileContents);
+ let standardContents;
+ try {
+ standardContents = JSON.parse(fileContents);
+ } catch (e) {
+ console.log("Invalid JSON in " + next);
+ throw e;
+ }
const stdName = standardContents.info.name;
const stdSubName = standardContents.info.subsection_name;
diff --git a/package.json b/package.json
index 93111f4..ef82442 100644
--- a/package.json
+++ b/package.json
@@ -26,8 +26,9 @@
"firefox": "web-ext -s add-on run",
"lint": "node_modules/eslint/bin/eslint.js .",
"lint:fix": "node_modules/eslint/bin/eslint.js --fix .",
- "test": "npm run clean; npm run bundle && ln -s `ls dist/` dist/webapi_manager.zip && cross-env node_modules/mocha/bin/mocha test/functional/*.js",
- "test:watch": "cross-env npm test --watch"
+ "test": "npm run clean; npm run bundle && ln -s `ls dist/` dist/webapi_manager.zip && cross-env node_modules/mocha/bin/mocha test/functional/*.js --only-local-tests",
+ "test:watch": "cross-env npm test --watch",
+ "test:all": "npm run clean; npm run bundle && ln -s `ls dist/` dist/webapi_manager.zip && cross-env node_modules/mocha/bin/mocha test/functional/*.js"
},
"pre-push": {
"run": [
diff --git a/test/fixtures/infinite-loop.html b/test/fixtures/infinite-loop.html
new file mode 100644
index 0000000..3ce4482
--- /dev/null
+++ b/test/fixtures/infinite-loop.html
@@ -0,0 +1,32 @@
+
+
+
+
+ Testing Infinite Loop Case
+
+
+
+
+
+
+
diff --git a/test/functional/block.js b/test/functional/block.js
index 1ac15df..c16ac36 100644
--- a/test/functional/block.js
+++ b/test/functional/block.js
@@ -3,6 +3,9 @@
const utils = require("./lib/utils");
const injected = require("./lib/injected");
const testServer = require("./lib/server");
+const webdriver = require("selenium-webdriver");
+const by = webdriver.By;
+const until = webdriver.until;
describe("Basic Functionality", function () {
@@ -27,7 +30,7 @@ describe("Basic Functionality", function () {
testUrl = url;
httpServer = server;
-
+
const standardsToBlock = [];
let driverReference;
@@ -54,10 +57,8 @@ describe("Basic Functionality", function () {
it("SVG blocking", function (done) {
- this.timeout = function () {
- return 10000;
- };
-
+ this.timeout = () => 10000;
+
const [server, url] = testServer.start();
testUrl = url;
@@ -84,5 +85,34 @@ describe("Basic Functionality", function () {
done(e);
});
});
+
+ it("Proxyblock does not get stuck in infinite loop", function (done) {
+
+ const [server, url] = testServer.startWithFile("infinite-loop.html");
+
+ testUrl = url;
+ httpServer = server;
+
+ const standardsToBlock = ["Selectors API Level 1"];
+ let driverReference;
+
+ utils.promiseGetDriver()
+ .then(function (driver) {
+ driverReference = driver;
+ return utils.promiseSetBlockingRules(driver, standardsToBlock);
+ })
+ .then(() => driverReference.get(testUrl))
+ .then(() => driverReference.wait(until.elementLocated(by.css("div.success-case")), 2000))
+ .then(function () {
+ driverReference.quit();
+ testServer.stop(httpServer);
+ done();
+ })
+ .catch(function (e) {
+ driverReference.quit();
+ testServer.stop(httpServer);
+ done(e);
+ });
+ });
});
});
diff --git a/test/functional/lib/server.js b/test/functional/lib/server.js
index ada3a23..04ee324 100644
--- a/test/functional/lib/server.js
+++ b/test/functional/lib/server.js
@@ -1,5 +1,7 @@
"use strict";
+const path = require("path");
+const fs = require("fs");
const http = require("http");
const testPort = 8989;
@@ -34,6 +36,27 @@ module.exports.start = function (callback, html) {
return [httpServer, testUrl];
};
+/**
+ * Starts the test server, serving the provided html file from the fixtures dir.
+ *
+ * @param {string} testHtmlFileName
+ * The name of the fixture file the test server should serve.
+ * @param {function|undefined} callback
+ * An optional callback function that, if provided, will be called with
+ * a single argument, an object describing which headers will be sent from
+ * the server. The callback function can modify this as needed.
+ *
+ * @return {array}
+ * An array of length two. The first item is the server object, and the
+ * second item is the absolute URL that the server is serving from.
+ */
+module.exports.startWithFile = function (testHtmlFileName, callback) {
+
+ const pathToTestHtmlFileName = path.join(__dirname, "..", "..", "fixtures", testHtmlFileName);
+ const htmlFileContents = fs.readFileSync(pathToTestHtmlFileName, "utf8");
+ return module.exports.start(callback, htmlFileContents);
+};
+
module.exports.stop = function (server) {
server.close();
};
diff --git a/test/functional/lib/utils.js b/test/functional/lib/utils.js
index 972a0e1..8de98f9 100644
--- a/test/functional/lib/utils.js
+++ b/test/functional/lib/utils.js
@@ -5,14 +5,16 @@
require("geckodriver");
const firefox = require("selenium-webdriver/firefox");
-const webdriver = require("selenium-webdriver");
const injectedScripts = require("./injected");
-const by = webdriver.By;
const Context = firefox.Context;
+const webdriver = require("selenium-webdriver");
+const by = webdriver.By;
const until = webdriver.until;
const keys = webdriver.Key;
const path = require("path");
+module.exports.shouldRunRemoteTests = process.argv.indexOf("--only-local-tests") === -1;
+
module.exports.constants = {
svgBlockRule: ["Scalable Vector Graphics (SVG) 1.1 (Second Edition)"]
};
diff --git a/test/functional/logins.js b/test/functional/logins.js
index bbcdb3a..ca4c804 100644
--- a/test/functional/logins.js
+++ b/test/functional/logins.js
@@ -13,8 +13,14 @@ const keys = webdriver.Key;
const by = webdriver.By;
const until = webdriver.until;
+
describe("Logging into popular sites", function () {
+ if (utils.shouldRunRemoteTests === false) {
+ // Skipping remote tests because of --only-local-tests flag
+ return;
+ }
+
describe("GitHub", function () {
if (!testParams.github.username) {