home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Minami 83
/
MINAMI83.iso
/
Extra
/
DivXInstaller.exe
/
$PLUGINSDIR
/
GoogleToolbarFirefox.msi
/
xpi
/
amulet-jslib
/
content-analyzer.js
< prev
next >
Wrap
Text File
|
2006-08-07
|
11KB
|
326 lines
function PROT_ContentAnalyzer(listWarden, threadQueue, opt_testing) {
this.listWarden_ = listWarden;
this.threadQueue_ = threadQueue;
this.testing_ = !!opt_testing;
this.debugZone = "contentanalyzer";
this.docs_ = [];
this.time_ = PROT_ContentAnalyzer.MIN_TIME;
this.numNodes_ = PROT_ContentAnalyzer.MIN_NODES;
this.reportURL = PROT_globalStore.getResultsReportURL();
this.urlCrypto_ = null;
this.useCrypto_ = !this.testing_;
this.prefs_ = new G_Preferences();
var contentAnalyzerEnabledPrefName =
PROT_globalStore.getContentAnalyzerEnabledPrefName();
var contentAnalyzerPrefObserver = BindToObject(this.onPrefChanged,
this);
this.prefs_.addObserver(contentAnalyzerEnabledPrefName,
contentAnalyzerPrefObserver);
this.isEnabled_ = false;
this.onPrefChanged(contentAnalyzerEnabledPrefName);
G_Debug(this, "content analyzer initialized");
}
PROT_ContentAnalyzer.MAX_DOCS = 3;
PROT_ContentAnalyzer.MAX_TIME = 60*1000;
PROT_ContentAnalyzer.MAX_NODES = 500;
PROT_ContentAnalyzer.prototype.onPrefChanged = function(prefName) {
this.isEnabled_ = this.prefs_.getPref(prefName, false);
var compatibleVersion = (new G_ThisFirefoxVersion()).
compareToString("1.5.0.2");
if (compatibleVersion < 0)
this.isEnabled_ = false;
this.maybeToggleDoWork();
}
PROT_ContentAnalyzer.prototype.maybeToggleDoWork = function() {
if (this.isEnabled_ === true) {
this.iterator_ = new PROT_SafeDOMIterator(this.listWarden_,
this,
this.threadQueue_);
this.alarm_ = new G_Alarm(BindToObject(this.doWork, this),
1000,
true /* repeating */);
} else if (this.isEnabled_ === false) {
if (this.alarm_) {
this.alarm_.cancel();
this.alarm_ = null;
}
if (this.iterator_) {
this.iterator_.shutdown();
this.iterator_ = null;
}
}
}
PROT_ContentAnalyzer.prototype.maybeAnalyzeDoc = function(doc) {
if (!this.isEnabled_ || !doc || !doc.URL)
return;
this.listWarden_.isWhiteURL(doc.URL,
BindToObject(this.maybeAnalyzeDoc_,
this, doc));
}
PROT_ContentAnalyzer.prototype.maybeAnalyzeDoc_ = function(doc, status) {
if (PROT_ListWarden.IN_WHITELIST == status)
return;
G_Debug(this, "Not in whitelist: " + doc.URL);
if (this.docs_.length < PROT_ContentAnalyzer.MAX_DOCS) {
this.docs_.push(doc);
G_Debug(this, "pushing " + doc.URL.slice(-50));
this.numDrops_ = 0;
} else {
G_Debug(this, this.docs_.length + " docs on queue, skipping " + doc.URL.slice(-50));
this.numDrops_++;
if (this.numDrops_ >= 2) {
G_Debug(this, "too many drops, aborting");
this.iterator_.abort();
}
}
}
PROT_ContentAnalyzer.prototype.doWork = function() {
if (!this.isEnabled_)
return;
if (this.docs_.length > 0 && this.iterator_.isReady()) {
this.iterator_.start(this.docs_[0],
PROT_ContentAnalyzer.MAX_TIME,
PROT_ContentAnalyzer.MAX_NODES);
}
}
PROT_ContentAnalyzer.prototype.reportResults = function(doc, results) {
if (!this.urlCrypto_)
this.urlCrypto_ = new PROT_UrlCrypto();
var reportURL = this.reportURL;
var params = {"url": doc.URL, "results": results};
if (this.useCrypto_) {
params = this.urlCrypto_.maybeCryptParams(params);
}
for (var param in params) {
reportURL += param + "=" +
encodeURIComponent(params[param]) + "&";
}
G_Debug(this, "reportURL: " + reportURL);
if (this.prefs_.getPref(PROT_globalStore.getSendUserReportsPrefName(),
false))
(new PROT_XMLFetcher(true /* strip cookies */)).get(reportURL, null /* no cb */);
}
PROT_ContentAnalyzer.prototype.docIsComplete = function(doc, results) {
if (!this.testing_ && results != "") {
this.reportResults(doc, results);
}
if (results == "")
G_Debug(this, "empty results for " + doc.URL.slice(-50));
else
G_Debug(this, "sandbox results for " + doc.URL + ": " + results);
this.docs_.shift();
}
function PROT_SafeDOMIterator(listWarden, contentAnalyzer, threadQueue) {
this.contentAnalyzer_ = contentAnalyzer;
this.threadQueue_ = threadQueue;
this.debugZone = "domiterator";
this.registrar_ = new EventRegistrar(["abort", "reset", "results", "meta"]);
this.attrs = {};
this.status_ = PROT_SafeDOMIterator.states.READY;
this.sandboxMgr_ = new PROT_SandboxManager(this,
listWarden,
"goog-sandbox-text");
}
PROT_SafeDOMIterator.prototype.shutdown = function() {
this.sandboxMgr_.shutdown();
}
PROT_SafeDOMIterator.whatToShow = Ci.nsIDOMNodeFilter.SHOW_ELEMENT |
Ci.nsIDOMNodeFilter.SHOW_TEXT;
PROT_SafeDOMIterator.CHUNK_SIZE = 10;
PROT_SafeDOMIterator.states = { WORKING: "working",
READY: "ready",
ABORT: "abort"}
PROT_SafeDOMIterator.MULTIPLIER = 2.5;
PROT_SafeDOMIterator.prototype.start = function(doc, maxTime, maxNodes) {
if (!doc || !this.isReady()) {
G_Debug(this, "is ready: " + this.isReady());
return;
}
this.doc_ = doc;
this.maxTime_ = maxTime;
this.maxNodes_ = maxNodes;
this.fire("reset", {});
this.fire("meta", { url: doc.URL,
title: doc.title,
referrer: doc.referrer,
callback: BindToObject(this.maybeStartWalk, this) });
}
PROT_SafeDOMIterator.prototype.maybeStartWalk = function(shouldWalk) {
if (!shouldWalk) {
this.status_ = PROT_SafeDOMIterator.states.READY;
G_Debug(this, "sandbox not interested, ignoring " + this.doc_.URL.slice(-50));
this.contentAnalyzer_.docIsComplete(this.doc_, "");
return;
}
this.status_ = PROT_SafeDOMIterator.states.WORKING;
this.iter_ = this.doc_.createTreeWalker(this.doc_.documentElement,
PROT_SafeDOMIterator.whatToShow,
null, /* no NodeFilter */
true /* expand entities */);
new G_Alarm(BindToObject(this.abort, this), this.maxTime_);
this.alarm_ = new G_ConditionalAlarm(BindToObject(this.maybeAbort, this),
1*1000 /* period in ms */,
true /* repeating */);
this.targetNodes_ =
PROT_SafeDOMIterator.CHUNK_SIZE*PROT_SafeDOMIterator.MULTIPLIER;
this.numNodes_ = 0;
this.threadQueue_.addWorker(BindToObject(this.walkDOM, this),
BindToObject(this.finishIfComplete, this));
this.threadQueue_.run();
}
PROT_SafeDOMIterator.prototype.maybeAbort = function() {
if (this.numNodes_ < this.targetNodes_ ||
!this.iter_.currentNode ||
this.numNodes_ >= this.maxNodes_) {
this.abort();
return true;
}
this.targetNodes_ = this.numNodes_ +
PROT_SafeDOMIterator.CHUNK_SIZE*PROT_SafeDOMIterator.MULTIPLIER;
G_Debug(this, "current nodes: " + this.numNodes_ + " target nodes: " +
this.targetNodes_);
return false;
}
PROT_SafeDOMIterator.prototype.extractFeatures = function(n) {
if (!(this.attrs.hasOwnProperty(n.nodeName)))
return;
var attrs = this.attrs[n.nodeName];
var values = {};
var MAX_LEN = 1024; // Never pass more than 1K to the sandbox
values.nodeName = n.nodeName;
for (var i = 0; i < attrs.length; i++) {
if (attrs[i] == "nodeValue" && n.nodeName == "#text") {
values[attrs[i]] = n[attrs[i]].toString().substring(0, MAX_LEN);
} else if (n.getAttribute(attrs[i])) {
values[attrs[i]] = n.getAttribute(attrs[i]).substring(0, MAX_LEN);
} else {
values[attrs[i]] = "undefined";
}
}
return values;
}
PROT_SafeDOMIterator.prototype.union = function(attrs1, attrs2) {
var newattrs = attrs1.concat(attrs2);
newattrs = newattrs.sort();
for (var i = newattrs.length-1; i >= 1; i--) {
if (newattrs[i] == newattrs[i-1] || !newattrs[i])
newattrs.splice(i, 1);
}
return newattrs;
}
PROT_SafeDOMIterator.prototype.registerEvent = function(eventType, attrs) {
if (!this.registrar_.isKnownEventType(eventType)) {
this.registrar_.addEventType(eventType);
}
if (!this.attrs[eventType])
this.attrs[eventType] = [];
this.attrs[eventType] = this.union(this.attrs[eventType], attrs);
}
PROT_SafeDOMIterator.prototype.registerHandler = function(nodeName,
handler,
attrs) {
this.registrar_.registerListener(nodeName, handler);
this.registerEvent(nodeName, attrs);
}
PROT_SafeDOMIterator.prototype.removeHandlers = function() {
this.registrar_ = new EventRegistrar(["abort", "reset", "results", "meta"]);
}
PROT_SafeDOMIterator.prototype.fire = function(eventType, e) {
this.registrar_.fire(eventType, e);
}
PROT_SafeDOMIterator.prototype.walkDOM = function() {
for (var i = 0; i < PROT_SafeDOMIterator.CHUNK_SIZE; i++) {
var n = this.iter_.nextNode();
if (!n)
return;
if (!(this.attrs.hasOwnProperty(n.nodeName))) {
continue;
}
var event = this.extractFeatures(n);
event.callback = BindToObject(this.maybeSetAbort, this);
this.fire(n.nodeName, event);
}
this.numNodes_ += PROT_SafeDOMIterator.CHUNK_SIZE;
G_Debug(this, "curr number nodes: " + this.numNodes_);
}
PROT_SafeDOMIterator.prototype.finishIfComplete = function() {
if (this.shouldAbort() || this.numNodes_ >= this.maxNodes_) {
G_Debug(this, "done. aborting: " + this.shouldAbort());
this.fire("results", { callback: BindToObject(this.getResults, this) });
return true;
}
G_Debug(this, "not done yet");
return false;
}
PROT_SafeDOMIterator.prototype.isReady = function() {
return this.status_ == PROT_SafeDOMIterator.states.READY &&
this.sandboxMgr_.hasData();
}
PROT_SafeDOMIterator.prototype.abort = function() {
if (this.status_ == PROT_SafeDOMIterator.states.WORKING) {
G_Debug(this, "aborting");
this.status_ = PROT_SafeDOMIterator.states.ABORT;
this.alarm_.cancel();
this.alarm_ = null;
} else {
}
}
PROT_SafeDOMIterator.prototype.shouldAbort = function() {
return this.status_ == PROT_SafeDOMIterator.states.ABORT;
}
PROT_SafeDOMIterator.prototype.maybeSetAbort = function(should_abort) {
if (should_abort && !this.isReady()) {
this.status_ = PROT_SafeDOMIterator.states.ABORT;
}
}
PROT_SafeDOMIterator.prototype.getResults = function(results) {
this.status_ = PROT_SafeDOMIterator.states.READY;
if (typeof results != "string") {
G_Debug(this, "sandbox returned wrong type for results: " + typeof
results);
} else {
this.contentAnalyzer_.docIsComplete(this.doc_, results);
}
}
var TEST_PROT_ContentAnalyzer = function(doc, listWarden) {
var z = "contentanalyzer UNITTEST";
G_debugService.enableZone(z);
G_Debug(z, "Starting");
var contentAnalyzer = new PROT_ContentAnalyzer(listWarden,
new TH_ThreadQueue(),
true /* testing */);
var createDocFromString = function(doc, s, opt_id) {
var iframe = doc.createElement("iframe");
doc.documentElement.appendChild(iframe);
iframe.setAttribute('id', opt_id);
iframe.style.maxHeight = '0px';
iframe.style.minHeight = '0px !important';
var innerdoc = iframe.contentDocument;
innerdoc.write(s);
function docNClosure(doc, closure) {
this.doc = doc;
this.closure = closure;
}
function close() {
doc.documentElement.removeChild(iframe);
}
return new docNClosure(innerdoc, close);
}
var iframeHtml = "<h1>Ebay affiliate</h1>";
iframeHtml += "<img src=http://pics.ebaystatic.com/aw/pics/logos/logoEbay_150x70.gif>";
iframeHtml += "<a href=http://ourpaypal.com>paypal.com</a>";
iframeHtml += "<a href=http://paypal.com/privacy.html>Privacy policy</a>";
iframeHtml += "<a href=http://somewhere.com>Not a juicy link</a>";
iframeHtml += "<img src=http://somewhere_else.com>";
iframeHtml += "<b><form action=\"/bad\" method=\"post\"><input type=\"text\" name=\"cc\">your credit card here</form>";
var docNClosure = createDocFromString(doc,
iframeHtml,
'unittestiframe');
new G_Alarm(BindToObject(contentAnalyzer.maybeAnalyzeDoc,
contentAnalyzer,
docNClosure.doc),
5000);
new G_Alarm(docNClosure.closure, 10*1000);
new G_Alarm(function() { G_Debug(z, "Passed"); }, 15*1000);
}