From 6c7f05852fbcb64f9f18e2220fd3bf1f6c5ae710 Mon Sep 17 00:00:00 2001
From: hackademix <giorgio@maone.net>
Date: Sep 24 2018 22:01:14 +0000
Subject: Match WebLabels by label rather than by canonical URL.


---

diff --git a/bg/ExternalLicenses.js b/bg/ExternalLicenses.js
index 0b2c911..27d9223 100644
--- a/bg/ExternalLicenses.js
+++ b/bg/ExternalLicenses.js
@@ -25,13 +25,11 @@
 
 "use strict";
 
-let licensesByURL = new Map();
+let licensesByLabel = new Map();
 {
   let {licenses} = require("../license_definitions");
-  for (let l of Object.values(licenses).filter(l => l.canonicalUrl)) {
-    for (let url of l.canonicalUrl) {
-      licensesByURL.set(url, l);
-    }
+  for (let l of Object.values(licenses).filter(l => l.identifier)) {
+    licensesByLabel.set(l.identifier, l);
   }
 }
 
@@ -41,7 +39,7 @@ var ExternalLicenses = {
   purgeCache(tabId) {
     cachedHrefs.delete(tabId);
   },
-  
+
   async check(script) {
     let {url, tabId, frameId, documentUrl} = script;
     let tabCache = cachedHrefs.get(tabId);
@@ -52,20 +50,23 @@ var ExternalLicenses = {
       url,
       cache,
     }, {frameId});
-    
-    if (!(scriptInfo && scriptInfo.licenseURLs.length)) {
+
+    if (!(scriptInfo && scriptInfo.licenseLinks.length)) {
       return null;
     }
     scriptInfo.licenses = new Set();
     scriptInfo.allFree = true;
     scriptInfo.toString = function() {
       let licenseIds = [...this.licenses].map(l => l.identifier).sort().join(", ");
-      return this.allFree ? `Free license${licenseIds.length > 1 ? "s" : ""} (${licenseIds})` : `Mixed free (${licenseIds}) and unknown licenses`;
+      return licenseIds
+         ? (this.allFree ? `Free license${this.licenses.length > 1 ? "s" : ""} (${licenseIds})`
+                         : `Mixed free (${licenseIds}) and unknown licenses`)
+         : "Unknown license(s)";
     }
-    
-    for (let u of scriptInfo.licenseURLs) {
-      if (licensesByURL.has(u)) {
-        scriptInfo.licenses.add(licensesByURL.get(u));
+
+    for (let {label} of scriptInfo.licenseLinks) {
+      if (licensesByLabel.has(label)) {
+        scriptInfo.licenses.add(licensesByLabel.get(label));
       } else {
         scriptInfo.allFree = false;
         break;
@@ -73,7 +74,7 @@ var ExternalLicenses = {
     }
     return scriptInfo;
   },
-  
+
   /**
   * moves / creates external license references before any script in the page
   * if needed, to have them ready when the first script load is triggered.
@@ -89,7 +90,7 @@ var ExternalLicenses = {
       cachedHrefs.set(tabId, frameCache = new Map());
     }
     frameCache.set(frameId, new Map([[documentUrl, cache]]));
-    
+
     let link = document.querySelector(`link[rel="jslicense"], link[data-jslicense="1"], a[rel="jslicense"], a[data-jslicense="1"]`);
     if (link) {
       let href = link.getAttribute("href");
@@ -111,7 +112,7 @@ var ExternalLicenses = {
         return move();
       }
     }
-    
+
     return false;
   }
 };
diff --git a/content/externalLicenseChecker.js b/content/externalLicenseChecker.js
index be09ef1..181e3f9 100644
--- a/content/externalLicenseChecker.js
+++ b/content/externalLicenseChecker.js
@@ -21,7 +21,7 @@
 "use strict";
 {
   let licensedScripts = null;
-    
+
   let fetchWebLabels = async args => {
     // see https://www.gnu.org/software/librejs/free-your-javascript.html#step3
     let {map, cache} = args;
@@ -40,26 +40,31 @@
       } else {
         doc.head.appendChild(doc.createElement("base")).href = baseURL;
       }
-      let firstURL = parent => parent.querySelector("a").href;
-      let allURLs = parent => Array.map(parent.querySelectorAll("a"), a => a.href);
-      for (let row of doc.querySelectorAll("table#jslicense-labels1 tr")) {
-        let cols = row.querySelectorAll("td");
-        let scriptURL = firstURL(cols[0]);
-        let licenseURLs = allURLs(cols[1]);
-        let sourceURLs = cols[2] ? allURLs(cols[2]) : [];
-        map.set(scriptURL, {scriptURL, licenseURLs, sourceURLs});
+      let link = a => ({ url: a.href, label: a.textContent });
+      let firstLink = parent => link(parent.querySelector("a"));
+      let allLinks = parent => Array.map(parent.querySelectorAll("a"), link);
+      for (let row of doc.querySelectorAll("table#jslicense-labels1 > tbody > tr")) {
+        try {
+          let cols = row.querySelectorAll("td");
+          let script = firstLink(cols[0]);
+          let licenseLinks = allLinks(cols[1]);
+          let sources = cols[2] ? allLinks(cols[2]) : [];
+          map.set(script.url, {script, licenseLinks, sources});
+        } catch (e) {
+         console.error("LibreJS: error parsing Web Labels at %s, row %s", baseURL, row.innerHTML, e);
+        }
       }
     } catch (e) {
       console.error("Error fetching Web Labels at %o", link, e);
     }
     return map;
   }
-  
+
   let fetchLicenseInfo = async cache => {
     let map = new Map();
     let args = {map, cache};
     // in the fetchXxx methods we add to a map whatever license(s)
-    // URLs and source code references we can find in various formats 
+    // URLs and source code references we can find in various formats
     // (WebLabels is currently the only implementation), keyed by script URLs.
     await Promise.all([
     fetchWebLabels(args),
@@ -69,7 +74,7 @@
     ]);
     return map;
   }
-  
+
   let handlers = {
     async checkLicensedScript(m) {
       let {url, cache} = m;

