зеркало из https://github.com/mozilla/gecko-dev.git
Bug 336694 (for tony@ponderer.org) r=ben use url-classifier db service for local list management
This commit is contained in:
Родитель
4db436d5f2
Коммит
f94d228c92
|
@ -267,7 +267,7 @@
|
|||
</button>
|
||||
<image id="lock-icon" onclick="if (event.button == 0) displaySecurityInfo(); event.stopPropagation();"/>
|
||||
#ifdef MOZ_SAFE_BROWSING
|
||||
<image src="chrome://browser/content/safebrowsing/skin/warning16x16.png"
|
||||
<image src="chrome://browser/skin/safebrowsing/warning16x16.png"
|
||||
id="safebrowsing-urlbar-icon" tooltiptext="&safeb.urlbaricon.tooltip;"
|
||||
style="display:none"
|
||||
onclick="goDoCommand('safebrowsing-show-warning')" />
|
||||
|
|
|
@ -131,109 +131,104 @@ PROT_ListWarden.prototype.registerWhiteTable = function(tableName) {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method that looks up a url in a set of tables
|
||||
*
|
||||
* @param tables array of table names
|
||||
* @param url URL to look up
|
||||
* @returns Boolean indicating if the url is in one of the tables
|
||||
*/
|
||||
PROT_ListWarden.prototype.isURLInTables_ = function(tables, url) {
|
||||
for (var i = 0; i < tables.length; ++i) {
|
||||
if (this.listManager_.safeExists(tables[i], url))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method that looks up a url in the white list.
|
||||
*
|
||||
* @param url URL to look up
|
||||
* @returns Boolean indicating if the url is on our whitelist
|
||||
*/
|
||||
PROT_ListWarden.prototype.isWhiteURL_ = function(url) {
|
||||
if (!this.listManager_)
|
||||
return false;
|
||||
|
||||
var whitelisted = this.isURLInTables_(this.whiteTables_, url);
|
||||
|
||||
if (whitelisted)
|
||||
G_Debug(this, "Whitelist hit: " + url);
|
||||
|
||||
return whitelisted;
|
||||
}
|
||||
|
||||
/**
|
||||
* External method that looks up a url on the whitelist, used by the
|
||||
* content-analyzer.
|
||||
*
|
||||
* @param url The URL to check
|
||||
* @returns Boolean indicating if the url is on the whitelist
|
||||
*/
|
||||
PROT_ListWarden.prototype.isWhiteURL = function(url) {
|
||||
return this.isWhiteURL_(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method that looks up a url in the black lists. Skips the lookup if
|
||||
* the URL is on our whitelist(s).
|
||||
*
|
||||
* @param url URL to look up
|
||||
* @returns Boolean indicating if the url is on our blacklist(s)
|
||||
*/
|
||||
PROT_ListWarden.prototype.isBlackURL_ = function(url) {
|
||||
if (!this.listManager_)
|
||||
return false;
|
||||
|
||||
var blacklisted = this.isURLInTables_(this.blackTables_, url);
|
||||
|
||||
if (blacklisted)
|
||||
G_Debug(this, "Blacklist hit: " + url);
|
||||
|
||||
return blacklisted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method that looks up a url in both the white and black lists.
|
||||
*
|
||||
* If there is conflict, the white list has precedence over the black list.
|
||||
*
|
||||
* This is tricky because all database queries are asynchronous. So we need
|
||||
* to chain together our checks against white and black tables. We use
|
||||
* MultiTableQuerier (see below) to manage this.
|
||||
*
|
||||
* @param url URL to look up
|
||||
* @returns Boolean indicating if the url is phishy.
|
||||
* @param evilCallback Function if the url is evil, we call this function.
|
||||
*/
|
||||
PROT_ListWarden.prototype.isEvilURL_ = function(url) {
|
||||
return !this.isWhiteURL_(url) && this.isBlackURL_(url);
|
||||
PROT_ListWarden.prototype.isEvilURL_ = function(url, evilCallback) {
|
||||
(new MultiTableQuerier(url,
|
||||
this.whiteTables_,
|
||||
this.blackTables_,
|
||||
evilCallback)).run();
|
||||
}
|
||||
|
||||
// Some unittests
|
||||
// TODO something more appropriate
|
||||
/**
|
||||
* This class helps us query multiple tables even though each table check
|
||||
* is asynchronous. It provides callbacks for each listManager lookup
|
||||
* and decides whether we need to continue querying or not. After
|
||||
* instantiating the method, use run() to invoke.
|
||||
*
|
||||
* @param url String The url to check
|
||||
* @param whiteTables Array of strings with each white table name
|
||||
* @param blackTables Array of strings with each black table name
|
||||
* @param evilCallback Function to call if it is an evil url
|
||||
*/
|
||||
function MultiTableQuerier(url, whiteTables, blackTables, evilCallback) {
|
||||
this.debugZone = "multitablequerier";
|
||||
this.url_ = url;
|
||||
|
||||
function TEST_PROT_ListWarden() {
|
||||
if (G_GDEBUG) {
|
||||
var z = "listwarden UNITTEST";
|
||||
G_debugService.enableZone(z);
|
||||
G_Debug(z, "Starting");
|
||||
// Since we pop from whiteTables_ and blackTables_, we need to make a copy.
|
||||
this.whiteTables_ = [];
|
||||
this.blackTables_ = [];
|
||||
for (var i = 0; i < whiteTables.length; ++i) {
|
||||
this.whiteTables_.push(whiteTables[i]);
|
||||
}
|
||||
for (var i = 0; i < blackTables.length; ++i) {
|
||||
this.blackTables_.push(blackTables[i]);
|
||||
}
|
||||
|
||||
var threadQueue = new TH_ThreadQueue();
|
||||
var listManager = new PROT_ListManager(threadQueue, true /* testing */);
|
||||
this.evilCallback_ = evilCallback;
|
||||
this.listManager_ = Cc["@mozilla.org/url-classifier/listmanager;1"]
|
||||
.getService(Ci.nsIUrlListManager);
|
||||
}
|
||||
|
||||
var warden = new PROT_ListWarden(listManager);
|
||||
|
||||
// Just some really simple test
|
||||
G_Assert(z, warden.registerWhiteTable("test-white-domain"),
|
||||
"Failed to register test-white-domain table");
|
||||
G_Assert(z, warden.registerWhiteTable("test-black-url"),
|
||||
"Failed to register test-black-url table");
|
||||
listManager.safeInsert("test-white-domain", "http://foo.com/good", "1");
|
||||
listManager.safeInsert("test-black-url", "http://foo.com/good/1", "1");
|
||||
listManager.safeInsert("test-black-url", "http://foo.com/bad/1", "1");
|
||||
|
||||
G_Assert(z, !warden.isEvilURL_("http://foo.com/good/1"),
|
||||
"White listing is not working.");
|
||||
G_Assert(z, warden.isEvilURL_("http://foo.com/bad/1"),
|
||||
"Black listing is not working.");
|
||||
|
||||
G_Debug(z, "PASSED");
|
||||
/**
|
||||
* We first query the white tables in succession. If any contain
|
||||
* the url, we stop. If none contain the url, we query the black tables
|
||||
* in succession. If any contain the url, we call evilCallback and
|
||||
* stop. If none of the black tables contain the url, then we just stop
|
||||
* (i.e., it's not black url).
|
||||
*/
|
||||
MultiTableQuerier.prototype.run = function() {
|
||||
if (this.whiteTables_.length > 0) {
|
||||
var tableName = this.whiteTables_.pop();
|
||||
G_Debug(this, "Looking in whitetable: " + tableName);
|
||||
this.listManager_.safeExists(tableName, this.url_,
|
||||
BindToObject(this.whiteTableCallback_,
|
||||
this));
|
||||
} else if (this.blackTables_.length > 0) {
|
||||
var tableName = this.blackTables_.pop();
|
||||
G_Debug(this, "Looking in blacktable: " + tableName);
|
||||
this.listManager_.safeExists(tableName, this.url_,
|
||||
BindToObject(this.blackTableCallback_,
|
||||
this));
|
||||
} else {
|
||||
// No tables left to check, so we quit.
|
||||
G_Debug(this, "Not found in any tables: " + this.url_);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* After checking a white table, we return here. If the url is found,
|
||||
* we can stop. Otherwise, we call run again.
|
||||
*/
|
||||
MultiTableQuerier.prototype.whiteTableCallback_ = function(isFound) {
|
||||
G_Debug(this, "whiteTableCallback_: " + isFound);
|
||||
if (!isFound)
|
||||
this.run();
|
||||
else
|
||||
G_Debug(this, "Found in whitelist: " + this.url_)
|
||||
}
|
||||
|
||||
/**
|
||||
* After checking a black table, we return here. If the url is found,
|
||||
* we can call the evilCallback and stop. Otherwise, we call run again.
|
||||
*/
|
||||
MultiTableQuerier.prototype.blackTableCallback_ = function(isFound) {
|
||||
G_Debug(this, "blackTableCallback_: " + isFound);
|
||||
if (!isFound) {
|
||||
this.run();
|
||||
} else {
|
||||
// In the blacklist, must be an evil url.
|
||||
G_Debug(this, "Found in blacklist: " + this.url_)
|
||||
this.evilCallback_();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -266,20 +266,15 @@ PROT_PhishingWarden.prototype.onDocNavStart = function(e) {
|
|||
// We're enabled. Either send a request off or check locally
|
||||
// TODO: move this logic to checkUrl, formalize the error callback
|
||||
if (this.checkRemote_) {
|
||||
// Use local whitelists to suppress remote BL lookups.
|
||||
if (!this.isWhiteURL_(url)) {
|
||||
G_Debug(this, "Local whitelist lookup failed");
|
||||
// TODO: Use local whitelists to suppress remote BL lookups.
|
||||
this.fetcher_.get(url,
|
||||
BindToObject(this.onTRFetchComplete,
|
||||
this,
|
||||
request));
|
||||
} else {
|
||||
G_Debug(this, "WL suppressing BL lookup for " + url);
|
||||
}
|
||||
} else {
|
||||
if (this.checkUrl(url)) {
|
||||
this.houstonWeHaveAProblem_(request);
|
||||
}
|
||||
this.checkUrl(url, BindToObject(this.houstonWeHaveAProblem_,
|
||||
this,
|
||||
request));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -432,22 +427,26 @@ PROT_PhishingWarden.prototype.isBlacklistTestURL = function(url) {
|
|||
/**
|
||||
* Look the URL up in our local blacklists
|
||||
*
|
||||
* @param url URL to check
|
||||
* @param callback Function to invoke if there is a problem.
|
||||
*
|
||||
* @param url URL to check
|
||||
*/
|
||||
PROT_PhishingWarden.prototype.checkUrl = function(url) {
|
||||
PROT_PhishingWarden.prototype.checkUrl = function(url, callback) {
|
||||
G_Debug(this, "Checking URL for " + url);
|
||||
|
||||
if (this.isEvilURL_(url) || this.isBlacklistTestURL(url)) {
|
||||
G_Debug(this, "Local blacklist hit");
|
||||
if (this.isBlacklistTestURL(url)) {
|
||||
callback();
|
||||
} else {
|
||||
// We wrap the callback because we also want
|
||||
// to report the blacklist hit to our data provider.
|
||||
function evilCallback() {
|
||||
G_Debug("evilCallback", "Local blacklist hit");
|
||||
// maybe send a report
|
||||
(new PROT_Reporter).report("phishblhit", url);
|
||||
return true;
|
||||
callback();
|
||||
}
|
||||
// Check the local lists.
|
||||
this.isEvilURL_(url, evilCallback);
|
||||
}
|
||||
|
||||
G_Debug(this, "Local blacklist miss");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const G_GDEBUG = true;
|
||||
const G_GDEBUG = false;
|
||||
|
||||
// Use subscript loader to load files. The files in ../content get mapped
|
||||
// to chrome://browser/content/safebrowsing/. Order matters if one file depends
|
||||
|
|
|
@ -1,225 +0,0 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Google Safe Browsing.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Niels Provos <niels@google.com> (original author)d
|
||||
|
||||
* Fritz Schneider <fritz@google.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// A warden that knows how to register lists with a listmanager and keep them
|
||||
// updated if necessary. The ListWarden also provides a simple interface to
|
||||
// check if a URL is evil or not. Specialized wardens like the PhishingWarden
|
||||
// inherit from it.
|
||||
//
|
||||
// Classes that inherit from ListWarden are responsible for calling
|
||||
// enableTableUpdates or disableTableUpdates. This usually entails
|
||||
// registering prefObservers and calling enable or disable in the base
|
||||
// class as appropriate.
|
||||
//
|
||||
|
||||
/**
|
||||
* Abtracts the checking of user/browser actions for signs of
|
||||
* phishing.
|
||||
*
|
||||
* @param ListManager ListManager that allows us to check against white
|
||||
* and black lists.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function PROT_ListWarden(listManager) {
|
||||
this.debugZone = "listwarden";
|
||||
this.listManager_ = listManager;
|
||||
|
||||
// Use this to query preferences
|
||||
this.prefs_ = new G_Preferences();
|
||||
|
||||
// Once we register tables, their respective names will be listed here.
|
||||
this.blackTables_ = [];
|
||||
this.whiteTables_ = [];
|
||||
this.sandboxUpdates_ = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the ListManger to keep all of our tables updated
|
||||
*/
|
||||
|
||||
PROT_ListWarden.prototype.enableTableUpdates = function() {
|
||||
this.listManager_.enableUpdateTables(this.blackTables_);
|
||||
this.listManager_.enableUpdateTables(this.whiteTables_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the ListManager to stop updating our tables
|
||||
*/
|
||||
|
||||
PROT_ListWarden.prototype.disableTableUpdates = function() {
|
||||
this.listManager_.disableUpdateTables(this.blackTables_);
|
||||
this.listManager_.disableUpdateTables(this.whiteTables_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the ListManager to keep sandbox updated. Don't tie this to the wl/bl
|
||||
* updates.
|
||||
*/
|
||||
PROT_ListWarden.prototype.enableSandboxUpdates = function() {
|
||||
this.listManager_.enableUpdateTables(this.sandboxUpdates_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the ListManager not to keep sandbox updated. Don't tie this to the
|
||||
* wl/bl updates.
|
||||
*/
|
||||
PROT_ListWarden.prototype.disableSandboxUpdates = function() {
|
||||
this.listManager_.disableUpdateTables(this.sandboxUpdates_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new black list table with the list manager
|
||||
* @param tableName - name of the table to register
|
||||
* @returns true if the table could be registered, false otherwise
|
||||
*/
|
||||
|
||||
PROT_ListWarden.prototype.registerBlackTable = function(tableName) {
|
||||
var result = this.listManager_.registerTable(tableName);
|
||||
if (result)
|
||||
this.blackTables_.push(tableName);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new white list table with the list manager
|
||||
* @param tableName - name of the table to register
|
||||
* @returns true if the table could be registered, false otherwise
|
||||
*/
|
||||
|
||||
PROT_ListWarden.prototype.registerWhiteTable = function(tableName) {
|
||||
var result = this.listManager_.registerTable(tableName);
|
||||
if (result)
|
||||
this.whiteTables_.push(tableName);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method that looks up a url in a set of tables
|
||||
*
|
||||
* @param tables array of table names
|
||||
* @param url URL to look up
|
||||
* @returns Boolean indicating if the url is in one of the tables
|
||||
*/
|
||||
PROT_ListWarden.prototype.isURLInTables_ = function(tables, url) {
|
||||
for (var i = 0; i < tables.length; ++i) {
|
||||
if (this.listManager_.safeLookup(tables[i], url))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method that looks up a url in the white list.
|
||||
*
|
||||
* @param url URL to look up
|
||||
* @returns Boolean indicating if the url is on our whitelist
|
||||
*/
|
||||
PROT_ListWarden.prototype.isWhiteURL_ = function(url) {
|
||||
if (!this.listManager_)
|
||||
return false;
|
||||
|
||||
var whitelisted = this.isURLInTables_(this.whiteTables_, url);
|
||||
|
||||
if (whitelisted)
|
||||
G_Debug(this, "Whitelist hit: " + url);
|
||||
|
||||
return whitelisted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method that looks up a url in the black lists.
|
||||
*
|
||||
* @param url URL to look up
|
||||
* @returns Boolean indicating if the url is on our blacklist(s)
|
||||
*/
|
||||
PROT_ListWarden.prototype.isBlackURL_ = function(url) {
|
||||
if (!this.listManager_)
|
||||
return false;
|
||||
|
||||
var blacklisted = this.isURLInTables_(this.blackTables_, url);
|
||||
|
||||
if (blacklisted)
|
||||
G_Debug(this, "Blacklist hit: " + url);
|
||||
|
||||
return blacklisted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method that looks up a url in both the white and black lists.
|
||||
*
|
||||
* If there is conflict, the white list has precedence over the black list.
|
||||
*
|
||||
* @param url URL to look up
|
||||
* @returns Boolean indicating if the url is phishy.
|
||||
*/
|
||||
PROT_ListWarden.prototype.isEvilURL_ = function(url) {
|
||||
return !this.isWhiteURL_(url) && this.isBlackURL_(url);
|
||||
}
|
||||
|
||||
// Some unittests
|
||||
// TODO something more appropriate
|
||||
|
||||
function TEST_PROT_ListWarden() {
|
||||
if (G_GDEBUG) {
|
||||
var z = "listwarden UNITTEST";
|
||||
G_debugService.enableZone(z);
|
||||
G_Debug(z, "Starting");
|
||||
|
||||
var threadQueue = new TH_ThreadQueue();
|
||||
var listManager = new PROT_ListManager(threadQueue, true /* testing */);
|
||||
|
||||
var warden = new PROT_ListWarden(listManager);
|
||||
|
||||
// Just some really simple test
|
||||
G_Assert(z, warden.registerWhiteTable("test-white-domain"),
|
||||
"Failed to register test-white-domain table");
|
||||
G_Assert(z, warden.registerWhiteTable("test-black-url"),
|
||||
"Failed to register test-black-url table");
|
||||
listManager.safeInsert("test-white-domain", "http://foo.com/good", "1");
|
||||
listManager.safeInsert("test-black-url", "http://foo.com/good/1", "1");
|
||||
listManager.safeInsert("test-black-url", "http://foo.com/bad/1", "1");
|
||||
|
||||
G_Assert(z, !warden.isEvilURL_("http://foo.com/good/1"),
|
||||
"White listing is not working.");
|
||||
G_Assert(z, warden.isEvilURL_("http://foo.com/bad/1"),
|
||||
"Black listing is not working.");
|
||||
|
||||
G_Debug(z, "PASSED");
|
||||
}
|
||||
}
|
|
@ -268,65 +268,21 @@ PROT_ListManager.prototype.stopUpdateChecker = function() {
|
|||
* use this because at certain points our tables might not be loaded,
|
||||
* and querying them could throw.
|
||||
*
|
||||
* @param table Name of the table that we want to consult
|
||||
* @param key Key for table lookup
|
||||
* @returns false or the value in the table corresponding to key.
|
||||
* If the table name does not exist, we return false, too.
|
||||
* @param table String Name of the table that we want to consult
|
||||
* @param key String Key for table lookup
|
||||
* @param callback nsIUrlListManagerCallback (ie., Function) given false or the
|
||||
* value in the table corresponding to key. If the table name does not
|
||||
* exist, we return false, too.
|
||||
*/
|
||||
PROT_ListManager.prototype.safeExists = function(table, key) {
|
||||
var result = false;
|
||||
PROT_ListManager.prototype.safeExists = function(table, key, callback) {
|
||||
try {
|
||||
G_Debug(this, "safeExists: " + table + ", " + key);
|
||||
var map = this.tablesData[table];
|
||||
result = map.exists(key);
|
||||
map.exists(key, callback);
|
||||
} catch(e) {
|
||||
result = false;
|
||||
G_Debug(this, "safeExists masked failure for " + table + ", key " + key + ": " + e);
|
||||
callback.handleEvent(false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides an exception free way to insert data into a table.
|
||||
* @param table Name of the table that we want to consult
|
||||
* @param key Key for table insert
|
||||
* @param value Value for table insert
|
||||
* @returns true if the value could be inserted, false otherwise
|
||||
*/
|
||||
PROT_ListManager.prototype.safeInsert = function(table, key, value) {
|
||||
if (!this.tablesKnown_[table]) {
|
||||
G_Debug(this, "Unknown table: " + table);
|
||||
return false;
|
||||
}
|
||||
if (!this.tablesData[table])
|
||||
this.tablesData[table] = newUrlClassifierTable(table);
|
||||
try {
|
||||
this.tablesData[table].insert(key, value);
|
||||
} catch (e) {
|
||||
G_Debug(this, "Cannot insert key " + key + " value " + value);
|
||||
G_Debug(this, e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides an exception free way to remove data from a table.
|
||||
* @param table Name of the table that we want to consult
|
||||
* @param key Key for table erase
|
||||
* @returns true if the value could be removed, false otherwise
|
||||
*/
|
||||
PROT_ListManager.prototype.safeRemove = function(table, key) {
|
||||
if (!this.tablesKnown_[table]) {
|
||||
G_Debug(this, "Unknown table: " + table);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.tablesData[table])
|
||||
return false;
|
||||
|
||||
return this.tablesData[table].remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -348,43 +304,30 @@ PROT_ListManager.prototype.loadTableVersions_ = function() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get lines of the form "[goog-black-enchash 1.1234]" or
|
||||
* "[goog-white-url 1.1234 update]" and set the version numbers in the user
|
||||
* pref.
|
||||
* @param updateString String containing the response from the server.
|
||||
* @return Array a list of table names
|
||||
* Callback from db update service. As new tables are added to the db,
|
||||
* this callback is fired so we can update the version number.
|
||||
* @param versionString String containing the table update response from the
|
||||
* server
|
||||
*/
|
||||
PROT_ListManager.prototype.setTableVersions_ = function(updateString) {
|
||||
var updatedTables = [];
|
||||
|
||||
var prefBase = kTableVersionPrefPrefix;
|
||||
var startPos = updateString.indexOf('[');
|
||||
var endPos;
|
||||
while (startPos != -1) {
|
||||
// [ needs to be the start of a new line
|
||||
if (0 == startPos || ('\n' == updateString[startPos - 1] &&
|
||||
'\n' == updateString[startPos - 2])) {
|
||||
endPos = updateString.indexOf('\n', startPos);
|
||||
if (endPos != -1) {
|
||||
var line = updateString.substring(startPos, endPos);
|
||||
var versionParser = new PROT_VersionParser("dummy");
|
||||
|
||||
if (versionParser.fromString(line)) {
|
||||
PROT_ListManager.prototype.setTableVersion_ = function(versionString) {
|
||||
G_Debug(this, "Got version string: " + versionString);
|
||||
var versionParser = new PROT_VersionParser("");
|
||||
if (versionParser.fromString(versionString)) {
|
||||
var tableName = versionParser.type;
|
||||
var version = versionParser.major + '.' + versionParser.minor;
|
||||
G_Debug(this, "Set table version for " + tableName + ": " + version);
|
||||
this.prefs_.setPref(prefBase + tableName, version);
|
||||
this.tablesKnown_[tableName].ImportVersion(versionParser);
|
||||
var versionNumber = versionParser.versionString();
|
||||
var prefBase = kTableVersionPrefPrefix;
|
||||
|
||||
updatedTables.push(tableName);
|
||||
this.prefs_.setPref(prefBase + tableName, versionNumber);
|
||||
|
||||
if (!this.tablesKnown_[tableName]) {
|
||||
this.tablesKnown_[tableName] = versionParser;
|
||||
} else {
|
||||
this.tablesKnown_[tableName].ImportVersion(versionParser);
|
||||
}
|
||||
|
||||
if (!this.tablesData[tableName])
|
||||
this.tablesData[tableName] = newUrlClassifierTable(tableName);
|
||||
}
|
||||
}
|
||||
// This could catch option params, but that's ok. The double newline
|
||||
// check will skip over it.
|
||||
startPos = updateString.indexOf('[', startPos + 1);
|
||||
}
|
||||
return updatedTables;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -485,32 +428,12 @@ PROT_ListManager.prototype.rpcDone = function(data) {
|
|||
return;
|
||||
}
|
||||
|
||||
// List updates (local lists) don't work yet. See bug 336203.
|
||||
throw Exception("dbservice not yet implemented.");
|
||||
|
||||
var dbUpdateSrv = Cc["@mozilla.org/url-classifier/dbservice;1"]
|
||||
.getService(Ci.nsIUrlClassifierDBService);
|
||||
|
||||
// Update the tables on disk.
|
||||
try {
|
||||
dbUpdateSrv.updateTables(data);
|
||||
} catch (e) {
|
||||
// dbUpdateSrv will throw an error if the background thread is already
|
||||
// working. In this case, we just wait for the next scheduled update.
|
||||
G_Debug(this, "Skipping update, write thread busy.");
|
||||
return;
|
||||
}
|
||||
|
||||
// While the update is being processed by a background thread, we need
|
||||
// to also update the table versions.
|
||||
var tableNames = this.setTableVersions_(data);
|
||||
G_Debug(this, "Updated tables: " + tableNames);
|
||||
|
||||
for (var t = 0, name = null; name = tableNames[t]; ++t) {
|
||||
// Create the table object if it doesn't exist.
|
||||
if (!this.tablesData[name])
|
||||
this.tablesData[name] = newUrlClassifierTable(name);
|
||||
}
|
||||
// Update the tables on disk in a background thread. Multiple updates
|
||||
// will be queue up.
|
||||
dbUpdateSrv.updateTables(data, BindToObject(this.setTableVersion_, this));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,232 +0,0 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Google Safe Browsing.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Fritz Schneider <fritz@google.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
// This is a map over which you can iterate (you can't get an iterator
|
||||
// for an Object used as a map). It is important to have an iterable
|
||||
// map if you have a large numbe ofkeys and you wish to process them
|
||||
// in chunks, for example on a thread.
|
||||
//
|
||||
// This Map's operations are all O(1) plus the time of the native
|
||||
// operations on its arrays and object. The tradeoff for this speed is
|
||||
// that the size of the map is always non-decreasing. That is, when an
|
||||
// item is remove()'d, it is merely marked as invalid and not actually
|
||||
// removed.
|
||||
//
|
||||
// This map is not safe if your keys are objects (they'll get
|
||||
// stringified to the same value in non-debug builds).
|
||||
//
|
||||
// Interface:
|
||||
// insert(key, value)
|
||||
// remove(key)
|
||||
// exists(key)
|
||||
// getList() // This is our poor man's iterator
|
||||
// forEach(someFunc)
|
||||
// replace(otherMap) // Clones otherMap, replacing the current map
|
||||
// count // readonly attribute
|
||||
//
|
||||
// TODO: we could easily have this map periodically compact itself so as
|
||||
// to eliminate the size tradeoff.
|
||||
|
||||
/**
|
||||
* Create a new Map
|
||||
*
|
||||
* @constructor
|
||||
* @param opt_name A string used to name the map
|
||||
*/
|
||||
function G_Map(opt_name) {
|
||||
this.debugZone = "map";
|
||||
this.name = "noname";
|
||||
|
||||
// We store key/value pairs sequentially in membersArray
|
||||
this.membersArray_ = [];
|
||||
|
||||
// In membersMap we map from keys to indices in the membersArray
|
||||
this.membersMap_ = {};
|
||||
this.count_ = 0;
|
||||
|
||||
// set to true to allow list manager to update
|
||||
this.needsUpdate = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item
|
||||
*
|
||||
* @param key An key to add (overwrites previous key)
|
||||
* @param value The value to store at that key
|
||||
*/
|
||||
G_Map.prototype.insert = function(key, value) {
|
||||
if (key == null)
|
||||
throw new Error("Can't use null as a key");
|
||||
else if (typeof key == "object")
|
||||
throw new Error("This class is not objectsafe; use ObjectSafeMap");
|
||||
if (value === undefined)
|
||||
throw new Error("Can't store undefined values in this map");
|
||||
|
||||
// Get rid of the old value, if there was one, and increment count if not
|
||||
var oldIndexInArray = this.membersMap_[key];
|
||||
if (typeof oldIndexInArray == "number")
|
||||
this.membersArray_[oldIndexInArray] = undefined;
|
||||
else
|
||||
this.count_++;
|
||||
|
||||
var indexInArray = this.membersArray_.length;
|
||||
this.membersArray_.push({ "key": key, "value": value});
|
||||
this.membersMap_[key] = indexInArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a key from the map
|
||||
*
|
||||
* @param key The key to remove
|
||||
* @returns Boolean indicating if the key was removed
|
||||
*/
|
||||
G_Map.prototype.remove = function(key) {
|
||||
var indexInArray = this.membersMap_[key];
|
||||
|
||||
if (indexInArray === undefined)
|
||||
return false;
|
||||
|
||||
this.count_--;
|
||||
delete this.membersMap_[key];
|
||||
// We could slice here, but that could be expensive if the map large
|
||||
this.membersArray_[indexInArray] = undefined;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private lookup function
|
||||
*
|
||||
* @param key The key to look up
|
||||
* @returns The value at that key or undefined if it doesn't exist
|
||||
*/
|
||||
G_Map.prototype.find_ = function(key) {
|
||||
var indexInArray = this.membersMap_[key];
|
||||
return ((indexInArray === undefined) ?
|
||||
undefined :
|
||||
this.membersArray_[indexInArray].value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public lookup function
|
||||
*
|
||||
* @param key The key to look up
|
||||
* @returns The value at that key or undefined if it doesn't exist
|
||||
*/
|
||||
G_Map.prototype.exists = function(key) {
|
||||
return this.find_(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of the keys we have. Use findValue to get the associated
|
||||
* value.
|
||||
*
|
||||
* TODO: its probably better to expose a real iterator, but this works
|
||||
* TODO: getting keys and values is a pain, do something more clever
|
||||
*
|
||||
* @returns Array of items in the map, some entries of which might be
|
||||
* undefined. Each item is an object with members key and
|
||||
* value
|
||||
*/
|
||||
G_Map.prototype.getKeys = function(count) {
|
||||
var ret = [];
|
||||
for (var i = 0; i < this.membersArray_.length; ++i) {
|
||||
ret.push(this.membersArray_[i].key);
|
||||
}
|
||||
count.value = ret.length;
|
||||
return ret;
|
||||
}
|
||||
|
||||
G_Map.prototype.findValue = function(key) {
|
||||
return this.find_(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace one map with the content of another
|
||||
*
|
||||
* IMPORTANT NOTE: This method copies references to objects, it does
|
||||
* NOT copy the objects themselves.
|
||||
*
|
||||
* @param other Reference to a G_Map that we should clone
|
||||
*/
|
||||
G_Map.prototype.replace = function(other) {
|
||||
this.membersMap_ = {};
|
||||
this.membersArray_ = [];
|
||||
|
||||
// TODO Make this faster, and possibly run it on a thread
|
||||
var lst = {};
|
||||
var otherList = other.getList(lst);
|
||||
for (var i = 0; i < otherList.length; i++)
|
||||
if (otherList[i]) {
|
||||
var index = this.membersArray_.length;
|
||||
this.membersArray_.push(otherList[i]);
|
||||
this.membersMap_[otherList[i].key] = index;
|
||||
}
|
||||
this.count_ = other.count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a function to each of the key value pairs.
|
||||
*
|
||||
* @param func Function to apply to the map's key value pairs
|
||||
*/
|
||||
G_Map.prototype.forEach = function(func) {
|
||||
if (typeof func != "function")
|
||||
throw new Error("argument to forEach is not a function, it's a(n) " +
|
||||
typeof func);
|
||||
|
||||
for (var i = 0; i < this.membersArray_.length; i++)
|
||||
if (this.membersArray_[i])
|
||||
func(this.membersArray_[i].key, this.membersArray_[i].value);
|
||||
}
|
||||
|
||||
G_Map.prototype.QueryInterface = function(iid) {
|
||||
if (iid.equals(Components.interfaces.nsISupports) ||
|
||||
iid.equals(Components.interfaces.nsIUrlClassifierTable))
|
||||
return this;
|
||||
|
||||
Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Readonly count attribute.
|
||||
* @returns The number of keys in the map
|
||||
*/
|
||||
G_Map.prototype.__defineGetter__('count', function() {
|
||||
return this.count_;
|
||||
});
|
|
@ -0,0 +1,145 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Google Safe Browsing.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Tony Chang <tony@google.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* This class helps us batch a series of async calls to the db.
|
||||
* If any of the tokens is in the database, we fire callback with
|
||||
* true as a param. If all the tokens are not in the database,
|
||||
* we fire callback with false as a param.
|
||||
* This is an "Abstract" base class. Subclasses need to supply
|
||||
* the condition_ method.
|
||||
*
|
||||
* @param tokens Array of strings to lookup in the db
|
||||
* @param tableName String name of the table
|
||||
* @param callback Function callback function that takes true if the condition
|
||||
* passes.
|
||||
*/
|
||||
function MultiQuerier(tokens, tableName, callback) {
|
||||
this.tokens_ = tokens;
|
||||
this.tableName_ = tableName;
|
||||
this.callback_ = callback;
|
||||
this.dbservice_ = Cc["@mozilla.org/url-classifier/dbservice;1"]
|
||||
.getService(Ci.nsIUrlClassifierDBService);
|
||||
// We put the current token in this variable.
|
||||
this.key_ = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the remaining tokens against the db.
|
||||
*/
|
||||
MultiQuerier.prototype.run = function() {
|
||||
if (this.tokens_.length == 0) {
|
||||
this.callback_.handleEvent(false);
|
||||
return;
|
||||
}
|
||||
|
||||
this.key_ = this.tokens_.pop();
|
||||
G_Debug(this, "Looking up " + this.key_ + " in " + this.tableName_);
|
||||
this.dbservice_.exists(this.tableName_, this.key_,
|
||||
BindToObject(this.result_, this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback from the db. If the returned value passes the this.condition_
|
||||
* test, go ahead and call the main callback.
|
||||
*/
|
||||
MultiQuerier.prototype.result_ = function(value) {
|
||||
if (this.condition_(value))
|
||||
this.callback_.handleEvent(true)
|
||||
else
|
||||
this.run();
|
||||
}
|
||||
|
||||
// Subclasses must override this.
|
||||
MultiQuerier.prototype.condition_ = function(value) {
|
||||
throw "MultiQuerier is an abstract base class";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Concrete MultiQuerier that stops if the key exists in the db.
|
||||
*/
|
||||
function ExistsMultiQuerier(tokens, tableName, callback) {
|
||||
MultiQuerier.call(this, tokens, tableName, callback);
|
||||
this.debugZone = "existsMultiQuerier";
|
||||
}
|
||||
ExistsMultiQuerier.inherits(MultiQuerier);
|
||||
|
||||
ExistsMultiQuerier.prototype.condition_ = function(value) {
|
||||
return value.length > 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Concrete MultiQuerier that looks up a key, decrypts it, then
|
||||
* checks the the resulting regular expressions for a match.
|
||||
* @param tokens Array of hosts
|
||||
*/
|
||||
function EnchashMultiQuerier(tokens, tableName, callback, url) {
|
||||
MultiQuerier.call(this, tokens, tableName, callback);
|
||||
this.url_ = url;
|
||||
this.enchashDecrypter_ = new PROT_EnchashDecrypter();
|
||||
this.debugZone = "enchashMultiQuerier";
|
||||
}
|
||||
EnchashMultiQuerier.inherits(MultiQuerier);
|
||||
|
||||
EnchashMultiQuerier.prototype.run = function() {
|
||||
if (this.tokens_.length == 0) {
|
||||
this.callback_.handleEvent(false);
|
||||
return;
|
||||
}
|
||||
var host = this.tokens_.pop();
|
||||
this.key_ = host;
|
||||
var lookupKey = this.enchashDecrypter_.getLookupKey(host);
|
||||
this.dbservice_.exists(this.tableName_, lookupKey,
|
||||
BindToObject(this.result_, this));
|
||||
}
|
||||
|
||||
EnchashMultiQuerier.prototype.condition_ = function(encryptedValue) {
|
||||
if (encryptedValue.length > 0) {
|
||||
// We have encrypted regular expressions for this host. Let's
|
||||
// decrypt them and see if we have a match.
|
||||
var decrypted = this.enchashDecrypter_.decryptData(encryptedValue,
|
||||
this.key_);
|
||||
var res = this.enchashDecrypter_.parseRegExps(decrypted);
|
||||
for (var j = 0; j < res.length; j++) {
|
||||
if (res[j].test(this.url_)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -105,25 +105,34 @@ PROT_VersionParser.prototype.ImportVersion = function(version) {
|
|||
this.mac = version.mac;
|
||||
this.macFailed = version.macFailed;
|
||||
this.macval = version.macval;
|
||||
// Don't set requireMac, since wfr creates vparsers from scratch and doesn't
|
||||
// Don't set requireMac, since we create vparsers from scratch and doesn't
|
||||
// know about it
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string like [goog-white-black 1.1] from internal information
|
||||
*
|
||||
* @returns version string
|
||||
* @returns String
|
||||
*/
|
||||
PROT_VersionParser.prototype.toString = function() {
|
||||
var s = "[" + this.type + " " + this.major + "." + this.minor + "]";
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string like 1.123 with the version number. This is the
|
||||
* format we store in prefs.
|
||||
* @return String
|
||||
*/
|
||||
PROT_VersionParser.prototype.versionString = function() {
|
||||
return this.major + "." + this.minor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string like 1:1 from internal information used for
|
||||
* fetching updates from the server. Called by the listmanager.
|
||||
*
|
||||
* @returns version string
|
||||
* @returns String
|
||||
*/
|
||||
PROT_VersionParser.prototype.toUrl = function() {
|
||||
return this.major + ":" + this.minor;
|
||||
|
|
|
@ -2,8 +2,7 @@ toolkit.jar:
|
|||
+ content/global/url-classifier/application.js (content/application.js)
|
||||
+ content/global/url-classifier/enchash-decrypter.js (content/enchash-decrypter.js)
|
||||
+ content/global/url-classifier/listmanager.js (content/listmanager.js)
|
||||
+ content/global/url-classifier/list-warden.js (content/list-warden.js)
|
||||
+ content/global/url-classifier/map.js (content/map.js)
|
||||
+ content/global/url-classifier/multi-querier.js (content/multi-querier.js)
|
||||
+ content/global/url-classifier/url-canonicalizer.js (content/url-canonicalizer.js)
|
||||
+ content/global/url-classifier/url-crypto.js (content/url-crypto.js)
|
||||
+ content/global/url-classifier/url-crypto-key-manager.js (content/url-crypto-key-manager.js)
|
||||
|
|
|
@ -36,15 +36,13 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIUrlListManager.idl"
|
||||
|
||||
// A map that contains a string keys mapped to string values.
|
||||
// TODO: maybe nsISerializeable to handle reading/writing from disk?
|
||||
|
||||
[scriptable, uuid(fd1f8334-1859-472d-b01f-4ac6b1121ce4)]
|
||||
interface nsIUrlClassifierTable : nsISupports
|
||||
{
|
||||
readonly attribute long count;
|
||||
|
||||
/**
|
||||
* The name used to identify this table
|
||||
*/
|
||||
|
@ -57,27 +55,9 @@ interface nsIUrlClassifierTable : nsISupports
|
|||
|
||||
/**
|
||||
* In the simple case, exists just looks up the string in the
|
||||
* table and returns true if it is found. However, it could
|
||||
* do something more complex (e.g., canonicalize the url).
|
||||
* table and call the callback after the query returns with true or
|
||||
* false. It's possible that something more complex happens
|
||||
* (e.g., canonicalize the url).
|
||||
*/
|
||||
boolean exists(in ACString key);
|
||||
|
||||
/**
|
||||
* In the simple case, key is a url and value is 1. However,
|
||||
* value could be more complicated (e.g., hashed value based
|
||||
* on site domain).
|
||||
*/
|
||||
void insert(in ACString key, in ACString value);
|
||||
|
||||
void remove(in ACString key);
|
||||
|
||||
// TEMPORARY: used to help serialize the table to disk. May be removed.
|
||||
void getKeys(out unsigned long size,
|
||||
[retval,array,size_is(size)] out string keys);
|
||||
|
||||
// TEMPORARY: used to help serialize the table to disk. May be removed.
|
||||
void findValue(in ACString key);
|
||||
|
||||
// TODO: merge data
|
||||
// void replace(in nsIUrlClassifierTable);
|
||||
void exists(in ACString key, in nsIUrlListManagerCallback cb);
|
||||
};
|
||||
|
|
|
@ -41,16 +41,15 @@
|
|||
* Interface for a class that manages updates of multiple nsIUrlClassifierTables.
|
||||
*/
|
||||
|
||||
interface nsIFile;
|
||||
// Interface for JS function callbacks
|
||||
[scriptable, function, uuid(ba913c5c-13d6-41eb-83c1-de2f4165a516)]
|
||||
interface nsIUrlListManagerCallback : nsISupports {
|
||||
void handleEvent(in boolean value);
|
||||
};
|
||||
|
||||
[scriptable, uuid(e1a80418-1bf9-4bd7-a40d-94d549c24955)]
|
||||
interface nsIUrlListManager : nsISupports
|
||||
{
|
||||
/**
|
||||
* Set the directory to read/write tables to.
|
||||
*/
|
||||
void setAppDir(in nsIFile appDir);
|
||||
|
||||
/**
|
||||
* Add a table to the list of tables we are managing. The name is a
|
||||
* string of the format provider_name-semantic_type-table_type. For
|
||||
|
@ -71,21 +70,10 @@ interface nsIUrlListManager : nsISupports
|
|||
void disableUpdate(in ACString tableName);
|
||||
|
||||
/**
|
||||
* Lookup a key in a table. Should not raise exceptions. Returns
|
||||
* true if the key was found into the table.
|
||||
* Lookup a key in a table. Should not raise exceptions. Calls
|
||||
* the callback function with a single parameter: true if the key
|
||||
* is in the table, false if it isn't.
|
||||
*/
|
||||
boolean safeExists(in ACString tableName, in ACString key);
|
||||
|
||||
/**
|
||||
* Insert a key in a table. Should not raise exceptions. Returns
|
||||
* true if the key was inserted into the table.
|
||||
*/
|
||||
boolean safeInsert(in ACString tableName, in ACString key,
|
||||
in ACString value);
|
||||
|
||||
/**
|
||||
* Remove a key from a table. Should not raise exceptions. Returns
|
||||
* true if the key was removed from the table.
|
||||
*/
|
||||
boolean safeRemove(in ACString tableName, in string key);
|
||||
void safeExists(in ACString tableName, in ACString key,
|
||||
in nsIUrlListManagerCallback cb);
|
||||
};
|
||||
|
|
|
@ -29,7 +29,6 @@ LOCAL_INCLUDES = \
|
|||
# EXTRA_COMPONENTS installs components written in JS to dist/bin/components
|
||||
EXTRA_COMPONENTS = urlClassifierTableUrl.js \
|
||||
urlClassifierTableDomain.js \
|
||||
urlClassifierTableSite.js \
|
||||
urlClassifierTableEnchash.js \
|
||||
urlListManager.js \
|
||||
$(NULL)
|
||||
|
|
|
@ -340,7 +340,7 @@ nsUrlClassifierDBServiceWorker::ProcessUpdateTable(
|
|||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
if ('+' == op && spacePos != kNotFound) {
|
||||
// Insert operation of the form "+KEY VALUE"
|
||||
// Insert operation of the form "+KEY\tVALUE"
|
||||
const nsDependentCSubstring &key = Substring(aLine, 1, spacePos - 1);
|
||||
const nsDependentCSubstring &value = Substring(aLine, spacePos + 1);
|
||||
aUpdateStatement->BindUTF8StringParameter(0, key);
|
||||
|
|
|
@ -1,3 +1,43 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Url Classifier code
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Tony Chang <tony@ponderer.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// TODO: Combine this file with other urlClassifierTable files and rename to
|
||||
// nsUrlClassifierTable.js
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const G_GDEBUG = false;
|
||||
|
@ -11,8 +51,9 @@ const LIB_FILES = [
|
|||
"chrome://global/content/url-classifier/moz/preferences.js",
|
||||
"chrome://global/content/url-classifier/moz/filesystem.js",
|
||||
"chrome://global/content/url-classifier/moz/debug.js", // req js/lang.js moz/prefs.js moz/filesystem.js
|
||||
"chrome://global/content/url-classifier/moz/lang.js",
|
||||
|
||||
"chrome://global/content/url-classifier/map.js",
|
||||
"chrome://global/content/url-classifier/multi-querier.js",
|
||||
];
|
||||
|
||||
for (var i = 0, libFile; libFile = LIB_FILES[i]; ++i) {
|
||||
|
@ -23,18 +64,25 @@ for (var i = 0, libFile; libFile = LIB_FILES[i]; ++i) {
|
|||
}
|
||||
|
||||
function UrlClassifierTableDomain() {
|
||||
G_Map.call(this);
|
||||
this.debugZone = "trtable-domain";
|
||||
this.name = '';
|
||||
this.needsUpdate = false;
|
||||
}
|
||||
|
||||
UrlClassifierTableDomain.inherits(G_Map);
|
||||
UrlClassifierTableDomain.prototype.QueryInterface = function(iid) {
|
||||
if (iid.equals(Components.interfaces.nsISupports) ||
|
||||
iid.equals(Components.interfaces.nsIUrlClassifierTable))
|
||||
return this;
|
||||
Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up a URL in a domain table
|
||||
*
|
||||
* @returns Boolean true if the url domain is in the table
|
||||
*/
|
||||
UrlClassifierTableDomain.prototype.exists = function(url) {
|
||||
UrlClassifierTableDomain.prototype.exists = function(url, callback) {
|
||||
var urlObj = Cc["@mozilla.org/network/standard-url;1"]
|
||||
.createInstance(Ci.nsIURL);
|
||||
urlObj.spec = url;
|
||||
|
@ -43,13 +91,14 @@ UrlClassifierTableDomain.prototype.exists = function(url) {
|
|||
|
||||
// We don't have a good way map from hosts to domains, so we instead try
|
||||
// each possibility. Could probably optimize to start at the second dot?
|
||||
var possible = [];
|
||||
for (var i = 0; i < components.length - 1; i++) {
|
||||
host = components.slice(i).join(".");
|
||||
var val = this.find_(host);
|
||||
if (val)
|
||||
return true;
|
||||
possible.push(host);
|
||||
}
|
||||
return false;
|
||||
|
||||
// Run the possible domains against the db.
|
||||
(new ExistsMultiQuerier(possible, this.name, callback)).run();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,43 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Url Classifier code
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Tony Chang <tony@ponderer.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// TODO: Combine this file with other urlClassifierTable files and rename to
|
||||
// nsUrlClassifierTable.js
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const G_GDEBUG = false;
|
||||
|
@ -12,11 +52,12 @@ const LIB_FILES = [
|
|||
"chrome://global/content/url-classifier/moz/preferences.js",
|
||||
"chrome://global/content/url-classifier/moz/filesystem.js",
|
||||
"chrome://global/content/url-classifier/moz/debug.js", // req js/lang.js moz/prefs.js moz/filesystem.js
|
||||
"chrome://global/content/url-classifier/moz/lang.js",
|
||||
|
||||
"chrome://global/content/url-classifier/map.js",
|
||||
"chrome://global/content/url-classifier/moz/base64.js",
|
||||
"chrome://global/content/url-classifier/moz/cryptohasher.js",
|
||||
"chrome://global/content/url-classifier/enchash-decrypter.js",
|
||||
"chrome://global/content/url-classifier/multi-querier.js",
|
||||
];
|
||||
|
||||
for (var i = 0, libFile; libFile = LIB_FILES[i]; ++i) {
|
||||
|
@ -27,45 +68,39 @@ for (var i = 0, libFile; libFile = LIB_FILES[i]; ++i) {
|
|||
}
|
||||
|
||||
function UrlClassifierTableEnchash() {
|
||||
G_Map.call(this);
|
||||
this.debugZone = "trtable-enchash";
|
||||
this.dbservice = Cc["@mozilla.org/url-classifier/dbservice;1"]
|
||||
.getService(Ci.nsIUrlClassifierDBService);
|
||||
this.name = '';
|
||||
this.needsUpdate = false;
|
||||
this.enchashDecrypter_ = new PROT_EnchashDecrypter();
|
||||
}
|
||||
|
||||
UrlClassifierTableEnchash.inherits(G_Map);
|
||||
UrlClassifierTableEnchash.prototype.QueryInterface = function(iid) {
|
||||
if (iid.equals(Components.interfaces.nsISupports) ||
|
||||
iid.equals(Components.interfaces.nsIUrlClassifierTable))
|
||||
return this;
|
||||
Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up a URL in an enchashDB
|
||||
*
|
||||
* @returns Boolean indicating whether the URL matches the regular
|
||||
* expression contained in the table value
|
||||
*/
|
||||
UrlClassifierTableEnchash.prototype.exists = function(url) {
|
||||
UrlClassifierTableEnchash.prototype.exists = function(url, callback) {
|
||||
var host = this.enchashDecrypter_.getCanonicalHost(url);
|
||||
|
||||
var possible = [];
|
||||
for (var i = 0; i < PROT_EnchashDecrypter.MAX_DOTS + 1; i++) {
|
||||
var key = this.enchashDecrypter_.getLookupKey(host);
|
||||
|
||||
var encrypted = this.find_(key);
|
||||
if (encrypted) {
|
||||
G_Debug(this, "Enchash DB has host " + host);
|
||||
|
||||
// We have encrypted regular expressions for this host. Let's
|
||||
// decrypt them and see if we have a match.
|
||||
var decrypted = this.enchashDecrypter_.decryptData(encrypted, host);
|
||||
var res = this.enchashDecrypter_.parseRegExps(decrypted);
|
||||
for (var j = 0; j < res.length; j++) {
|
||||
if (res[j].test(url))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
possible.push(host);
|
||||
|
||||
var index = host.indexOf(".");
|
||||
if (index == -1)
|
||||
break;
|
||||
host = host.substring(index + 1);
|
||||
}
|
||||
return false;
|
||||
// Run the possible domains against the db.
|
||||
(new EnchashMultiQuerier(possible, this.name, callback, url)).run();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const G_GDEBUG = false;
|
||||
|
||||
// Use subscript loader to load files. The files in ../content get mapped
|
||||
// to chrome://global/content/url-classifier/. Order matters if one file depends
|
||||
// on another file during initialization.
|
||||
const LIB_FILES = [
|
||||
"chrome://global/content/url-classifier/js/lang.js",
|
||||
|
||||
"chrome://global/content/url-classifier/moz/preferences.js",
|
||||
"chrome://global/content/url-classifier/moz/filesystem.js",
|
||||
"chrome://global/content/url-classifier/moz/debug.js", // req js/lang.js moz/prefs.js moz/filesystem.js
|
||||
|
||||
"chrome://global/content/url-classifier/map.js",
|
||||
];
|
||||
|
||||
for (var i = 0, libFile; libFile = LIB_FILES[i]; ++i) {
|
||||
//dump('*** loading subscript ' + libFile + '\n');
|
||||
Cc["@mozilla.org/moz/jssubscript-loader;1"]
|
||||
.getService(Ci.mozIJSSubScriptLoader)
|
||||
.loadSubScript(libFile);
|
||||
}
|
||||
|
||||
function UrlClassifierTableSite() {
|
||||
G_Map.call(this);
|
||||
this.debugZone = "trtable-site";
|
||||
this.ioService_ = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
}
|
||||
|
||||
UrlClassifierTableSite.inherits(G_Map);
|
||||
|
||||
/**
|
||||
* Look up a URL in a site DB
|
||||
*
|
||||
* @returns Boolean true if URL matches in table, we normalize based on
|
||||
* part of the path
|
||||
*/
|
||||
UrlClassifierTableSite.prototype.exists = function(url) {
|
||||
var nsIURI = this.ioService_.newURI(url, null, null);
|
||||
var host = nsIURI.asciiHost;
|
||||
var hostComponents = host.split(".");
|
||||
|
||||
var path = nsIURI.path;
|
||||
var pathComponents = path.split("/");
|
||||
|
||||
// We don't have a good way to convert a fully specified URL into a
|
||||
// site. We try host name components with or without the first
|
||||
// path component.
|
||||
for (var i = 0; i < hostComponents.length - 1; i++) {
|
||||
host = hostComponents.slice(i).join(".") + "/";
|
||||
var val = this.find_(host);
|
||||
G_Debug(this, "Checking: " + host + " : " + val);
|
||||
if (val)
|
||||
return true;
|
||||
|
||||
// The path starts with a "/", so we are interested in the second path
|
||||
// component if it is available
|
||||
if (pathComponents.length >= 2) {
|
||||
host = host + pathComponents[1] + "/";
|
||||
var val = this.find_(host);
|
||||
G_Debug(this, "Checking: " + host + " : " + val);
|
||||
if (val)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Module object
|
||||
function UrlClassifierTableSiteMod() {
|
||||
this.firstTime = true;
|
||||
this.cid = Components.ID("{1e48f217-34e4-44a3-9b4a-9b66ed0a1201}");
|
||||
this.progid = "@mozilla.org/url-classifier/table;1?type=site";
|
||||
}
|
||||
|
||||
UrlClassifierTableSiteMod.prototype.registerSelf = function(compMgr, fileSpec, loc, type) {
|
||||
if (this.firstTime) {
|
||||
this.firstTime = false;
|
||||
throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
|
||||
}
|
||||
compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
compMgr.registerFactoryLocation(this.cid,
|
||||
"UrlClassifier Table Site Module",
|
||||
this.progid,
|
||||
fileSpec,
|
||||
loc,
|
||||
type);
|
||||
};
|
||||
|
||||
UrlClassifierTableSiteMod.prototype.getClassObject = function(compMgr, cid, iid) {
|
||||
if (!cid.equals(this.cid))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
if (!iid.equals(Ci.nsIFactory))
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
return this.factory;
|
||||
}
|
||||
|
||||
UrlClassifierTableSiteMod.prototype.canUnload = function(compMgr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
UrlClassifierTableSiteMod.prototype.factory = {
|
||||
createInstance: function(outer, iid) {
|
||||
if (outer != null)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
return (new UrlClassifierTableSite()).QueryInterface(iid);
|
||||
}
|
||||
};
|
||||
|
||||
var SiteModInst = new UrlClassifierTableSiteMod();
|
||||
|
||||
function NSGetModule(compMgr, fileSpec) {
|
||||
return SiteModInst;
|
||||
}
|
|
@ -1,3 +1,43 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Url Classifier code
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Tony Chang <tony@ponderer.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// TODO: Combine this file with other urlClassifierTable files and rename to
|
||||
// nsUrlClassifierTable.js
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const G_GDEBUG = false;
|
||||
|
@ -12,7 +52,6 @@ const LIB_FILES = [
|
|||
"chrome://global/content/url-classifier/moz/filesystem.js",
|
||||
"chrome://global/content/url-classifier/moz/debug.js", // req js/lang.js moz/prefs.js moz/filesystem.js
|
||||
|
||||
"chrome://global/content/url-classifier/map.js",
|
||||
"chrome://global/content/url-classifier/url-canonicalizer.js"
|
||||
];
|
||||
|
||||
|
@ -24,22 +63,33 @@ for (var i = 0, libFile; libFile = LIB_FILES[i]; ++i) {
|
|||
}
|
||||
|
||||
function UrlClassifierTableUrl() {
|
||||
G_Map.call(this);
|
||||
this.debugZone = "trtable-url";
|
||||
this.dbservice_ = Cc["@mozilla.org/url-classifier/dbservice;1"]
|
||||
.getService(Ci.nsIUrlClassifierDBService);
|
||||
this.name = '';
|
||||
this.needsUpdate = false;
|
||||
}
|
||||
|
||||
UrlClassifierTableUrl.inherits(G_Map);
|
||||
UrlClassifierTableUrl.prototype.QueryInterface = function(iid) {
|
||||
if (iid.equals(Components.interfaces.nsISupports) ||
|
||||
iid.equals(Components.interfaces.nsIUrlClassifierTable))
|
||||
return this;
|
||||
Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up a URL in a URL table
|
||||
*
|
||||
* @returns Boolean true if the canonicalized url is in the table
|
||||
*/
|
||||
UrlClassifierTableUrl.prototype.exists = function(url) {
|
||||
UrlClassifierTableUrl.prototype.exists = function(url, callback) {
|
||||
var canonicalized = PROT_URLCanonicalizer.canonicalizeURL_(url);
|
||||
// Uncomment for debugging
|
||||
G_Debug(this, "Looking up: " + url + " (" + canonicalized + ")");
|
||||
return this.find_(canonicalized);
|
||||
|
||||
function dbCallback(v) {
|
||||
G_Debug("dbCallback", "Looked up " + url + ": " + v + "|");
|
||||
callback.handleEvent(v.length > 0);
|
||||
}
|
||||
this.dbservice_.exists(this.name, url, dbCallback);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,45 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Url Classifier code
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Tony Chang <tony@ponderer.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// TODO: Rename this file to nsUrlClassifierListManager.js
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const G_GDEBUG = true;
|
||||
const G_GDEBUG = false;
|
||||
|
||||
// Use subscript loader to load files. The files in ../content get mapped
|
||||
// to chrome://global/content/url-classifier/. Order matters if one file depends
|
||||
|
|
Загрузка…
Ссылка в новой задаче