Skip to content

Commit

Permalink
Cause:
Browse files Browse the repository at this point in the history
From the user agent strings in our server logs, the offending user agents are
    Morzilla/5.0 (X11; CrOS x86_64 6457.107.0)
which fails to match
   'CrOS ([a-zA-Z0-9]*) ([0-9.]*)'
because _ is missing in the first match group.

This CL:
1. Fixes the regular expression.
2. Unifies the duplicated platform detection logic in our logs and platform.js
3. Implements an unit test using key examples from the server logs as test cases.

BUG=495206

Review URL: https://codereview.chromium.org/1154023007

Cr-Commit-Position: refs/heads/master@{#333208}
  • Loading branch information
kelvinp authored and Commit bot committed Jun 6, 2015
1 parent e779456 commit e989257
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 105 deletions.
1 change: 1 addition & 0 deletions remoting/remoting_webapp_files.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
'webapp/base/js/identity_unittest.js',
'webapp/base/js/ipc_unittest.js',
'webapp/base/js/l10n_unittest.js',
'webapp/base/js/platform_unittest.js',
'webapp/base/js/protocol_extension_manager_unittest.js',
'webapp/base/js/typecheck_unittest.js',
'webapp/base/js/viewport_unittest.js',
Expand Down
122 changes: 95 additions & 27 deletions remoting/webapp/base/js/platform.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,33 @@
/** @suppress {duplicate} */
var remoting = remoting || {};

/** @enum {string} */
remoting.Os = {
WINDOWS: 'Windows',
LINUX: 'Linux',
MAC: 'Mac',
CHROMEOS: 'ChromeOS',
UNKNOWN: 'Unknown'
};

/**
* Returns full Chrome version.
* @return {string?}
* @typedef {{
* osName: remoting.Os,
* osVersion: string,
* cpu: string,
* chromeVersion: string
* }}
*/
remoting.getChromeVersion = function() {
var match = new RegExp('Chrome/([0-9.]*)').exec(navigator.userAgent);
if (match && (match.length >= 2)) {
return match[1];
}
return null;
};
remoting.SystemInfo;

(function() {

/**
* Returns Chrome major version.
* @return {number}
* Returns full Chrome version.
* @return {string?}
*/
remoting.getChromeMajorVersion = function() {
var match = new RegExp('Chrome/([0-9]+)\.').exec(navigator.userAgent);
if (match && (match.length >= 2)) {
return parseInt(match[1], 10);
}
return 0;
remoting.getChromeVersion = function() {
return remoting.getSystemInfo().chromeVersion;
};

/**
Expand All @@ -37,34 +42,97 @@ remoting.getChromeMajorVersion = function() {
* @return {boolean} True if the platform is Mac.
*/
remoting.platformIsMac = function() {
return navigator.platform.indexOf('Mac') != -1;
}
return remoting.getSystemInfo().osName === remoting.Os.MAC;
};

/**
* Tests whether we are running on Windows.
*
* @return {boolean} True if the platform is Windows.
*/
remoting.platformIsWindows = function() {
return (navigator.platform.indexOf('Win32') != -1) ||
(navigator.platform.indexOf('Win64') != -1);
}
return remoting.getSystemInfo().osName === remoting.Os.WINDOWS;
};

/**
* Tests whether we are running on Linux.
*
* @return {boolean} True if the platform is Linux.
*/
remoting.platformIsLinux = function() {
return (navigator.platform.indexOf('Linux') != -1) &&
!remoting.platformIsChromeOS();
}
return remoting.getSystemInfo().osName === remoting.Os.LINUX;
};

/**
* Tests whether we are running on ChromeOS.
*
* @return {boolean} True if the platform is ChromeOS.
*/
remoting.platformIsChromeOS = function() {
return navigator.userAgent.match(/\bCrOS\b/) != null;
}
return remoting.getSystemInfo().osName === remoting.Os.CHROMEOS;
};

/**
* @return {?remoting.SystemInfo}
*/
remoting.getSystemInfo = function() {
var userAgent = remoting.getUserAgent();

/** @type {remoting.SystemInfo} */
var result = {
chromeVersion: '',
osName: remoting.Os.UNKNOWN,
osVersion: '',
cpu: ''
};

// See platform_unittest.js for sample user agent strings.
var chromeVersion = new RegExp('Chrome/([0-9.]*)').exec(userAgent);
if (chromeVersion && chromeVersion.length >= 2) {
result.chromeVersion = chromeVersion[1];
}

var match = new RegExp('Windows NT ([0-9\\.]*)').exec(userAgent);
if (match && (match.length >= 2)) {
result.osName = remoting.Os.WINDOWS;
result.osVersion = match[1];
return result;
}

match = new RegExp('Linux ([a-zA-Z0-9_]*)').exec(userAgent);
if (match && (match.length >= 2)) {
result.osName = remoting.Os.LINUX;
result.osVersion = '';
result.cpu = match[1];
return result;
}

match = new RegExp('([a-zA-Z]*) Mac OS X ([0-9_]*)').exec(userAgent);
if (match && (match.length >= 3)) {
result.osName = remoting.Os.MAC;
result.osVersion = match[2].replace(/_/g, '.');
result.cpu = match[1];
return result;
}

match = new RegExp('CrOS ([a-zA-Z0-9_]*) ([0-9.]*)').exec(userAgent);
if (match && (match.length >= 3)) {
result.osName = remoting.Os.CHROMEOS;
result.osVersion = match[2];
result.cpu = match[1];
return result;
}
return null;
};

/**
* To be overwritten by unit test.
*
* @return {!string}
*/
remoting.getUserAgent = function() {
return navigator.userAgent;
};

})();

153 changes: 153 additions & 0 deletions remoting/webapp/base/js/platform_unittest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

(function() {

'use strict';

var testData = [{
userAgent: 'Mozilla/5.0 (X11; CrOS x86_64 6457.107.0) AppleWebKit/537.36 ' +
'(KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36,gzip(gfe)',
osName: 'ChromeOS',
osVersion: '6457.107.0',
cpu: 'x86_64',
chromeVersion: '40.0.2214.115'
}, {
userAgent: 'Mozilla/5.0 (X11; CrOS i686 6812.88.0) AppleWebKit/537.36 ' +
'(KHTML, like Gecko) Chrome/42.0.2311.153 Safari/537.36,gzip(gfe)',
osName: 'ChromeOS',
osVersion: '6812.88.0',
cpu: 'i686',
chromeVersion: '42.0.2311.153'
}, {
userAgent: 'Mozilla/5.0 (X11; CrOS armv7l 6946.52.0) AppleWebKit/537.36 ' +
'(KHTML, like Gecko) Chrome/43.0.2357.73 Safari/537.36,gzip(gfe)',
osName: 'ChromeOS',
osVersion: '6946.52.0',
cpu: 'armv7l',
chromeVersion: '43.0.2357.73'
}, {
userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 ' +
'(KHTML, like Gecko) Chrome/45.0.2414.0 Safari/537.36,gzip(gfe)',
osName: 'Linux',
osVersion: '',
cpu: 'x86_64',
chromeVersion: '45.0.2414.0'
},{
userAgent: 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 ' +
'(KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36,gzip(gfe)',
osName: 'Windows',
osVersion: '6.1',
cpu: '',
chromeVersion: '43.0.2357.81'
},{
userAgent: 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 ' +
'(KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36,gzip(gfe)',
osName: 'Windows',
osVersion: '6.3',
cpu: '',
chromeVersion: '42.0.2311.152'
},{
userAgent: 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 ' +
'(KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36,gzip(gfe)',
osName: 'Windows',
osVersion: '6.3',
cpu: '',
chromeVersion: '43.0.2357.81'
}, {
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '+
'(KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36,gzip(gfe)',
osName: 'Windows',
osVersion: '10.0',
cpu: '',
chromeVersion: '43.0.2357.81'
},{
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit' +
'/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36,gzip(gfe)',
osName: 'Mac',
osVersion: '10.9.5',
cpu: 'Intel',
chromeVersion: '43.0.2357.81'
},{
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit' +
'/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36,gzip(gfe)',
osName: 'Mac',
osVersion: '10.10.1',
cpu: 'Intel',
chromeVersion: '43.0.2357.81'
},{
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit' +
'/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36,gzip(gfe)',
osName: 'Mac',
osVersion: '10.10.2',
cpu: 'Intel',
chromeVersion: '43.0.2357.81'
},{
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit' +
'/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36,gzip(gfe)',
osName: 'Mac',
osVersion: '10.10.3',
cpu: 'Intel',
chromeVersion: '43.0.2357.81'
}
];

QUnit.module('platform');

function forEachUserAgent(/** function(Object<string>, string) */ callback) {
testData.forEach(function(/** Object<string>*/ testCase) {
var message = 'userAgent: ' + testCase['userAgent']
var userAgentStub = sinon.stub(remoting, 'getUserAgent');
userAgentStub.returns(testCase['userAgent']);
var result = remoting.getSystemInfo();
callback(testCase, message);
userAgentStub.restore();
});
}

QUnit.test('OS name, OS version, chrome version and cpu detection',
function(assert) {
forEachUserAgent(
function(/** Object<string> */ testCase, /** string */ message) {
var result = remoting.getSystemInfo();
assert.equal(result.osName, testCase['osName'], message);
assert.equal(result.osVersion, testCase['osVersion'], message);
assert.equal(result.cpu, testCase['cpu'], message);
assert.equal(result.chromeVersion, testCase['chromeVersion'], message);
});
});

QUnit.test('platform is Mac', function(assert) {
forEachUserAgent(
function(/** Object<string> */ testCase, /** string */ message) {
assert.equal(remoting.platformIsMac(),
testCase['osName'] === 'Mac', message);
});
});

QUnit.test('platform is Windows', function(assert) {
forEachUserAgent(
function(/** Object<string> */ testCase, /** string */ message) {
assert.equal(remoting.platformIsWindows(),
testCase['osName'] === 'Windows', message);
});
});

QUnit.test('platform is Linux', function(assert) {
forEachUserAgent(
function(/** Object<string> */ testCase, /** string */ message) {
assert.equal(remoting.platformIsLinux(),
testCase['osName'] === 'Linux', message);
});
});

QUnit.test('platform is ChromeOS', function(assert) {
forEachUserAgent(
function(/** Object<string> */ testCase, /** string */ message) {
assert.equal(remoting.platformIsChromeOS(),
testCase['osName'] === 'ChromeOS', message);
});
});

})();
Loading

0 comments on commit e989257

Please sign in to comment.