diff --git a/drivers/bookmarklet/js/wappalyzer.js b/drivers/bookmarklet/js/wappalyzer.js index bde06f5c2..3bb3d9ad2 100644 --- a/drivers/bookmarklet/js/wappalyzer.js +++ b/drivers/bookmarklet/js/wappalyzer.js @@ -13,64 +13,64 @@ var wappalyzer = (function() { * Application class */ var Application = function(app, detected) { - var self = this; - - self.app = app; - self.confidence = {}; - self.confidenceTotal = 0; - self.detected = Boolean(detected); - self.version = ''; - self.versions = []; + this.app = app; + this.confidence = {}; + this.confidenceTotal = 0; + this.detected = Boolean(detected); + this.version = ''; + this.versions = []; + }; + Application.prototype = { /** * Calculate confidence total */ - self.getConfidence = function() { + getConfidence: function() { var total = 0; - for ( id in self.confidence ) { - total += self.confidence[id]; + for ( id in this.confidence ) { + total += this.confidence[id]; } - return self.confidenceTotal = Math.min(total, 100); - } + return this.confidenceTotal = Math.min(total, 100); + }, /** * Resolve version number (find the longest version number that contains all shorter detected version numbers) */ - self.getVersion = function() { - var next, resolved; + getVersion: function() { + var i, next, resolved; - if ( !self.versions.length ) { + if ( !this.versions.length ) { return; } - self.versions.sort(function(a, b) { + this.versions.sort(function(a, b) { return a.length > b.length ? 1 : ( a.length < b.length ? -1 : 0 ); }); - resolved = self.versions[0]; + resolved = this.versions[0]; - for ( i in self.versions ) { + for ( i in this.versions ) { next = parseInt(i) + 1; - if ( next < self.versions.length ) { - if ( self.versions[next].indexOf(self.versions[i]) !== -1 ) { - resolved = self.versions[next]; + if ( next < this.versions.length ) { + if ( this.versions[next].indexOf(this.versions[i]) !== -1 ) { + resolved = this.versions[next]; } else { break; } } } - return self.version = resolved; - } + return this.version = resolved; + }, - self.setDetected = function(pattern, type, value, key) { - self.detected = true; + setDetected: function(pattern, type, value, key) { + this.detected = true; // Set confidence level - self.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; + this.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; // Detect version number if ( pattern.version ) { @@ -100,14 +100,43 @@ var wappalyzer = (function() { }); if ( version ) { - self.versions.push(version); + this.versions.push(version); } - self.getVersion(); + this.getVersion(); } } } - } + }; + + var Profiler = function() { + this.regexCount = 0; + this.startTime = new Date().getTime(); + this.lastTime = new Date().getTime(); + this.slowest = { duration: null, app: '', type: '', pattern: '' }; + this.timedOut = false; + }; + + Profiler.prototype = { + checkPoint: function(app, type, regex) { + var duration = new Date().getTime() - this.lastTime; + + if ( !this.slowest.duration || duration > this.slowest.duration ) { + this.slowest.duration = duration; + this.slowest.app = app; + this.slowest.type = type; + this.slowest.regex = regex; + } + + this.lastTime = new Date().getTime(); + + this.timedOut = this.getDuration() > 1000; + }, + + getDuration: function() { + return new Date().getTime() - this.startTime; + } + }; /** * Call driver functions @@ -224,10 +253,7 @@ var wappalyzer = (function() { analyze: function(hostname, url, data) { var i, j, app, confidence, type, regexMeta, regexScript, match, content, meta, header, version, - profiler = { - regexCount: 0, - startTime: new Date().getTime() - }, + profiler = new Profiler(), apps = {} ; @@ -246,13 +272,21 @@ var wappalyzer = (function() { } for ( app in w.apps ) { + // Exit loop after one second to prevent CPU hogging + // Remaining patterns will not be evaluated + if ( profiler.timedOut ) { + w.log('Timeout, exiting loop'); + + break; + } + apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app); for ( type in w.apps[app] ) { switch ( type ) { case 'url': parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(url) ) { apps[app].setDetected(pattern, type, url); @@ -266,7 +300,7 @@ var wappalyzer = (function() { } parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type]) ) { apps[app].setDetected(pattern, type, data[type]); @@ -282,10 +316,10 @@ var wappalyzer = (function() { regexScript = new RegExp(']+src=("|\')([^"\']+)', 'ig'); parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); while ( match = regexScript.exec(data.html) ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(match[2]) ) { apps[app].setDetected(pattern, type, match[2]); @@ -299,19 +333,17 @@ var wappalyzer = (function() { break; } - profiler.regexCount ++; - regexMeta = /]+>/ig; while ( match = regexMeta.exec(data.html) ) { for ( meta in w.apps[app][type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, regexMeta); if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { content = match.toString().match(/content=("|')([^"']+)("|')/i); parse(w.apps[app].meta[meta]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( content && content.length === 4 && pattern.regex.test(content[2]) ) { apps[app].setDetected(pattern, type, content[2], meta); @@ -329,7 +361,7 @@ var wappalyzer = (function() { for ( header in w.apps[app].headers ) { parse(w.apps[app][type][header]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( typeof data[type][header] === 'string' && pattern.regex.test(data[type][header]) ) { apps[app].setDetected(pattern, type, data[type][header], header); @@ -345,7 +377,7 @@ var wappalyzer = (function() { parse(w.apps[app][type]).map(function(pattern) { for ( i in data[type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type][i]) ) { apps[app].setDetected(pattern, type, data[type][i]); @@ -358,7 +390,8 @@ var wappalyzer = (function() { } } - w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); + w.log('[ PROFILER ] Tested ' + profiler.regexCount + ' regular expressions in ' + ( profiler.getDuration() / 1000 ) + 's'); + w.log('[ PROFILER ] Slowest pattern took ' + ( profiler.slowest.duration / 1000 ) + 's: ' + profiler.slowest.app + ' | ' + profiler.slowest.type + ' | ' + profiler.slowest.regex); for ( app in apps ) { if ( !apps[app].detected ) { diff --git a/drivers/chrome/js/wappalyzer.js b/drivers/chrome/js/wappalyzer.js index bde06f5c2..3bb3d9ad2 100644 --- a/drivers/chrome/js/wappalyzer.js +++ b/drivers/chrome/js/wappalyzer.js @@ -13,64 +13,64 @@ var wappalyzer = (function() { * Application class */ var Application = function(app, detected) { - var self = this; - - self.app = app; - self.confidence = {}; - self.confidenceTotal = 0; - self.detected = Boolean(detected); - self.version = ''; - self.versions = []; + this.app = app; + this.confidence = {}; + this.confidenceTotal = 0; + this.detected = Boolean(detected); + this.version = ''; + this.versions = []; + }; + Application.prototype = { /** * Calculate confidence total */ - self.getConfidence = function() { + getConfidence: function() { var total = 0; - for ( id in self.confidence ) { - total += self.confidence[id]; + for ( id in this.confidence ) { + total += this.confidence[id]; } - return self.confidenceTotal = Math.min(total, 100); - } + return this.confidenceTotal = Math.min(total, 100); + }, /** * Resolve version number (find the longest version number that contains all shorter detected version numbers) */ - self.getVersion = function() { - var next, resolved; + getVersion: function() { + var i, next, resolved; - if ( !self.versions.length ) { + if ( !this.versions.length ) { return; } - self.versions.sort(function(a, b) { + this.versions.sort(function(a, b) { return a.length > b.length ? 1 : ( a.length < b.length ? -1 : 0 ); }); - resolved = self.versions[0]; + resolved = this.versions[0]; - for ( i in self.versions ) { + for ( i in this.versions ) { next = parseInt(i) + 1; - if ( next < self.versions.length ) { - if ( self.versions[next].indexOf(self.versions[i]) !== -1 ) { - resolved = self.versions[next]; + if ( next < this.versions.length ) { + if ( this.versions[next].indexOf(this.versions[i]) !== -1 ) { + resolved = this.versions[next]; } else { break; } } } - return self.version = resolved; - } + return this.version = resolved; + }, - self.setDetected = function(pattern, type, value, key) { - self.detected = true; + setDetected: function(pattern, type, value, key) { + this.detected = true; // Set confidence level - self.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; + this.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; // Detect version number if ( pattern.version ) { @@ -100,14 +100,43 @@ var wappalyzer = (function() { }); if ( version ) { - self.versions.push(version); + this.versions.push(version); } - self.getVersion(); + this.getVersion(); } } } - } + }; + + var Profiler = function() { + this.regexCount = 0; + this.startTime = new Date().getTime(); + this.lastTime = new Date().getTime(); + this.slowest = { duration: null, app: '', type: '', pattern: '' }; + this.timedOut = false; + }; + + Profiler.prototype = { + checkPoint: function(app, type, regex) { + var duration = new Date().getTime() - this.lastTime; + + if ( !this.slowest.duration || duration > this.slowest.duration ) { + this.slowest.duration = duration; + this.slowest.app = app; + this.slowest.type = type; + this.slowest.regex = regex; + } + + this.lastTime = new Date().getTime(); + + this.timedOut = this.getDuration() > 1000; + }, + + getDuration: function() { + return new Date().getTime() - this.startTime; + } + }; /** * Call driver functions @@ -224,10 +253,7 @@ var wappalyzer = (function() { analyze: function(hostname, url, data) { var i, j, app, confidence, type, regexMeta, regexScript, match, content, meta, header, version, - profiler = { - regexCount: 0, - startTime: new Date().getTime() - }, + profiler = new Profiler(), apps = {} ; @@ -246,13 +272,21 @@ var wappalyzer = (function() { } for ( app in w.apps ) { + // Exit loop after one second to prevent CPU hogging + // Remaining patterns will not be evaluated + if ( profiler.timedOut ) { + w.log('Timeout, exiting loop'); + + break; + } + apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app); for ( type in w.apps[app] ) { switch ( type ) { case 'url': parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(url) ) { apps[app].setDetected(pattern, type, url); @@ -266,7 +300,7 @@ var wappalyzer = (function() { } parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type]) ) { apps[app].setDetected(pattern, type, data[type]); @@ -282,10 +316,10 @@ var wappalyzer = (function() { regexScript = new RegExp(']+src=("|\')([^"\']+)', 'ig'); parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); while ( match = regexScript.exec(data.html) ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(match[2]) ) { apps[app].setDetected(pattern, type, match[2]); @@ -299,19 +333,17 @@ var wappalyzer = (function() { break; } - profiler.regexCount ++; - regexMeta = /]+>/ig; while ( match = regexMeta.exec(data.html) ) { for ( meta in w.apps[app][type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, regexMeta); if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { content = match.toString().match(/content=("|')([^"']+)("|')/i); parse(w.apps[app].meta[meta]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( content && content.length === 4 && pattern.regex.test(content[2]) ) { apps[app].setDetected(pattern, type, content[2], meta); @@ -329,7 +361,7 @@ var wappalyzer = (function() { for ( header in w.apps[app].headers ) { parse(w.apps[app][type][header]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( typeof data[type][header] === 'string' && pattern.regex.test(data[type][header]) ) { apps[app].setDetected(pattern, type, data[type][header], header); @@ -345,7 +377,7 @@ var wappalyzer = (function() { parse(w.apps[app][type]).map(function(pattern) { for ( i in data[type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type][i]) ) { apps[app].setDetected(pattern, type, data[type][i]); @@ -358,7 +390,8 @@ var wappalyzer = (function() { } } - w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); + w.log('[ PROFILER ] Tested ' + profiler.regexCount + ' regular expressions in ' + ( profiler.getDuration() / 1000 ) + 's'); + w.log('[ PROFILER ] Slowest pattern took ' + ( profiler.slowest.duration / 1000 ) + 's: ' + profiler.slowest.app + ' | ' + profiler.slowest.type + ' | ' + profiler.slowest.regex); for ( app in apps ) { if ( !apps[app].detected ) { diff --git a/drivers/chrome/manifest.json b/drivers/chrome/manifest.json index 3b246332e..c85c58e61 100644 --- a/drivers/chrome/manifest.json +++ b/drivers/chrome/manifest.json @@ -1,7 +1,7 @@ { "name": "Wappalyzer", "homepage_url": "http://wappalyzer.com?utm_source=chrome&utm_medium=context&utm_campaign=extensions", "description": "Identifies software on the web", - "version": "2.22", + "version": "2.23", "default_locale": "en", "manifest_version": 2, "icons": { diff --git a/drivers/firefox-jetpack/lib/wappalyzer.js b/drivers/firefox-jetpack/lib/wappalyzer.js index bde06f5c2..3bb3d9ad2 100644 --- a/drivers/firefox-jetpack/lib/wappalyzer.js +++ b/drivers/firefox-jetpack/lib/wappalyzer.js @@ -13,64 +13,64 @@ var wappalyzer = (function() { * Application class */ var Application = function(app, detected) { - var self = this; - - self.app = app; - self.confidence = {}; - self.confidenceTotal = 0; - self.detected = Boolean(detected); - self.version = ''; - self.versions = []; + this.app = app; + this.confidence = {}; + this.confidenceTotal = 0; + this.detected = Boolean(detected); + this.version = ''; + this.versions = []; + }; + Application.prototype = { /** * Calculate confidence total */ - self.getConfidence = function() { + getConfidence: function() { var total = 0; - for ( id in self.confidence ) { - total += self.confidence[id]; + for ( id in this.confidence ) { + total += this.confidence[id]; } - return self.confidenceTotal = Math.min(total, 100); - } + return this.confidenceTotal = Math.min(total, 100); + }, /** * Resolve version number (find the longest version number that contains all shorter detected version numbers) */ - self.getVersion = function() { - var next, resolved; + getVersion: function() { + var i, next, resolved; - if ( !self.versions.length ) { + if ( !this.versions.length ) { return; } - self.versions.sort(function(a, b) { + this.versions.sort(function(a, b) { return a.length > b.length ? 1 : ( a.length < b.length ? -1 : 0 ); }); - resolved = self.versions[0]; + resolved = this.versions[0]; - for ( i in self.versions ) { + for ( i in this.versions ) { next = parseInt(i) + 1; - if ( next < self.versions.length ) { - if ( self.versions[next].indexOf(self.versions[i]) !== -1 ) { - resolved = self.versions[next]; + if ( next < this.versions.length ) { + if ( this.versions[next].indexOf(this.versions[i]) !== -1 ) { + resolved = this.versions[next]; } else { break; } } } - return self.version = resolved; - } + return this.version = resolved; + }, - self.setDetected = function(pattern, type, value, key) { - self.detected = true; + setDetected: function(pattern, type, value, key) { + this.detected = true; // Set confidence level - self.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; + this.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; // Detect version number if ( pattern.version ) { @@ -100,14 +100,43 @@ var wappalyzer = (function() { }); if ( version ) { - self.versions.push(version); + this.versions.push(version); } - self.getVersion(); + this.getVersion(); } } } - } + }; + + var Profiler = function() { + this.regexCount = 0; + this.startTime = new Date().getTime(); + this.lastTime = new Date().getTime(); + this.slowest = { duration: null, app: '', type: '', pattern: '' }; + this.timedOut = false; + }; + + Profiler.prototype = { + checkPoint: function(app, type, regex) { + var duration = new Date().getTime() - this.lastTime; + + if ( !this.slowest.duration || duration > this.slowest.duration ) { + this.slowest.duration = duration; + this.slowest.app = app; + this.slowest.type = type; + this.slowest.regex = regex; + } + + this.lastTime = new Date().getTime(); + + this.timedOut = this.getDuration() > 1000; + }, + + getDuration: function() { + return new Date().getTime() - this.startTime; + } + }; /** * Call driver functions @@ -224,10 +253,7 @@ var wappalyzer = (function() { analyze: function(hostname, url, data) { var i, j, app, confidence, type, regexMeta, regexScript, match, content, meta, header, version, - profiler = { - regexCount: 0, - startTime: new Date().getTime() - }, + profiler = new Profiler(), apps = {} ; @@ -246,13 +272,21 @@ var wappalyzer = (function() { } for ( app in w.apps ) { + // Exit loop after one second to prevent CPU hogging + // Remaining patterns will not be evaluated + if ( profiler.timedOut ) { + w.log('Timeout, exiting loop'); + + break; + } + apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app); for ( type in w.apps[app] ) { switch ( type ) { case 'url': parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(url) ) { apps[app].setDetected(pattern, type, url); @@ -266,7 +300,7 @@ var wappalyzer = (function() { } parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type]) ) { apps[app].setDetected(pattern, type, data[type]); @@ -282,10 +316,10 @@ var wappalyzer = (function() { regexScript = new RegExp(']+src=("|\')([^"\']+)', 'ig'); parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); while ( match = regexScript.exec(data.html) ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(match[2]) ) { apps[app].setDetected(pattern, type, match[2]); @@ -299,19 +333,17 @@ var wappalyzer = (function() { break; } - profiler.regexCount ++; - regexMeta = /]+>/ig; while ( match = regexMeta.exec(data.html) ) { for ( meta in w.apps[app][type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, regexMeta); if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { content = match.toString().match(/content=("|')([^"']+)("|')/i); parse(w.apps[app].meta[meta]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( content && content.length === 4 && pattern.regex.test(content[2]) ) { apps[app].setDetected(pattern, type, content[2], meta); @@ -329,7 +361,7 @@ var wappalyzer = (function() { for ( header in w.apps[app].headers ) { parse(w.apps[app][type][header]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( typeof data[type][header] === 'string' && pattern.regex.test(data[type][header]) ) { apps[app].setDetected(pattern, type, data[type][header], header); @@ -345,7 +377,7 @@ var wappalyzer = (function() { parse(w.apps[app][type]).map(function(pattern) { for ( i in data[type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type][i]) ) { apps[app].setDetected(pattern, type, data[type][i]); @@ -358,7 +390,8 @@ var wappalyzer = (function() { } } - w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); + w.log('[ PROFILER ] Tested ' + profiler.regexCount + ' regular expressions in ' + ( profiler.getDuration() / 1000 ) + 's'); + w.log('[ PROFILER ] Slowest pattern took ' + ( profiler.slowest.duration / 1000 ) + 's: ' + profiler.slowest.app + ' | ' + profiler.slowest.type + ' | ' + profiler.slowest.regex); for ( app in apps ) { if ( !apps[app].detected ) { diff --git a/drivers/firefox/content/js/wappalyzer.js b/drivers/firefox/content/js/wappalyzer.js index bde06f5c2..3bb3d9ad2 100644 --- a/drivers/firefox/content/js/wappalyzer.js +++ b/drivers/firefox/content/js/wappalyzer.js @@ -13,64 +13,64 @@ var wappalyzer = (function() { * Application class */ var Application = function(app, detected) { - var self = this; - - self.app = app; - self.confidence = {}; - self.confidenceTotal = 0; - self.detected = Boolean(detected); - self.version = ''; - self.versions = []; + this.app = app; + this.confidence = {}; + this.confidenceTotal = 0; + this.detected = Boolean(detected); + this.version = ''; + this.versions = []; + }; + Application.prototype = { /** * Calculate confidence total */ - self.getConfidence = function() { + getConfidence: function() { var total = 0; - for ( id in self.confidence ) { - total += self.confidence[id]; + for ( id in this.confidence ) { + total += this.confidence[id]; } - return self.confidenceTotal = Math.min(total, 100); - } + return this.confidenceTotal = Math.min(total, 100); + }, /** * Resolve version number (find the longest version number that contains all shorter detected version numbers) */ - self.getVersion = function() { - var next, resolved; + getVersion: function() { + var i, next, resolved; - if ( !self.versions.length ) { + if ( !this.versions.length ) { return; } - self.versions.sort(function(a, b) { + this.versions.sort(function(a, b) { return a.length > b.length ? 1 : ( a.length < b.length ? -1 : 0 ); }); - resolved = self.versions[0]; + resolved = this.versions[0]; - for ( i in self.versions ) { + for ( i in this.versions ) { next = parseInt(i) + 1; - if ( next < self.versions.length ) { - if ( self.versions[next].indexOf(self.versions[i]) !== -1 ) { - resolved = self.versions[next]; + if ( next < this.versions.length ) { + if ( this.versions[next].indexOf(this.versions[i]) !== -1 ) { + resolved = this.versions[next]; } else { break; } } } - return self.version = resolved; - } + return this.version = resolved; + }, - self.setDetected = function(pattern, type, value, key) { - self.detected = true; + setDetected: function(pattern, type, value, key) { + this.detected = true; // Set confidence level - self.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; + this.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; // Detect version number if ( pattern.version ) { @@ -100,14 +100,43 @@ var wappalyzer = (function() { }); if ( version ) { - self.versions.push(version); + this.versions.push(version); } - self.getVersion(); + this.getVersion(); } } } - } + }; + + var Profiler = function() { + this.regexCount = 0; + this.startTime = new Date().getTime(); + this.lastTime = new Date().getTime(); + this.slowest = { duration: null, app: '', type: '', pattern: '' }; + this.timedOut = false; + }; + + Profiler.prototype = { + checkPoint: function(app, type, regex) { + var duration = new Date().getTime() - this.lastTime; + + if ( !this.slowest.duration || duration > this.slowest.duration ) { + this.slowest.duration = duration; + this.slowest.app = app; + this.slowest.type = type; + this.slowest.regex = regex; + } + + this.lastTime = new Date().getTime(); + + this.timedOut = this.getDuration() > 1000; + }, + + getDuration: function() { + return new Date().getTime() - this.startTime; + } + }; /** * Call driver functions @@ -224,10 +253,7 @@ var wappalyzer = (function() { analyze: function(hostname, url, data) { var i, j, app, confidence, type, regexMeta, regexScript, match, content, meta, header, version, - profiler = { - regexCount: 0, - startTime: new Date().getTime() - }, + profiler = new Profiler(), apps = {} ; @@ -246,13 +272,21 @@ var wappalyzer = (function() { } for ( app in w.apps ) { + // Exit loop after one second to prevent CPU hogging + // Remaining patterns will not be evaluated + if ( profiler.timedOut ) { + w.log('Timeout, exiting loop'); + + break; + } + apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app); for ( type in w.apps[app] ) { switch ( type ) { case 'url': parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(url) ) { apps[app].setDetected(pattern, type, url); @@ -266,7 +300,7 @@ var wappalyzer = (function() { } parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type]) ) { apps[app].setDetected(pattern, type, data[type]); @@ -282,10 +316,10 @@ var wappalyzer = (function() { regexScript = new RegExp(']+src=("|\')([^"\']+)', 'ig'); parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); while ( match = regexScript.exec(data.html) ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(match[2]) ) { apps[app].setDetected(pattern, type, match[2]); @@ -299,19 +333,17 @@ var wappalyzer = (function() { break; } - profiler.regexCount ++; - regexMeta = /]+>/ig; while ( match = regexMeta.exec(data.html) ) { for ( meta in w.apps[app][type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, regexMeta); if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { content = match.toString().match(/content=("|')([^"']+)("|')/i); parse(w.apps[app].meta[meta]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( content && content.length === 4 && pattern.regex.test(content[2]) ) { apps[app].setDetected(pattern, type, content[2], meta); @@ -329,7 +361,7 @@ var wappalyzer = (function() { for ( header in w.apps[app].headers ) { parse(w.apps[app][type][header]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( typeof data[type][header] === 'string' && pattern.regex.test(data[type][header]) ) { apps[app].setDetected(pattern, type, data[type][header], header); @@ -345,7 +377,7 @@ var wappalyzer = (function() { parse(w.apps[app][type]).map(function(pattern) { for ( i in data[type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type][i]) ) { apps[app].setDetected(pattern, type, data[type][i]); @@ -358,7 +390,8 @@ var wappalyzer = (function() { } } - w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); + w.log('[ PROFILER ] Tested ' + profiler.regexCount + ' regular expressions in ' + ( profiler.getDuration() / 1000 ) + 's'); + w.log('[ PROFILER ] Slowest pattern took ' + ( profiler.slowest.duration / 1000 ) + 's: ' + profiler.slowest.app + ' | ' + profiler.slowest.type + ' | ' + profiler.slowest.regex); for ( app in apps ) { if ( !apps[app].detected ) { diff --git a/drivers/html/js/wappalyzer.js b/drivers/html/js/wappalyzer.js index bde06f5c2..3bb3d9ad2 100644 --- a/drivers/html/js/wappalyzer.js +++ b/drivers/html/js/wappalyzer.js @@ -13,64 +13,64 @@ var wappalyzer = (function() { * Application class */ var Application = function(app, detected) { - var self = this; - - self.app = app; - self.confidence = {}; - self.confidenceTotal = 0; - self.detected = Boolean(detected); - self.version = ''; - self.versions = []; + this.app = app; + this.confidence = {}; + this.confidenceTotal = 0; + this.detected = Boolean(detected); + this.version = ''; + this.versions = []; + }; + Application.prototype = { /** * Calculate confidence total */ - self.getConfidence = function() { + getConfidence: function() { var total = 0; - for ( id in self.confidence ) { - total += self.confidence[id]; + for ( id in this.confidence ) { + total += this.confidence[id]; } - return self.confidenceTotal = Math.min(total, 100); - } + return this.confidenceTotal = Math.min(total, 100); + }, /** * Resolve version number (find the longest version number that contains all shorter detected version numbers) */ - self.getVersion = function() { - var next, resolved; + getVersion: function() { + var i, next, resolved; - if ( !self.versions.length ) { + if ( !this.versions.length ) { return; } - self.versions.sort(function(a, b) { + this.versions.sort(function(a, b) { return a.length > b.length ? 1 : ( a.length < b.length ? -1 : 0 ); }); - resolved = self.versions[0]; + resolved = this.versions[0]; - for ( i in self.versions ) { + for ( i in this.versions ) { next = parseInt(i) + 1; - if ( next < self.versions.length ) { - if ( self.versions[next].indexOf(self.versions[i]) !== -1 ) { - resolved = self.versions[next]; + if ( next < this.versions.length ) { + if ( this.versions[next].indexOf(this.versions[i]) !== -1 ) { + resolved = this.versions[next]; } else { break; } } } - return self.version = resolved; - } + return this.version = resolved; + }, - self.setDetected = function(pattern, type, value, key) { - self.detected = true; + setDetected: function(pattern, type, value, key) { + this.detected = true; // Set confidence level - self.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; + this.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; // Detect version number if ( pattern.version ) { @@ -100,14 +100,43 @@ var wappalyzer = (function() { }); if ( version ) { - self.versions.push(version); + this.versions.push(version); } - self.getVersion(); + this.getVersion(); } } } - } + }; + + var Profiler = function() { + this.regexCount = 0; + this.startTime = new Date().getTime(); + this.lastTime = new Date().getTime(); + this.slowest = { duration: null, app: '', type: '', pattern: '' }; + this.timedOut = false; + }; + + Profiler.prototype = { + checkPoint: function(app, type, regex) { + var duration = new Date().getTime() - this.lastTime; + + if ( !this.slowest.duration || duration > this.slowest.duration ) { + this.slowest.duration = duration; + this.slowest.app = app; + this.slowest.type = type; + this.slowest.regex = regex; + } + + this.lastTime = new Date().getTime(); + + this.timedOut = this.getDuration() > 1000; + }, + + getDuration: function() { + return new Date().getTime() - this.startTime; + } + }; /** * Call driver functions @@ -224,10 +253,7 @@ var wappalyzer = (function() { analyze: function(hostname, url, data) { var i, j, app, confidence, type, regexMeta, regexScript, match, content, meta, header, version, - profiler = { - regexCount: 0, - startTime: new Date().getTime() - }, + profiler = new Profiler(), apps = {} ; @@ -246,13 +272,21 @@ var wappalyzer = (function() { } for ( app in w.apps ) { + // Exit loop after one second to prevent CPU hogging + // Remaining patterns will not be evaluated + if ( profiler.timedOut ) { + w.log('Timeout, exiting loop'); + + break; + } + apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app); for ( type in w.apps[app] ) { switch ( type ) { case 'url': parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(url) ) { apps[app].setDetected(pattern, type, url); @@ -266,7 +300,7 @@ var wappalyzer = (function() { } parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type]) ) { apps[app].setDetected(pattern, type, data[type]); @@ -282,10 +316,10 @@ var wappalyzer = (function() { regexScript = new RegExp(']+src=("|\')([^"\']+)', 'ig'); parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); while ( match = regexScript.exec(data.html) ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(match[2]) ) { apps[app].setDetected(pattern, type, match[2]); @@ -299,19 +333,17 @@ var wappalyzer = (function() { break; } - profiler.regexCount ++; - regexMeta = /]+>/ig; while ( match = regexMeta.exec(data.html) ) { for ( meta in w.apps[app][type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, regexMeta); if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { content = match.toString().match(/content=("|')([^"']+)("|')/i); parse(w.apps[app].meta[meta]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( content && content.length === 4 && pattern.regex.test(content[2]) ) { apps[app].setDetected(pattern, type, content[2], meta); @@ -329,7 +361,7 @@ var wappalyzer = (function() { for ( header in w.apps[app].headers ) { parse(w.apps[app][type][header]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( typeof data[type][header] === 'string' && pattern.regex.test(data[type][header]) ) { apps[app].setDetected(pattern, type, data[type][header], header); @@ -345,7 +377,7 @@ var wappalyzer = (function() { parse(w.apps[app][type]).map(function(pattern) { for ( i in data[type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type][i]) ) { apps[app].setDetected(pattern, type, data[type][i]); @@ -358,7 +390,8 @@ var wappalyzer = (function() { } } - w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); + w.log('[ PROFILER ] Tested ' + profiler.regexCount + ' regular expressions in ' + ( profiler.getDuration() / 1000 ) + 's'); + w.log('[ PROFILER ] Slowest pattern took ' + ( profiler.slowest.duration / 1000 ) + 's: ' + profiler.slowest.app + ' | ' + profiler.slowest.type + ' | ' + profiler.slowest.regex); for ( app in apps ) { if ( !apps[app].detected ) { diff --git a/drivers/php/js/wappalyzer.js b/drivers/php/js/wappalyzer.js index bde06f5c2..3bb3d9ad2 100644 --- a/drivers/php/js/wappalyzer.js +++ b/drivers/php/js/wappalyzer.js @@ -13,64 +13,64 @@ var wappalyzer = (function() { * Application class */ var Application = function(app, detected) { - var self = this; - - self.app = app; - self.confidence = {}; - self.confidenceTotal = 0; - self.detected = Boolean(detected); - self.version = ''; - self.versions = []; + this.app = app; + this.confidence = {}; + this.confidenceTotal = 0; + this.detected = Boolean(detected); + this.version = ''; + this.versions = []; + }; + Application.prototype = { /** * Calculate confidence total */ - self.getConfidence = function() { + getConfidence: function() { var total = 0; - for ( id in self.confidence ) { - total += self.confidence[id]; + for ( id in this.confidence ) { + total += this.confidence[id]; } - return self.confidenceTotal = Math.min(total, 100); - } + return this.confidenceTotal = Math.min(total, 100); + }, /** * Resolve version number (find the longest version number that contains all shorter detected version numbers) */ - self.getVersion = function() { - var next, resolved; + getVersion: function() { + var i, next, resolved; - if ( !self.versions.length ) { + if ( !this.versions.length ) { return; } - self.versions.sort(function(a, b) { + this.versions.sort(function(a, b) { return a.length > b.length ? 1 : ( a.length < b.length ? -1 : 0 ); }); - resolved = self.versions[0]; + resolved = this.versions[0]; - for ( i in self.versions ) { + for ( i in this.versions ) { next = parseInt(i) + 1; - if ( next < self.versions.length ) { - if ( self.versions[next].indexOf(self.versions[i]) !== -1 ) { - resolved = self.versions[next]; + if ( next < this.versions.length ) { + if ( this.versions[next].indexOf(this.versions[i]) !== -1 ) { + resolved = this.versions[next]; } else { break; } } } - return self.version = resolved; - } + return this.version = resolved; + }, - self.setDetected = function(pattern, type, value, key) { - self.detected = true; + setDetected: function(pattern, type, value, key) { + this.detected = true; // Set confidence level - self.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; + this.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; // Detect version number if ( pattern.version ) { @@ -100,14 +100,43 @@ var wappalyzer = (function() { }); if ( version ) { - self.versions.push(version); + this.versions.push(version); } - self.getVersion(); + this.getVersion(); } } } - } + }; + + var Profiler = function() { + this.regexCount = 0; + this.startTime = new Date().getTime(); + this.lastTime = new Date().getTime(); + this.slowest = { duration: null, app: '', type: '', pattern: '' }; + this.timedOut = false; + }; + + Profiler.prototype = { + checkPoint: function(app, type, regex) { + var duration = new Date().getTime() - this.lastTime; + + if ( !this.slowest.duration || duration > this.slowest.duration ) { + this.slowest.duration = duration; + this.slowest.app = app; + this.slowest.type = type; + this.slowest.regex = regex; + } + + this.lastTime = new Date().getTime(); + + this.timedOut = this.getDuration() > 1000; + }, + + getDuration: function() { + return new Date().getTime() - this.startTime; + } + }; /** * Call driver functions @@ -224,10 +253,7 @@ var wappalyzer = (function() { analyze: function(hostname, url, data) { var i, j, app, confidence, type, regexMeta, regexScript, match, content, meta, header, version, - profiler = { - regexCount: 0, - startTime: new Date().getTime() - }, + profiler = new Profiler(), apps = {} ; @@ -246,13 +272,21 @@ var wappalyzer = (function() { } for ( app in w.apps ) { + // Exit loop after one second to prevent CPU hogging + // Remaining patterns will not be evaluated + if ( profiler.timedOut ) { + w.log('Timeout, exiting loop'); + + break; + } + apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app); for ( type in w.apps[app] ) { switch ( type ) { case 'url': parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(url) ) { apps[app].setDetected(pattern, type, url); @@ -266,7 +300,7 @@ var wappalyzer = (function() { } parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type]) ) { apps[app].setDetected(pattern, type, data[type]); @@ -282,10 +316,10 @@ var wappalyzer = (function() { regexScript = new RegExp(']+src=("|\')([^"\']+)', 'ig'); parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); while ( match = regexScript.exec(data.html) ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(match[2]) ) { apps[app].setDetected(pattern, type, match[2]); @@ -299,19 +333,17 @@ var wappalyzer = (function() { break; } - profiler.regexCount ++; - regexMeta = /]+>/ig; while ( match = regexMeta.exec(data.html) ) { for ( meta in w.apps[app][type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, regexMeta); if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { content = match.toString().match(/content=("|')([^"']+)("|')/i); parse(w.apps[app].meta[meta]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( content && content.length === 4 && pattern.regex.test(content[2]) ) { apps[app].setDetected(pattern, type, content[2], meta); @@ -329,7 +361,7 @@ var wappalyzer = (function() { for ( header in w.apps[app].headers ) { parse(w.apps[app][type][header]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( typeof data[type][header] === 'string' && pattern.regex.test(data[type][header]) ) { apps[app].setDetected(pattern, type, data[type][header], header); @@ -345,7 +377,7 @@ var wappalyzer = (function() { parse(w.apps[app][type]).map(function(pattern) { for ( i in data[type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type][i]) ) { apps[app].setDetected(pattern, type, data[type][i]); @@ -358,7 +390,8 @@ var wappalyzer = (function() { } } - w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); + w.log('[ PROFILER ] Tested ' + profiler.regexCount + ' regular expressions in ' + ( profiler.getDuration() / 1000 ) + 's'); + w.log('[ PROFILER ] Slowest pattern took ' + ( profiler.slowest.duration / 1000 ) + 's: ' + profiler.slowest.app + ' | ' + profiler.slowest.type + ' | ' + profiler.slowest.regex); for ( app in apps ) { if ( !apps[app].detected ) { diff --git a/share/js/wappalyzer.js b/share/js/wappalyzer.js index bde06f5c2..3bb3d9ad2 100644 --- a/share/js/wappalyzer.js +++ b/share/js/wappalyzer.js @@ -13,64 +13,64 @@ var wappalyzer = (function() { * Application class */ var Application = function(app, detected) { - var self = this; - - self.app = app; - self.confidence = {}; - self.confidenceTotal = 0; - self.detected = Boolean(detected); - self.version = ''; - self.versions = []; + this.app = app; + this.confidence = {}; + this.confidenceTotal = 0; + this.detected = Boolean(detected); + this.version = ''; + this.versions = []; + }; + Application.prototype = { /** * Calculate confidence total */ - self.getConfidence = function() { + getConfidence: function() { var total = 0; - for ( id in self.confidence ) { - total += self.confidence[id]; + for ( id in this.confidence ) { + total += this.confidence[id]; } - return self.confidenceTotal = Math.min(total, 100); - } + return this.confidenceTotal = Math.min(total, 100); + }, /** * Resolve version number (find the longest version number that contains all shorter detected version numbers) */ - self.getVersion = function() { - var next, resolved; + getVersion: function() { + var i, next, resolved; - if ( !self.versions.length ) { + if ( !this.versions.length ) { return; } - self.versions.sort(function(a, b) { + this.versions.sort(function(a, b) { return a.length > b.length ? 1 : ( a.length < b.length ? -1 : 0 ); }); - resolved = self.versions[0]; + resolved = this.versions[0]; - for ( i in self.versions ) { + for ( i in this.versions ) { next = parseInt(i) + 1; - if ( next < self.versions.length ) { - if ( self.versions[next].indexOf(self.versions[i]) !== -1 ) { - resolved = self.versions[next]; + if ( next < this.versions.length ) { + if ( this.versions[next].indexOf(this.versions[i]) !== -1 ) { + resolved = this.versions[next]; } else { break; } } } - return self.version = resolved; - } + return this.version = resolved; + }, - self.setDetected = function(pattern, type, value, key) { - self.detected = true; + setDetected: function(pattern, type, value, key) { + this.detected = true; // Set confidence level - self.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; + this.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100; // Detect version number if ( pattern.version ) { @@ -100,14 +100,43 @@ var wappalyzer = (function() { }); if ( version ) { - self.versions.push(version); + this.versions.push(version); } - self.getVersion(); + this.getVersion(); } } } - } + }; + + var Profiler = function() { + this.regexCount = 0; + this.startTime = new Date().getTime(); + this.lastTime = new Date().getTime(); + this.slowest = { duration: null, app: '', type: '', pattern: '' }; + this.timedOut = false; + }; + + Profiler.prototype = { + checkPoint: function(app, type, regex) { + var duration = new Date().getTime() - this.lastTime; + + if ( !this.slowest.duration || duration > this.slowest.duration ) { + this.slowest.duration = duration; + this.slowest.app = app; + this.slowest.type = type; + this.slowest.regex = regex; + } + + this.lastTime = new Date().getTime(); + + this.timedOut = this.getDuration() > 1000; + }, + + getDuration: function() { + return new Date().getTime() - this.startTime; + } + }; /** * Call driver functions @@ -224,10 +253,7 @@ var wappalyzer = (function() { analyze: function(hostname, url, data) { var i, j, app, confidence, type, regexMeta, regexScript, match, content, meta, header, version, - profiler = { - regexCount: 0, - startTime: new Date().getTime() - }, + profiler = new Profiler(), apps = {} ; @@ -246,13 +272,21 @@ var wappalyzer = (function() { } for ( app in w.apps ) { + // Exit loop after one second to prevent CPU hogging + // Remaining patterns will not be evaluated + if ( profiler.timedOut ) { + w.log('Timeout, exiting loop'); + + break; + } + apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app); for ( type in w.apps[app] ) { switch ( type ) { case 'url': parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(url) ) { apps[app].setDetected(pattern, type, url); @@ -266,7 +300,7 @@ var wappalyzer = (function() { } parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type]) ) { apps[app].setDetected(pattern, type, data[type]); @@ -282,10 +316,10 @@ var wappalyzer = (function() { regexScript = new RegExp(']+src=("|\')([^"\']+)', 'ig'); parse(w.apps[app][type]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); while ( match = regexScript.exec(data.html) ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(match[2]) ) { apps[app].setDetected(pattern, type, match[2]); @@ -299,19 +333,17 @@ var wappalyzer = (function() { break; } - profiler.regexCount ++; - regexMeta = /]+>/ig; while ( match = regexMeta.exec(data.html) ) { for ( meta in w.apps[app][type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, regexMeta); if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) { content = match.toString().match(/content=("|')([^"']+)("|')/i); parse(w.apps[app].meta[meta]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( content && content.length === 4 && pattern.regex.test(content[2]) ) { apps[app].setDetected(pattern, type, content[2], meta); @@ -329,7 +361,7 @@ var wappalyzer = (function() { for ( header in w.apps[app].headers ) { parse(w.apps[app][type][header]).map(function(pattern) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( typeof data[type][header] === 'string' && pattern.regex.test(data[type][header]) ) { apps[app].setDetected(pattern, type, data[type][header], header); @@ -345,7 +377,7 @@ var wappalyzer = (function() { parse(w.apps[app][type]).map(function(pattern) { for ( i in data[type] ) { - profiler.regexCount ++; + profiler.checkPoint(app, type, pattern.regex); if ( pattern.regex.test(data[type][i]) ) { apps[app].setDetected(pattern, type, data[type][i]); @@ -358,7 +390,8 @@ var wappalyzer = (function() { } } - w.log('Tested ' + profiler.regexCount + ' regular expressions in ' + ( ( ( new Date ).getTime() - profiler.startTime ) / 1000 ) + 's'); + w.log('[ PROFILER ] Tested ' + profiler.regexCount + ' regular expressions in ' + ( profiler.getDuration() / 1000 ) + 's'); + w.log('[ PROFILER ] Slowest pattern took ' + ( profiler.slowest.duration / 1000 ) + 's: ' + profiler.slowest.app + ' | ' + profiler.slowest.type + ' | ' + profiler.slowest.regex); for ( app in apps ) { if ( !apps[app].detected ) {