From 52ba2d69c164dc121deefa26ea9f99453c2b2e6a Mon Sep 17 00:00:00 2001 From: Elbert Alias Date: Sun, 14 Oct 2012 10:38:41 +1100 Subject: [PATCH] Performance improvements --- drivers/bookmarklet/js/wappalyzer.js | 246 +++++++++++++-------- drivers/chrome/js/wappalyzer.js | 246 +++++++++++++-------- drivers/firefox-jetpack/lib/wappalyzer.js | 246 +++++++++++++-------- drivers/firefox/content/js/content.js | 35 +-- drivers/firefox/content/js/wappalyzer.js | 246 +++++++++++++-------- drivers/html/js/wappalyzer.js | 246 +++++++++++++-------- drivers/php/js/wappalyzer.js | 246 +++++++++++++-------- share/js/wappalyzer.js | 249 +++++++++++++--------- 8 files changed, 1088 insertions(+), 672 deletions(-) diff --git a/drivers/bookmarklet/js/wappalyzer.js b/drivers/bookmarklet/js/wappalyzer.js index 27542339a..edcd0192e 100644 --- a/drivers/bookmarklet/js/wappalyzer.js +++ b/drivers/bookmarklet/js/wappalyzer.js @@ -92,162 +92,222 @@ var wappalyzer = wappalyzer || (function() { analyze: function(hostname, url, data) { w.log('w.analyze'); + data.url = url; + if ( w.apps == null || w.categories == null ) { w.log('apps.json not loaded'); return; } - var i, app, type, regex, match, content, meta, header, apps = []; + if ( w.detected[url] == null ) { + w.detected[url] = []; + } - if ( w.detected[url] == null ) { w.detected[url] = []; } + var + i, app, type, regex, match, content, meta, header, + profiler = { + regexCount: 0, + startTime: ( new Date ).getTime() + }, + apps = [] + ; + + for ( app in w.apps ) { + // Skip if the app has already been detected + if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { + continue; + } - if ( data ) { - for ( app in w.apps ) { - for ( type in w.apps[app] ) { - if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { continue; } // Skip if the app has already been detected + next: - switch ( type ) { - case 'url': - if ( w.apps[app].url.test(url) ) { apps.push(app); } + for ( type in w.apps[app] ) { + if ( data[type] == null ) { + continue; + } - break; - case 'html': - if ( data[type] == null ) { break; } + switch ( type ) { + case 'url': + regex = new RegExp(w.apps[app][type], 'i'); + + profiler.regexCount ++; + + if ( regex.test(url) ) { + apps.push(app); - if ( w.apps[app][type].test(data[type]) ) { apps.push(app); } + break next; + } + + break; + case 'html': + regex = new RegExp(w.apps[app][type], 'i'); + + profiler.regexCount ++; + + if ( regex.test(data[type]) ) { + apps.push(app); + + break next; + } + break; + case 'script': + if ( data['html'] == null ) { break; - case 'script': - if ( data['html'] == null ) { break; } + } - regex = /]+src=("|')([^"']+)\1/ig; + regex = new RegExp(w.apps[app][type], 'i'); - while ( match = regex.exec(data['html']) ) { - if ( w.apps[app][type].test(match[2]) ) { - apps.push(app); + profiler.regexCount ++; - break; - } + while ( match = new RegExp(']+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { + profiler.regexCount ++; + + if ( regex.test(match[2]) ) { + apps.push(app); + + break next; } + } + break; + case 'meta': + if ( data['html'] == null ) { break; - case 'meta': - if ( data['html'] == null ) { break; } + } + + profiler.regexCount ++; - regex = /]+>/ig; + while ( match = new RegExp(']+>', 'ig').exec(data['html']) ) { + for ( meta in w.apps[app][type] ) { + profiler.regexCount ++; - while ( match = regex.exec(data['html']) ) { - for ( meta in w.apps[app][type] ) { - if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { - content = match.toString().match(/content=("|')([^"']+)("|')/i); + if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { + content = match.toString().match(/content=("|')([^"']+)("|')/i); - if ( content && content.length == 4 && w.apps[app].meta[meta].test(content[2]) ) { - apps.push(app); + regex = new RegExp(w.apps[app].meta[meta], 'i'); - break; - } + profiler.regexCount ++; + + if ( content && content.length === 4 && regex.test(content[2]) ) { + apps.push(app); + + break next; } } } + } + break; + case 'headers': + if ( data[type] == null ) { break; - case 'headers': - if ( data[type] == null ) { break; } + } - for ( header in w.apps[app].headers ) { - if ( data[type][header] != null && w.apps[app][type][header].test(data[type][header]) ) { - apps.push(app); + for ( header in w.apps[app].headers ) { + regex = new RegExp(w.apps[app][type][header], 'i'); - break; - } + profiler.regexCount ++; + + if ( data[type][header] != null && regex.test(data[type][header]) ) { + apps.push(app); + + break next; } + } + break; + case 'env': + if ( data[type] == null ) { break; - case 'env': - if ( data[type] == null ) { break; } + } - for ( i in data[type] ) { - if ( w.apps[app][type].test(data[type][i]) ) { - apps.push(app); + regex = RegExp(w.apps[app][type], 'i'); - break; - } + for ( i in data[type] ) { + profiler.regexCount ++; + + if ( regex.test(data[type][i]) ) { + apps.push(app); + + break next; } + } - break; - } + break; } } + } - // Implied applications - var i, j, k, implied; + w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); - for ( i = 0; i < 3; i ++ ) { - for ( j in apps ) { - if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { - for ( k in w.apps[apps[j]].implies ) { - implied = w.apps[apps[j]].implies[k]; + // Implied applications + var i, j, k, implied; - if ( !w.apps[implied] ) { - w.log('Implied application ' + implied + ' does not exist'); + for ( i = 0; i < 3; i ++ ) { + for ( j in apps ) { + if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { + for ( k in w.apps[apps[j]].implies ) { + implied = w.apps[apps[j]].implies[k]; - continue; - } + if ( !w.apps[implied] ) { + w.log('Implied application ' + implied + ' does not exist'); - if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { - apps.push(implied); - } + continue; + } + + if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { + apps.push(implied); } } } } + } - w.log(apps.length + ' apps detected: ' + apps.join(', ')); - - // Keep history of detected apps - var i, app, match; + w.log(apps.length + ' apps detected: ' + apps.join(', ')); - for ( i in apps ) { - app = apps[i]; + // Keep history of detected apps + var i, app, match; - // Per hostname - if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { - if ( typeof w.ping.hostnames === 'undefined' ) { - w.ping.hostnames = {}; - } + for ( i in apps ) { + app = apps[i]; - if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { - w.ping.hostnames[hostname] = { applications: {}, meta: {} }; - } + // Per hostname + if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { + if ( typeof w.ping.hostnames === 'undefined' ) { + w.ping.hostnames = {}; + } - if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { - w.ping.hostnames[hostname].applications[app] = 1; - } + if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { + w.ping.hostnames[hostname] = { applications: {}, meta: {} }; + } - w.ping.hostnames[hostname].applications[app] ++; + if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { + w.ping.hostnames[hostname].applications[app] = 1; } - // Per URL - if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + w.ping.hostnames[hostname].applications[app] ++; } - // Additional information - if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { - if ( data.html != null ) { - match = data.html.match(/]*[: ]lang="([^"]+)"/); + // Per URL + if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + } - if ( match != null && match.length ) { - w.ping.hostnames[hostname].meta['language'] = match[1]; - } + // Additional information + if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { + if ( data.html != null ) { + match = data.html.match(/]*[: ]lang="([^"]+)"/); + + if ( match != null && match.length ) { + w.ping.hostnames[hostname].meta['language'] = match[1]; } } + } - if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } + if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } - apps = null; - data = null; - } + apps = null; + data = null; driver('displayApps'); } diff --git a/drivers/chrome/js/wappalyzer.js b/drivers/chrome/js/wappalyzer.js index 27542339a..edcd0192e 100644 --- a/drivers/chrome/js/wappalyzer.js +++ b/drivers/chrome/js/wappalyzer.js @@ -92,162 +92,222 @@ var wappalyzer = wappalyzer || (function() { analyze: function(hostname, url, data) { w.log('w.analyze'); + data.url = url; + if ( w.apps == null || w.categories == null ) { w.log('apps.json not loaded'); return; } - var i, app, type, regex, match, content, meta, header, apps = []; + if ( w.detected[url] == null ) { + w.detected[url] = []; + } - if ( w.detected[url] == null ) { w.detected[url] = []; } + var + i, app, type, regex, match, content, meta, header, + profiler = { + regexCount: 0, + startTime: ( new Date ).getTime() + }, + apps = [] + ; + + for ( app in w.apps ) { + // Skip if the app has already been detected + if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { + continue; + } - if ( data ) { - for ( app in w.apps ) { - for ( type in w.apps[app] ) { - if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { continue; } // Skip if the app has already been detected + next: - switch ( type ) { - case 'url': - if ( w.apps[app].url.test(url) ) { apps.push(app); } + for ( type in w.apps[app] ) { + if ( data[type] == null ) { + continue; + } - break; - case 'html': - if ( data[type] == null ) { break; } + switch ( type ) { + case 'url': + regex = new RegExp(w.apps[app][type], 'i'); + + profiler.regexCount ++; + + if ( regex.test(url) ) { + apps.push(app); - if ( w.apps[app][type].test(data[type]) ) { apps.push(app); } + break next; + } + + break; + case 'html': + regex = new RegExp(w.apps[app][type], 'i'); + + profiler.regexCount ++; + + if ( regex.test(data[type]) ) { + apps.push(app); + + break next; + } + break; + case 'script': + if ( data['html'] == null ) { break; - case 'script': - if ( data['html'] == null ) { break; } + } - regex = /]+src=("|')([^"']+)\1/ig; + regex = new RegExp(w.apps[app][type], 'i'); - while ( match = regex.exec(data['html']) ) { - if ( w.apps[app][type].test(match[2]) ) { - apps.push(app); + profiler.regexCount ++; - break; - } + while ( match = new RegExp(']+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { + profiler.regexCount ++; + + if ( regex.test(match[2]) ) { + apps.push(app); + + break next; } + } + break; + case 'meta': + if ( data['html'] == null ) { break; - case 'meta': - if ( data['html'] == null ) { break; } + } + + profiler.regexCount ++; - regex = /]+>/ig; + while ( match = new RegExp(']+>', 'ig').exec(data['html']) ) { + for ( meta in w.apps[app][type] ) { + profiler.regexCount ++; - while ( match = regex.exec(data['html']) ) { - for ( meta in w.apps[app][type] ) { - if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { - content = match.toString().match(/content=("|')([^"']+)("|')/i); + if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { + content = match.toString().match(/content=("|')([^"']+)("|')/i); - if ( content && content.length == 4 && w.apps[app].meta[meta].test(content[2]) ) { - apps.push(app); + regex = new RegExp(w.apps[app].meta[meta], 'i'); - break; - } + profiler.regexCount ++; + + if ( content && content.length === 4 && regex.test(content[2]) ) { + apps.push(app); + + break next; } } } + } + break; + case 'headers': + if ( data[type] == null ) { break; - case 'headers': - if ( data[type] == null ) { break; } + } - for ( header in w.apps[app].headers ) { - if ( data[type][header] != null && w.apps[app][type][header].test(data[type][header]) ) { - apps.push(app); + for ( header in w.apps[app].headers ) { + regex = new RegExp(w.apps[app][type][header], 'i'); - break; - } + profiler.regexCount ++; + + if ( data[type][header] != null && regex.test(data[type][header]) ) { + apps.push(app); + + break next; } + } + break; + case 'env': + if ( data[type] == null ) { break; - case 'env': - if ( data[type] == null ) { break; } + } - for ( i in data[type] ) { - if ( w.apps[app][type].test(data[type][i]) ) { - apps.push(app); + regex = RegExp(w.apps[app][type], 'i'); - break; - } + for ( i in data[type] ) { + profiler.regexCount ++; + + if ( regex.test(data[type][i]) ) { + apps.push(app); + + break next; } + } - break; - } + break; } } + } - // Implied applications - var i, j, k, implied; + w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); - for ( i = 0; i < 3; i ++ ) { - for ( j in apps ) { - if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { - for ( k in w.apps[apps[j]].implies ) { - implied = w.apps[apps[j]].implies[k]; + // Implied applications + var i, j, k, implied; - if ( !w.apps[implied] ) { - w.log('Implied application ' + implied + ' does not exist'); + for ( i = 0; i < 3; i ++ ) { + for ( j in apps ) { + if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { + for ( k in w.apps[apps[j]].implies ) { + implied = w.apps[apps[j]].implies[k]; - continue; - } + if ( !w.apps[implied] ) { + w.log('Implied application ' + implied + ' does not exist'); - if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { - apps.push(implied); - } + continue; + } + + if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { + apps.push(implied); } } } } + } - w.log(apps.length + ' apps detected: ' + apps.join(', ')); - - // Keep history of detected apps - var i, app, match; + w.log(apps.length + ' apps detected: ' + apps.join(', ')); - for ( i in apps ) { - app = apps[i]; + // Keep history of detected apps + var i, app, match; - // Per hostname - if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { - if ( typeof w.ping.hostnames === 'undefined' ) { - w.ping.hostnames = {}; - } + for ( i in apps ) { + app = apps[i]; - if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { - w.ping.hostnames[hostname] = { applications: {}, meta: {} }; - } + // Per hostname + if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { + if ( typeof w.ping.hostnames === 'undefined' ) { + w.ping.hostnames = {}; + } - if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { - w.ping.hostnames[hostname].applications[app] = 1; - } + if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { + w.ping.hostnames[hostname] = { applications: {}, meta: {} }; + } - w.ping.hostnames[hostname].applications[app] ++; + if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { + w.ping.hostnames[hostname].applications[app] = 1; } - // Per URL - if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + w.ping.hostnames[hostname].applications[app] ++; } - // Additional information - if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { - if ( data.html != null ) { - match = data.html.match(/]*[: ]lang="([^"]+)"/); + // Per URL + if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + } - if ( match != null && match.length ) { - w.ping.hostnames[hostname].meta['language'] = match[1]; - } + // Additional information + if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { + if ( data.html != null ) { + match = data.html.match(/]*[: ]lang="([^"]+)"/); + + if ( match != null && match.length ) { + w.ping.hostnames[hostname].meta['language'] = match[1]; } } + } - if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } + if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } - apps = null; - data = null; - } + apps = null; + data = null; driver('displayApps'); } diff --git a/drivers/firefox-jetpack/lib/wappalyzer.js b/drivers/firefox-jetpack/lib/wappalyzer.js index 27542339a..edcd0192e 100644 --- a/drivers/firefox-jetpack/lib/wappalyzer.js +++ b/drivers/firefox-jetpack/lib/wappalyzer.js @@ -92,162 +92,222 @@ var wappalyzer = wappalyzer || (function() { analyze: function(hostname, url, data) { w.log('w.analyze'); + data.url = url; + if ( w.apps == null || w.categories == null ) { w.log('apps.json not loaded'); return; } - var i, app, type, regex, match, content, meta, header, apps = []; + if ( w.detected[url] == null ) { + w.detected[url] = []; + } - if ( w.detected[url] == null ) { w.detected[url] = []; } + var + i, app, type, regex, match, content, meta, header, + profiler = { + regexCount: 0, + startTime: ( new Date ).getTime() + }, + apps = [] + ; + + for ( app in w.apps ) { + // Skip if the app has already been detected + if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { + continue; + } - if ( data ) { - for ( app in w.apps ) { - for ( type in w.apps[app] ) { - if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { continue; } // Skip if the app has already been detected + next: - switch ( type ) { - case 'url': - if ( w.apps[app].url.test(url) ) { apps.push(app); } + for ( type in w.apps[app] ) { + if ( data[type] == null ) { + continue; + } - break; - case 'html': - if ( data[type] == null ) { break; } + switch ( type ) { + case 'url': + regex = new RegExp(w.apps[app][type], 'i'); + + profiler.regexCount ++; + + if ( regex.test(url) ) { + apps.push(app); - if ( w.apps[app][type].test(data[type]) ) { apps.push(app); } + break next; + } + + break; + case 'html': + regex = new RegExp(w.apps[app][type], 'i'); + + profiler.regexCount ++; + + if ( regex.test(data[type]) ) { + apps.push(app); + + break next; + } + break; + case 'script': + if ( data['html'] == null ) { break; - case 'script': - if ( data['html'] == null ) { break; } + } - regex = /]+src=("|')([^"']+)\1/ig; + regex = new RegExp(w.apps[app][type], 'i'); - while ( match = regex.exec(data['html']) ) { - if ( w.apps[app][type].test(match[2]) ) { - apps.push(app); + profiler.regexCount ++; - break; - } + while ( match = new RegExp(']+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { + profiler.regexCount ++; + + if ( regex.test(match[2]) ) { + apps.push(app); + + break next; } + } + break; + case 'meta': + if ( data['html'] == null ) { break; - case 'meta': - if ( data['html'] == null ) { break; } + } + + profiler.regexCount ++; - regex = /]+>/ig; + while ( match = new RegExp(']+>', 'ig').exec(data['html']) ) { + for ( meta in w.apps[app][type] ) { + profiler.regexCount ++; - while ( match = regex.exec(data['html']) ) { - for ( meta in w.apps[app][type] ) { - if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { - content = match.toString().match(/content=("|')([^"']+)("|')/i); + if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { + content = match.toString().match(/content=("|')([^"']+)("|')/i); - if ( content && content.length == 4 && w.apps[app].meta[meta].test(content[2]) ) { - apps.push(app); + regex = new RegExp(w.apps[app].meta[meta], 'i'); - break; - } + profiler.regexCount ++; + + if ( content && content.length === 4 && regex.test(content[2]) ) { + apps.push(app); + + break next; } } } + } + break; + case 'headers': + if ( data[type] == null ) { break; - case 'headers': - if ( data[type] == null ) { break; } + } - for ( header in w.apps[app].headers ) { - if ( data[type][header] != null && w.apps[app][type][header].test(data[type][header]) ) { - apps.push(app); + for ( header in w.apps[app].headers ) { + regex = new RegExp(w.apps[app][type][header], 'i'); - break; - } + profiler.regexCount ++; + + if ( data[type][header] != null && regex.test(data[type][header]) ) { + apps.push(app); + + break next; } + } + break; + case 'env': + if ( data[type] == null ) { break; - case 'env': - if ( data[type] == null ) { break; } + } - for ( i in data[type] ) { - if ( w.apps[app][type].test(data[type][i]) ) { - apps.push(app); + regex = RegExp(w.apps[app][type], 'i'); - break; - } + for ( i in data[type] ) { + profiler.regexCount ++; + + if ( regex.test(data[type][i]) ) { + apps.push(app); + + break next; } + } - break; - } + break; } } + } - // Implied applications - var i, j, k, implied; + w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); - for ( i = 0; i < 3; i ++ ) { - for ( j in apps ) { - if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { - for ( k in w.apps[apps[j]].implies ) { - implied = w.apps[apps[j]].implies[k]; + // Implied applications + var i, j, k, implied; - if ( !w.apps[implied] ) { - w.log('Implied application ' + implied + ' does not exist'); + for ( i = 0; i < 3; i ++ ) { + for ( j in apps ) { + if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { + for ( k in w.apps[apps[j]].implies ) { + implied = w.apps[apps[j]].implies[k]; - continue; - } + if ( !w.apps[implied] ) { + w.log('Implied application ' + implied + ' does not exist'); - if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { - apps.push(implied); - } + continue; + } + + if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { + apps.push(implied); } } } } + } - w.log(apps.length + ' apps detected: ' + apps.join(', ')); - - // Keep history of detected apps - var i, app, match; + w.log(apps.length + ' apps detected: ' + apps.join(', ')); - for ( i in apps ) { - app = apps[i]; + // Keep history of detected apps + var i, app, match; - // Per hostname - if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { - if ( typeof w.ping.hostnames === 'undefined' ) { - w.ping.hostnames = {}; - } + for ( i in apps ) { + app = apps[i]; - if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { - w.ping.hostnames[hostname] = { applications: {}, meta: {} }; - } + // Per hostname + if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { + if ( typeof w.ping.hostnames === 'undefined' ) { + w.ping.hostnames = {}; + } - if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { - w.ping.hostnames[hostname].applications[app] = 1; - } + if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { + w.ping.hostnames[hostname] = { applications: {}, meta: {} }; + } - w.ping.hostnames[hostname].applications[app] ++; + if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { + w.ping.hostnames[hostname].applications[app] = 1; } - // Per URL - if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + w.ping.hostnames[hostname].applications[app] ++; } - // Additional information - if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { - if ( data.html != null ) { - match = data.html.match(/]*[: ]lang="([^"]+)"/); + // Per URL + if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + } - if ( match != null && match.length ) { - w.ping.hostnames[hostname].meta['language'] = match[1]; - } + // Additional information + if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { + if ( data.html != null ) { + match = data.html.match(/]*[: ]lang="([^"]+)"/); + + if ( match != null && match.length ) { + w.ping.hostnames[hostname].meta['language'] = match[1]; } } + } - if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } + if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } - apps = null; - data = null; - } + apps = null; + data = null; driver('displayApps'); } diff --git a/drivers/firefox/content/js/content.js b/drivers/firefox/content/js/content.js index 60927bb97..410ba565c 100644 --- a/drivers/firefox/content/js/content.js +++ b/drivers/firefox/content/js/content.js @@ -2,33 +2,37 @@ (function() { var - lastEnv = null, - prefs = {} + data = {}, + lastEnv = [], + prefs = null ; addEventListener('DOMContentLoaded', function() { removeEventListener('DOMContentLoaded', onLoad, false); + if ( prefs != null || content.document.contentType != 'text/html' ) { + return; + } + prefs = sendSyncMessage('wappalyzer', { action: 'get prefs' })[0]; onLoad(); }, false); function onLoad() { - if ( content.document.contentType != 'text/html' ) { return; } - - if ( prefs.analyzeOnLoad ) { + if ( prefs.analyzeJavaScript && prefs.analyzeOnLoad ) { content.document.documentElement.addEventListener('load', function() { var env = Object.keys(content.wrappedJSObject); - if ( env.join() !== lastEnv ) { - lastEnv = env.join(); + // Only analyze new variables + data = { env: env.filter(function(i) { return lastEnv.indexOf(i) === -1; }) }; + + lastEnv = env; + if ( data.env.length ) { sendAsyncMessage('wappalyzer', { action: 'analyze', - analyze: { - env: Object.keys(content.wrappedJSObject) - } + analyze: data }); } @@ -48,14 +52,17 @@ html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length); } + data = { html: html }; + + if ( prefs.analyzeJavaScript ) { + data.env = Object.keys(content.wrappedJSObject); + } + sendAsyncMessage('wappalyzer', { action: 'analyze', hostname: content.location.hostname, url: content.location.href, - analyze: { - html: html, - env: prefs.analyzeJavaScript ? Object.keys(content.wrappedJSObject) : [] - } + analyze: data }); } })(); diff --git a/drivers/firefox/content/js/wappalyzer.js b/drivers/firefox/content/js/wappalyzer.js index 27542339a..edcd0192e 100644 --- a/drivers/firefox/content/js/wappalyzer.js +++ b/drivers/firefox/content/js/wappalyzer.js @@ -92,162 +92,222 @@ var wappalyzer = wappalyzer || (function() { analyze: function(hostname, url, data) { w.log('w.analyze'); + data.url = url; + if ( w.apps == null || w.categories == null ) { w.log('apps.json not loaded'); return; } - var i, app, type, regex, match, content, meta, header, apps = []; + if ( w.detected[url] == null ) { + w.detected[url] = []; + } - if ( w.detected[url] == null ) { w.detected[url] = []; } + var + i, app, type, regex, match, content, meta, header, + profiler = { + regexCount: 0, + startTime: ( new Date ).getTime() + }, + apps = [] + ; + + for ( app in w.apps ) { + // Skip if the app has already been detected + if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { + continue; + } - if ( data ) { - for ( app in w.apps ) { - for ( type in w.apps[app] ) { - if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { continue; } // Skip if the app has already been detected + next: - switch ( type ) { - case 'url': - if ( w.apps[app].url.test(url) ) { apps.push(app); } + for ( type in w.apps[app] ) { + if ( data[type] == null ) { + continue; + } - break; - case 'html': - if ( data[type] == null ) { break; } + switch ( type ) { + case 'url': + regex = new RegExp(w.apps[app][type], 'i'); + + profiler.regexCount ++; + + if ( regex.test(url) ) { + apps.push(app); - if ( w.apps[app][type].test(data[type]) ) { apps.push(app); } + break next; + } + + break; + case 'html': + regex = new RegExp(w.apps[app][type], 'i'); + + profiler.regexCount ++; + + if ( regex.test(data[type]) ) { + apps.push(app); + + break next; + } + break; + case 'script': + if ( data['html'] == null ) { break; - case 'script': - if ( data['html'] == null ) { break; } + } - regex = /]+src=("|')([^"']+)\1/ig; + regex = new RegExp(w.apps[app][type], 'i'); - while ( match = regex.exec(data['html']) ) { - if ( w.apps[app][type].test(match[2]) ) { - apps.push(app); + profiler.regexCount ++; - break; - } + while ( match = new RegExp(']+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { + profiler.regexCount ++; + + if ( regex.test(match[2]) ) { + apps.push(app); + + break next; } + } + break; + case 'meta': + if ( data['html'] == null ) { break; - case 'meta': - if ( data['html'] == null ) { break; } + } + + profiler.regexCount ++; - regex = /]+>/ig; + while ( match = new RegExp(']+>', 'ig').exec(data['html']) ) { + for ( meta in w.apps[app][type] ) { + profiler.regexCount ++; - while ( match = regex.exec(data['html']) ) { - for ( meta in w.apps[app][type] ) { - if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { - content = match.toString().match(/content=("|')([^"']+)("|')/i); + if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { + content = match.toString().match(/content=("|')([^"']+)("|')/i); - if ( content && content.length == 4 && w.apps[app].meta[meta].test(content[2]) ) { - apps.push(app); + regex = new RegExp(w.apps[app].meta[meta], 'i'); - break; - } + profiler.regexCount ++; + + if ( content && content.length === 4 && regex.test(content[2]) ) { + apps.push(app); + + break next; } } } + } + break; + case 'headers': + if ( data[type] == null ) { break; - case 'headers': - if ( data[type] == null ) { break; } + } - for ( header in w.apps[app].headers ) { - if ( data[type][header] != null && w.apps[app][type][header].test(data[type][header]) ) { - apps.push(app); + for ( header in w.apps[app].headers ) { + regex = new RegExp(w.apps[app][type][header], 'i'); - break; - } + profiler.regexCount ++; + + if ( data[type][header] != null && regex.test(data[type][header]) ) { + apps.push(app); + + break next; } + } + break; + case 'env': + if ( data[type] == null ) { break; - case 'env': - if ( data[type] == null ) { break; } + } - for ( i in data[type] ) { - if ( w.apps[app][type].test(data[type][i]) ) { - apps.push(app); + regex = RegExp(w.apps[app][type], 'i'); - break; - } + for ( i in data[type] ) { + profiler.regexCount ++; + + if ( regex.test(data[type][i]) ) { + apps.push(app); + + break next; } + } - break; - } + break; } } + } - // Implied applications - var i, j, k, implied; + w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); - for ( i = 0; i < 3; i ++ ) { - for ( j in apps ) { - if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { - for ( k in w.apps[apps[j]].implies ) { - implied = w.apps[apps[j]].implies[k]; + // Implied applications + var i, j, k, implied; - if ( !w.apps[implied] ) { - w.log('Implied application ' + implied + ' does not exist'); + for ( i = 0; i < 3; i ++ ) { + for ( j in apps ) { + if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { + for ( k in w.apps[apps[j]].implies ) { + implied = w.apps[apps[j]].implies[k]; - continue; - } + if ( !w.apps[implied] ) { + w.log('Implied application ' + implied + ' does not exist'); - if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { - apps.push(implied); - } + continue; + } + + if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { + apps.push(implied); } } } } + } - w.log(apps.length + ' apps detected: ' + apps.join(', ')); - - // Keep history of detected apps - var i, app, match; + w.log(apps.length + ' apps detected: ' + apps.join(', ')); - for ( i in apps ) { - app = apps[i]; + // Keep history of detected apps + var i, app, match; - // Per hostname - if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { - if ( typeof w.ping.hostnames === 'undefined' ) { - w.ping.hostnames = {}; - } + for ( i in apps ) { + app = apps[i]; - if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { - w.ping.hostnames[hostname] = { applications: {}, meta: {} }; - } + // Per hostname + if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { + if ( typeof w.ping.hostnames === 'undefined' ) { + w.ping.hostnames = {}; + } - if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { - w.ping.hostnames[hostname].applications[app] = 1; - } + if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { + w.ping.hostnames[hostname] = { applications: {}, meta: {} }; + } - w.ping.hostnames[hostname].applications[app] ++; + if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { + w.ping.hostnames[hostname].applications[app] = 1; } - // Per URL - if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + w.ping.hostnames[hostname].applications[app] ++; } - // Additional information - if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { - if ( data.html != null ) { - match = data.html.match(/]*[: ]lang="([^"]+)"/); + // Per URL + if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + } - if ( match != null && match.length ) { - w.ping.hostnames[hostname].meta['language'] = match[1]; - } + // Additional information + if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { + if ( data.html != null ) { + match = data.html.match(/]*[: ]lang="([^"]+)"/); + + if ( match != null && match.length ) { + w.ping.hostnames[hostname].meta['language'] = match[1]; } } + } - if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } + if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } - apps = null; - data = null; - } + apps = null; + data = null; driver('displayApps'); } diff --git a/drivers/html/js/wappalyzer.js b/drivers/html/js/wappalyzer.js index 27542339a..edcd0192e 100644 --- a/drivers/html/js/wappalyzer.js +++ b/drivers/html/js/wappalyzer.js @@ -92,162 +92,222 @@ var wappalyzer = wappalyzer || (function() { analyze: function(hostname, url, data) { w.log('w.analyze'); + data.url = url; + if ( w.apps == null || w.categories == null ) { w.log('apps.json not loaded'); return; } - var i, app, type, regex, match, content, meta, header, apps = []; + if ( w.detected[url] == null ) { + w.detected[url] = []; + } - if ( w.detected[url] == null ) { w.detected[url] = []; } + var + i, app, type, regex, match, content, meta, header, + profiler = { + regexCount: 0, + startTime: ( new Date ).getTime() + }, + apps = [] + ; + + for ( app in w.apps ) { + // Skip if the app has already been detected + if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { + continue; + } - if ( data ) { - for ( app in w.apps ) { - for ( type in w.apps[app] ) { - if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { continue; } // Skip if the app has already been detected + next: - switch ( type ) { - case 'url': - if ( w.apps[app].url.test(url) ) { apps.push(app); } + for ( type in w.apps[app] ) { + if ( data[type] == null ) { + continue; + } - break; - case 'html': - if ( data[type] == null ) { break; } + switch ( type ) { + case 'url': + regex = new RegExp(w.apps[app][type], 'i'); + + profiler.regexCount ++; + + if ( regex.test(url) ) { + apps.push(app); - if ( w.apps[app][type].test(data[type]) ) { apps.push(app); } + break next; + } + + break; + case 'html': + regex = new RegExp(w.apps[app][type], 'i'); + + profiler.regexCount ++; + + if ( regex.test(data[type]) ) { + apps.push(app); + + break next; + } + break; + case 'script': + if ( data['html'] == null ) { break; - case 'script': - if ( data['html'] == null ) { break; } + } - regex = /]+src=("|')([^"']+)\1/ig; + regex = new RegExp(w.apps[app][type], 'i'); - while ( match = regex.exec(data['html']) ) { - if ( w.apps[app][type].test(match[2]) ) { - apps.push(app); + profiler.regexCount ++; - break; - } + while ( match = new RegExp(']+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { + profiler.regexCount ++; + + if ( regex.test(match[2]) ) { + apps.push(app); + + break next; } + } + break; + case 'meta': + if ( data['html'] == null ) { break; - case 'meta': - if ( data['html'] == null ) { break; } + } + + profiler.regexCount ++; - regex = /]+>/ig; + while ( match = new RegExp(']+>', 'ig').exec(data['html']) ) { + for ( meta in w.apps[app][type] ) { + profiler.regexCount ++; - while ( match = regex.exec(data['html']) ) { - for ( meta in w.apps[app][type] ) { - if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { - content = match.toString().match(/content=("|')([^"']+)("|')/i); + if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { + content = match.toString().match(/content=("|')([^"']+)("|')/i); - if ( content && content.length == 4 && w.apps[app].meta[meta].test(content[2]) ) { - apps.push(app); + regex = new RegExp(w.apps[app].meta[meta], 'i'); - break; - } + profiler.regexCount ++; + + if ( content && content.length === 4 && regex.test(content[2]) ) { + apps.push(app); + + break next; } } } + } + break; + case 'headers': + if ( data[type] == null ) { break; - case 'headers': - if ( data[type] == null ) { break; } + } - for ( header in w.apps[app].headers ) { - if ( data[type][header] != null && w.apps[app][type][header].test(data[type][header]) ) { - apps.push(app); + for ( header in w.apps[app].headers ) { + regex = new RegExp(w.apps[app][type][header], 'i'); - break; - } + profiler.regexCount ++; + + if ( data[type][header] != null && regex.test(data[type][header]) ) { + apps.push(app); + + break next; } + } + break; + case 'env': + if ( data[type] == null ) { break; - case 'env': - if ( data[type] == null ) { break; } + } - for ( i in data[type] ) { - if ( w.apps[app][type].test(data[type][i]) ) { - apps.push(app); + regex = RegExp(w.apps[app][type], 'i'); - break; - } + for ( i in data[type] ) { + profiler.regexCount ++; + + if ( regex.test(data[type][i]) ) { + apps.push(app); + + break next; } + } - break; - } + break; } } + } - // Implied applications - var i, j, k, implied; + w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); - for ( i = 0; i < 3; i ++ ) { - for ( j in apps ) { - if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { - for ( k in w.apps[apps[j]].implies ) { - implied = w.apps[apps[j]].implies[k]; + // Implied applications + var i, j, k, implied; - if ( !w.apps[implied] ) { - w.log('Implied application ' + implied + ' does not exist'); + for ( i = 0; i < 3; i ++ ) { + for ( j in apps ) { + if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { + for ( k in w.apps[apps[j]].implies ) { + implied = w.apps[apps[j]].implies[k]; - continue; - } + if ( !w.apps[implied] ) { + w.log('Implied application ' + implied + ' does not exist'); - if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { - apps.push(implied); - } + continue; + } + + if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { + apps.push(implied); } } } } + } - w.log(apps.length + ' apps detected: ' + apps.join(', ')); - - // Keep history of detected apps - var i, app, match; + w.log(apps.length + ' apps detected: ' + apps.join(', ')); - for ( i in apps ) { - app = apps[i]; + // Keep history of detected apps + var i, app, match; - // Per hostname - if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { - if ( typeof w.ping.hostnames === 'undefined' ) { - w.ping.hostnames = {}; - } + for ( i in apps ) { + app = apps[i]; - if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { - w.ping.hostnames[hostname] = { applications: {}, meta: {} }; - } + // Per hostname + if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { + if ( typeof w.ping.hostnames === 'undefined' ) { + w.ping.hostnames = {}; + } - if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { - w.ping.hostnames[hostname].applications[app] = 1; - } + if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { + w.ping.hostnames[hostname] = { applications: {}, meta: {} }; + } - w.ping.hostnames[hostname].applications[app] ++; + if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { + w.ping.hostnames[hostname].applications[app] = 1; } - // Per URL - if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + w.ping.hostnames[hostname].applications[app] ++; } - // Additional information - if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { - if ( data.html != null ) { - match = data.html.match(/]*[: ]lang="([^"]+)"/); + // Per URL + if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + } - if ( match != null && match.length ) { - w.ping.hostnames[hostname].meta['language'] = match[1]; - } + // Additional information + if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { + if ( data.html != null ) { + match = data.html.match(/]*[: ]lang="([^"]+)"/); + + if ( match != null && match.length ) { + w.ping.hostnames[hostname].meta['language'] = match[1]; } } + } - if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } + if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } - apps = null; - data = null; - } + apps = null; + data = null; driver('displayApps'); } diff --git a/drivers/php/js/wappalyzer.js b/drivers/php/js/wappalyzer.js index 27542339a..edcd0192e 100644 --- a/drivers/php/js/wappalyzer.js +++ b/drivers/php/js/wappalyzer.js @@ -92,162 +92,222 @@ var wappalyzer = wappalyzer || (function() { analyze: function(hostname, url, data) { w.log('w.analyze'); + data.url = url; + if ( w.apps == null || w.categories == null ) { w.log('apps.json not loaded'); return; } - var i, app, type, regex, match, content, meta, header, apps = []; + if ( w.detected[url] == null ) { + w.detected[url] = []; + } - if ( w.detected[url] == null ) { w.detected[url] = []; } + var + i, app, type, regex, match, content, meta, header, + profiler = { + regexCount: 0, + startTime: ( new Date ).getTime() + }, + apps = [] + ; + + for ( app in w.apps ) { + // Skip if the app has already been detected + if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { + continue; + } - if ( data ) { - for ( app in w.apps ) { - for ( type in w.apps[app] ) { - if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { continue; } // Skip if the app has already been detected + next: - switch ( type ) { - case 'url': - if ( w.apps[app].url.test(url) ) { apps.push(app); } + for ( type in w.apps[app] ) { + if ( data[type] == null ) { + continue; + } - break; - case 'html': - if ( data[type] == null ) { break; } + switch ( type ) { + case 'url': + regex = new RegExp(w.apps[app][type], 'i'); + + profiler.regexCount ++; + + if ( regex.test(url) ) { + apps.push(app); - if ( w.apps[app][type].test(data[type]) ) { apps.push(app); } + break next; + } + + break; + case 'html': + regex = new RegExp(w.apps[app][type], 'i'); + + profiler.regexCount ++; + + if ( regex.test(data[type]) ) { + apps.push(app); + + break next; + } + break; + case 'script': + if ( data['html'] == null ) { break; - case 'script': - if ( data['html'] == null ) { break; } + } - regex = /]+src=("|')([^"']+)\1/ig; + regex = new RegExp(w.apps[app][type], 'i'); - while ( match = regex.exec(data['html']) ) { - if ( w.apps[app][type].test(match[2]) ) { - apps.push(app); + profiler.regexCount ++; - break; - } + while ( match = new RegExp(']+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { + profiler.regexCount ++; + + if ( regex.test(match[2]) ) { + apps.push(app); + + break next; } + } + break; + case 'meta': + if ( data['html'] == null ) { break; - case 'meta': - if ( data['html'] == null ) { break; } + } + + profiler.regexCount ++; - regex = /]+>/ig; + while ( match = new RegExp(']+>', 'ig').exec(data['html']) ) { + for ( meta in w.apps[app][type] ) { + profiler.regexCount ++; - while ( match = regex.exec(data['html']) ) { - for ( meta in w.apps[app][type] ) { - if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { - content = match.toString().match(/content=("|')([^"']+)("|')/i); + if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { + content = match.toString().match(/content=("|')([^"']+)("|')/i); - if ( content && content.length == 4 && w.apps[app].meta[meta].test(content[2]) ) { - apps.push(app); + regex = new RegExp(w.apps[app].meta[meta], 'i'); - break; - } + profiler.regexCount ++; + + if ( content && content.length === 4 && regex.test(content[2]) ) { + apps.push(app); + + break next; } } } + } + break; + case 'headers': + if ( data[type] == null ) { break; - case 'headers': - if ( data[type] == null ) { break; } + } - for ( header in w.apps[app].headers ) { - if ( data[type][header] != null && w.apps[app][type][header].test(data[type][header]) ) { - apps.push(app); + for ( header in w.apps[app].headers ) { + regex = new RegExp(w.apps[app][type][header], 'i'); - break; - } + profiler.regexCount ++; + + if ( data[type][header] != null && regex.test(data[type][header]) ) { + apps.push(app); + + break next; } + } + break; + case 'env': + if ( data[type] == null ) { break; - case 'env': - if ( data[type] == null ) { break; } + } - for ( i in data[type] ) { - if ( w.apps[app][type].test(data[type][i]) ) { - apps.push(app); + regex = RegExp(w.apps[app][type], 'i'); - break; - } + for ( i in data[type] ) { + profiler.regexCount ++; + + if ( regex.test(data[type][i]) ) { + apps.push(app); + + break next; } + } - break; - } + break; } } + } - // Implied applications - var i, j, k, implied; + w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); - for ( i = 0; i < 3; i ++ ) { - for ( j in apps ) { - if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { - for ( k in w.apps[apps[j]].implies ) { - implied = w.apps[apps[j]].implies[k]; + // Implied applications + var i, j, k, implied; - if ( !w.apps[implied] ) { - w.log('Implied application ' + implied + ' does not exist'); + for ( i = 0; i < 3; i ++ ) { + for ( j in apps ) { + if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { + for ( k in w.apps[apps[j]].implies ) { + implied = w.apps[apps[j]].implies[k]; - continue; - } + if ( !w.apps[implied] ) { + w.log('Implied application ' + implied + ' does not exist'); - if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { - apps.push(implied); - } + continue; + } + + if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { + apps.push(implied); } } } } + } - w.log(apps.length + ' apps detected: ' + apps.join(', ')); - - // Keep history of detected apps - var i, app, match; + w.log(apps.length + ' apps detected: ' + apps.join(', ')); - for ( i in apps ) { - app = apps[i]; + // Keep history of detected apps + var i, app, match; - // Per hostname - if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { - if ( typeof w.ping.hostnames === 'undefined' ) { - w.ping.hostnames = {}; - } + for ( i in apps ) { + app = apps[i]; - if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { - w.ping.hostnames[hostname] = { applications: {}, meta: {} }; - } + // Per hostname + if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { + if ( typeof w.ping.hostnames === 'undefined' ) { + w.ping.hostnames = {}; + } - if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { - w.ping.hostnames[hostname].applications[app] = 1; - } + if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { + w.ping.hostnames[hostname] = { applications: {}, meta: {} }; + } - w.ping.hostnames[hostname].applications[app] ++; + if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { + w.ping.hostnames[hostname].applications[app] = 1; } - // Per URL - if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + w.ping.hostnames[hostname].applications[app] ++; } - // Additional information - if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { - if ( data.html != null ) { - match = data.html.match(/]*[: ]lang="([^"]+)"/); + // Per URL + if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + } - if ( match != null && match.length ) { - w.ping.hostnames[hostname].meta['language'] = match[1]; - } + // Additional information + if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { + if ( data.html != null ) { + match = data.html.match(/]*[: ]lang="([^"]+)"/); + + if ( match != null && match.length ) { + w.ping.hostnames[hostname].meta['language'] = match[1]; } } + } - if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } + if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } - apps = null; - data = null; - } + apps = null; + data = null; driver('displayApps'); } diff --git a/share/js/wappalyzer.js b/share/js/wappalyzer.js index 18ff747bc..edcd0192e 100644 --- a/share/js/wappalyzer.js +++ b/share/js/wappalyzer.js @@ -92,173 +92,222 @@ var wappalyzer = wappalyzer || (function() { analyze: function(hostname, url, data) { w.log('w.analyze'); + data.url = url; + if ( w.apps == null || w.categories == null ) { w.log('apps.json not loaded'); return; } - var i, app, type, regex, match, content, meta, header, apps = []; + if ( w.detected[url] == null ) { + w.detected[url] = []; + } - if ( w.detected[url] == null ) { w.detected[url] = []; } + var + i, app, type, regex, match, content, meta, header, + profiler = { + regexCount: 0, + startTime: ( new Date ).getTime() + }, + apps = [] + ; + + for ( app in w.apps ) { + // Skip if the app has already been detected + if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { + continue; + } - if ( data ) { - for ( app in w.apps ) { - for ( type in w.apps[app] ) { - // Skip if the app has already been detected - if ( w.detected[url].indexOf(app) !== -1 || apps.indexOf(app) !== -1 ) { - continue; - } + next: - switch ( type ) { - case 'url': - regex = new RegExp(w.apps[app][type], 'i'); + for ( type in w.apps[app] ) { + if ( data[type] == null ) { + continue; + } - if ( regex.test(url) ) { apps.push(app); } + switch ( type ) { + case 'url': + regex = new RegExp(w.apps[app][type], 'i'); - break; - case 'html': - if ( data[type] == null ) { break; } + profiler.regexCount ++; - regex = new RegExp(w.apps[app][type], 'i'); + if ( regex.test(url) ) { + apps.push(app); - if ( regex.test(data[type]) ) { apps.push(app); } + break next; + } + break; + case 'html': + regex = new RegExp(w.apps[app][type], 'i'); + + profiler.regexCount ++; + + if ( regex.test(data[type]) ) { + apps.push(app); + + break next; + } + + break; + case 'script': + if ( data['html'] == null ) { break; - case 'script': - if ( data['html'] == null ) { break; } + } - regex = /]+src=("|')([^"']+)\1/ig; + regex = new RegExp(w.apps[app][type], 'i'); - while ( match = regex.exec(data['html']) ) { - if ( w.apps[app][type].test(match[2]) ) { - apps.push(app); + profiler.regexCount ++; - break; - } + while ( match = new RegExp(']+src=("|\')([^"\']+)\1', 'ig').exec(data['html']) ) { + profiler.regexCount ++; + + if ( regex.test(match[2]) ) { + apps.push(app); + + break next; } + } + break; + case 'meta': + if ( data['html'] == null ) { break; - case 'meta': - if ( data['html'] == null ) { break; } + } + + profiler.regexCount ++; - regex = /]+>/ig; + while ( match = new RegExp(']+>', 'ig').exec(data['html']) ) { + for ( meta in w.apps[app][type] ) { + profiler.regexCount ++; - while ( match = regex.exec(data['html']) ) { - for ( meta in w.apps[app][type] ) { - if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { - content = match.toString().match(/content=("|')([^"']+)("|')/i); + if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { + content = match.toString().match(/content=("|')([^"']+)("|')/i); - if ( content && content.length == 4 && w.apps[app].meta[meta].test(content[2]) ) { - apps.push(app); + regex = new RegExp(w.apps[app].meta[meta], 'i'); - break; - } + profiler.regexCount ++; + + if ( content && content.length === 4 && regex.test(content[2]) ) { + apps.push(app); + + break next; } } } + } + break; + case 'headers': + if ( data[type] == null ) { break; - case 'headers': - if ( data[type] == null ) { break; } + } - for ( header in w.apps[app].headers ) { - regex = new RegExp(w.apps[app][type][header], 'i'); + for ( header in w.apps[app].headers ) { + regex = new RegExp(w.apps[app][type][header], 'i'); - if ( data[type][header] != null && regex.test(data[type][header]) ) { - apps.push(app); + profiler.regexCount ++; - break; - } + if ( data[type][header] != null && regex.test(data[type][header]) ) { + apps.push(app); + + break next; } + } + break; + case 'env': + if ( data[type] == null ) { break; - case 'env': - if ( data[type] == null ) { break; } + } - regex = RegExp(w.apps[app][type], 'i'); + regex = RegExp(w.apps[app][type], 'i'); - for ( i in data[type] ) { - if ( regex.test(data[type][i]) ) { - apps.push(app); + for ( i in data[type] ) { + profiler.regexCount ++; - break; - } + if ( regex.test(data[type][i]) ) { + apps.push(app); + + break next; } + } - break; - } + break; } } + } - // Implied applications - var i, j, k, implied; + w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); - for ( i = 0; i < 3; i ++ ) { - for ( j in apps ) { - if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { - for ( k in w.apps[apps[j]].implies ) { - implied = w.apps[apps[j]].implies[k]; + // Implied applications + var i, j, k, implied; - if ( !w.apps[implied] ) { - w.log('Implied application ' + implied + ' does not exist'); + for ( i = 0; i < 3; i ++ ) { + for ( j in apps ) { + if ( w.apps[apps[j]] && w.apps[apps[j]].implies ) { + for ( k in w.apps[apps[j]].implies ) { + implied = w.apps[apps[j]].implies[k]; - continue; - } + if ( !w.apps[implied] ) { + w.log('Implied application ' + implied + ' does not exist'); - if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { - apps.push(implied); - } + continue; + } + + if ( w.detected[url].indexOf(implied) === -1 && apps.indexOf(implied) === -1 ) { + apps.push(implied); } } } } + } - w.log(apps.length + ' apps detected: ' + apps.join(', ')); - - // Keep history of detected apps - var i, app, match; + w.log(apps.length + ' apps detected: ' + apps.join(', ')); - for ( i in apps ) { - app = apps[i]; + // Keep history of detected apps + var i, app, match; - // Per hostname - if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { - if ( typeof w.ping.hostnames === 'undefined' ) { - w.ping.hostnames = {}; - } + for ( i in apps ) { + app = apps[i]; - if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { - w.ping.hostnames[hostname] = { applications: {}, meta: {} }; - } + // Per hostname + if ( /^[a-z0-9._\-]+\.[a-z]+/.test(hostname) && !/(dev\.|\/admin|\.local)/.test(url) ) { + if ( typeof w.ping.hostnames === 'undefined' ) { + w.ping.hostnames = {}; + } - if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { - w.ping.hostnames[hostname].applications[app] = 1; - } + if ( typeof w.ping.hostnames[hostname] === 'undefined' ) { + w.ping.hostnames[hostname] = { applications: {}, meta: {} }; + } - w.ping.hostnames[hostname].applications[app] ++; + if ( typeof w.ping.hostnames[hostname].applications[app] === 'undefined' ) { + w.ping.hostnames[hostname].applications[app] = 1; } - // Per URL - if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + w.ping.hostnames[hostname].applications[app] ++; } - // Additional information - if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { - if ( data.html != null ) { - match = data.html.match(/]*[: ]lang="([^"]+)"/); + // Per URL + if ( w.detected[url].indexOf(app) === -1 ) { w.detected[url].push(app); } + } - if ( match != null && match.length ) { - w.ping.hostnames[hostname].meta['language'] = match[1]; - } + // Additional information + if ( typeof w.ping.hostnames !== 'undefined' && typeof w.ping.hostnames[hostname] !== 'undefined' ) { + if ( data.html != null ) { + match = data.html.match(/]*[: ]lang="([^"]+)"/); + + if ( match != null && match.length ) { + w.ping.hostnames[hostname].meta['language'] = match[1]; } } + } - if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } + if ( w.ping.hostnames != null && Object.keys(w.ping.hostnames).length >= 50 ) { driver('ping'); } - apps = null; - data = null; - } + apps = null; + data = null; driver('displayApps'); }