aboutsummaryrefslogtreecommitdiffstats
path: root/lib/js_checker/free_checker.js
diff options
context:
space:
mode:
authorNik Nyby <nikolas@gnu.org>2015-01-17 17:12:36 -0500
committerNik Nyby <nikolas@gnu.org>2015-01-17 17:12:36 -0500
commitada88090ead2c3b9d0804794c5f20f9b24d1c2b1 (patch)
tree2838a7eee6c5d74094216acebd86915e0ea1de42 /lib/js_checker/free_checker.js
downloadlibrejsxul-ada88090ead2c3b9d0804794c5f20f9b24d1c2b1.tar.lz
librejsxul-ada88090ead2c3b9d0804794c5f20f9b24d1c2b1.tar.xz
librejsxul-ada88090ead2c3b9d0804794c5f20f9b24d1c2b1.zip
Import to new git repository
The old repository was using almost 100mb of space because of all the unnecessary files in the history. So I've imported the code to a new git repository. Unfortunately the history isn't viewable from this repository anymore. To see what happened with LibreJS before 2015, see the old Bazaar repo here: http://bzr.savannah.gnu.org/lh/librejs/
Diffstat (limited to 'lib/js_checker/free_checker.js')
-rw-r--r--lib/js_checker/free_checker.js231
1 files changed, 231 insertions, 0 deletions
diff --git a/lib/js_checker/free_checker.js b/lib/js_checker/free_checker.js
new file mode 100644
index 0000000..9aaa262
--- /dev/null
+++ b/lib/js_checker/free_checker.js
@@ -0,0 +1,231 @@
+/**
+ * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript.
+ * *
+ * Copyright (C) 2011, 2012, 2013, 2014 Loic J. Duros
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+var licenses = require('js_checker/license_definitions');
+var simpleStorage = require("sdk/simple-storage");
+const LAZY = licenses.types.LAZY;
+var licenseRegex = [];
+const END_OF_SCRIPT = require('html_script_finder/bug_fix').END_OF_SCRIPT;
+const types = require("js_checker/constant_types");
+
+const token = types.token;
+
+var patternUtils = require('js_checker/pattern_utils').patternUtils;
+
+var licStartLicEndRe = /@licstartThefollowingistheentirelicensenoticefortheJavaScriptcodeinthis(?:page|file)(.*)?@licendTheaboveistheentirelicensenoticefortheJavaScriptcodeinthis(?:page|file)/mi;
+var licenseMagnet = /.*@license ?(magnet\:\?xt=urn\:btih\:[0-9A-Za-z]+).*/;
+var licenseEndMagnet = /.*@license-end.*/i;
+exports.freeCheck = {
+ initLicenses: function (licenses) {
+ for (var item in licenses) {
+ this.stripLicenseToRegexp(licenses[item]);
+ }
+ },
+
+ /**
+ * stripLicenseToRegexp
+ *
+ * Removes all non-alphanumeric characters except for the
+ * special tokens, and replace the text values that are
+ * hardcoded in license_definitions.js
+ *
+ */
+ stripLicenseToRegexp: function (license) {
+ var i = 0,
+ max = license.licenseFragments.length,
+ item;
+
+ for (; i < max; i++) {
+ item = license.licenseFragments[i];
+ item.regex = patternUtils.removeNonalpha(item.text);
+
+ if (license.licenseFragments[i].type === LAZY) {
+
+ // do not permit words before. Since "Not" could be added
+ // and make it nonfree. e.g.: Not licensed under the GPLv3.
+ item.regex = '^(?!.*not).*' + item.regex;
+
+ }
+
+ item.regex = new RegExp(
+ patternUtils.replaceTokens(item.regex), 'i');
+ }
+
+ return license;
+ },
+
+ /**
+ * checkNodeFreeLicense
+ *
+ * Check if the node mentions a free license
+ * in one of its comments.
+ *
+ */
+ checkNodeFreeLicense: function (n, queue) {
+ var strippedComment,
+ magnetLink,
+ comment = this.getComment(n),
+ list = licenses.licenses,
+ i, j,
+ max,
+ regex,
+ frag,
+ matchLicStart,
+ matchMagnet,
+ license,
+ isMagnetValid = false;
+
+ if (n.counter === 2 &&
+ n.parent != undefined &&
+ n.parent.type === token.SCRIPT &&
+ comment != undefined &&
+ comment != " "
+ ) {
+ strippedComment = patternUtils.removeNonalpha(comment);
+ matchLicStart = strippedComment.match(licStartLicEndRe);
+ console.debug("matchMagnet is", matchMagnet);
+ if (matchLicStart) {
+ strippedComment = matchLicStart[1];
+ for (license in list) {
+ frag = list[license].licenseFragments;
+ max = list[license].licenseFragments.length;
+ for (i = 0; i < max; i++) {
+ if (frag[i].regex.test(strippedComment)) {
+ return {
+ licenseName: list[license].licenseName,
+ type: types.checkTypes.FREE
+ };
+
+ }
+ }
+ }
+ }
+ // check for @license -- @license-end notation.
+ return this.matchMagnet(comment, queue);
+ }
+ },
+
+ /**
+ * matchMagnet
+ * Attempts to find valid @license [magnet]
+ * and @license-end notation.
+ */
+ matchMagnet: function (comment, queue) {
+ let matchMagnet = comment.match(licenseMagnet);
+ if (matchMagnet) {
+ let magnetLinkRe = new RegExp(
+ matchMagnet[1].replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
+ );
+ let list = licenses.licenses;
+ let queue_end = queue.length;
+
+ for (var license in list) {
+ frag = list[license].canonicalUrl;
+ console.debug("frag is ", frag);
+ if (frag != undefined) {
+ max = list[license].canonicalUrl.length;
+ console.debug("max is", max);
+ for (i = 0;i < max; i++) {
+ console.debug("current frag is", frag[i]);
+ if (frag[i].match(magnetLinkRe)) {
+ for (let i = 0; i < queue_end; i++) {
+ console.debug(queue[i]);
+ let n = queue[i];
+ comment = this.getComment(n);
+ if (comment != undefined &&
+ comment.match(licenseEndMagnet) &&
+ this.checkIsLastNode(n)
+ ) {
+ // found a closing match. Just accept this script.
+ return {
+ licenseName: list[license].licenseName,
+ type: types.checkTypes.FREE_SINGLE_ITEM
+ };
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return;
+ },
+
+ /**
+ * checkIsLastJsNode.
+ * returns true if n is the last node.
+ * Or if nodes before it are only comments etc (not valid code.)
+ * A special LibreJS node is appended at the end of a script tree to
+ * check if this is the last (and also for narcissus to keep the last comment
+ * in the tree.)
+ * TODO: Refactor LibreJS so that END nodes can have a comment.
+ */
+ checkIsLastNode: function (n) {
+ // first check if the comment is part of the very last statement.
+ if (n.value == "this" && n.next == undefined) {
+ // just make sure the last node is indeed our harmless bit of
+ // js.
+ if (n.tokenizer) {
+ let source = n.tokenizer.source;
+ let substring = source.substr(n.start, n.end+23);
+ if (substring == END_OF_SCRIPT) {
+ return true;
+ }
+ else {
+ console.debug("substring is ", substring);
+ return false;
+ }
+ }
+ console.debug("Hurra! This is the end of our script");
+ return true;
+ }
+
+ // isn't our last node.
+ return false;
+ },
+
+ /**
+ * getComment
+ *
+ * Grab the comment(s) from the node. Concatenates
+ * multiple comments.
+ *
+ */
+ getComment: function (n) {
+ var i = 0, length, comment = "";
+
+ if (n.blockComments == undefined || n.blockComments == " ") {
+ return;
+ }
+
+ length = n.blockComments.length;
+ if (length > 0) {
+ for (; i < length; i++) {
+ comment += n.blockComments[i];
+ }
+ }
+ if (comment == "") {
+ return;
+ }
+ return comment;
+ }
+};
+
+exports.freeCheck.initLicenses(licenses.licenses);