From 47c310e20380e15fa0575b45ba4c1a8d01bf00d2 Mon Sep 17 00:00:00 2001 From: Ziding Zhang Date: Thu, 16 Sep 2021 16:11:51 +0100 Subject: [PATCH 01/24] Create SECURITY.md A simple instruction for security researchers. --- SECURITY.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..de525bb --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy + +## Reporting a Vulnerability + +Please report security issues to `f@faisalman.com` From 336ce2b9502923fb931615598dfb0baefed04f5d Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 17 Sep 2021 23:24:42 +0700 Subject: [PATCH 02/24] Improve regex efficiency when trimming long ua string https://blog.stevenlevithan.com/archives/faster-trim-javascript --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 2a62367..7d8beb6 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -91,7 +91,7 @@ }, trim = function (str, len) { if (typeof(str) === STR_TYPE) { - str = str.replace(/^\s+|\s+$/g, EMPTY); + str = str.replace(/^\s\s*/, EMPTY).replace(/\s\s*$/, EMPTY); return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); } }; From 15aa73de406695607ebe3c0cc9921baf02d7c437 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 21 Sep 2021 09:15:49 -0700 Subject: [PATCH 03/24] Add Huawei models --- src/ua-parser.js | 2 +- test/device-test.json | 117 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 7d8beb6..5f8a265 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -388,7 +388,7 @@ /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /(?:huawei|honor)([-\w ]+)[;\)]/i, - /\b(nexus 6p|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b(?!.+d\/s)/i + /\b(nexus 6p|lya-l0c|yale?\-a?l\d{2}[ad]?|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi diff --git a/test/device-test.json b/test/device-test.json index ae9392f..60a7b23 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -268,6 +268,24 @@ "type": "mobile" } }, + { + "desc": "Huawei Honor 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L41) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L41", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-AL10", + "type": "mobile" + } + }, { "desc": "Huawei Nexus 6P", "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 6P Build/MTC19V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537", @@ -421,6 +439,42 @@ "type": "mobile" } }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-AL10", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L0C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-L0C", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-TL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-TL00", + "type": "mobile" + } + }, { "desc": "Huawei P20 Lite", "ua": "Mozilla/5.0 (Linux; Android 8.0.0; ANE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", @@ -502,6 +556,69 @@ "type": "mobile" } }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L21) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L21", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L61) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L61", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L71) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L71", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L61D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L61D", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L61A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YALE-L61A", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L61D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YALE-L61D", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L71A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YALE-L71A", + "type": "mobile" + } + }, { "desc": "Huawei Enjoy10e", "ua": "Dalvik/2.1.0 (Linux; U; Android 10; MED-AL00 Build/HUAWEIMED-AL00)", From b542df155ac339cd2a7e67e6634e0f1068208ad3 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 21 Sep 2021 11:01:28 -0700 Subject: [PATCH 04/24] Sony Xperia 1ii --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 7d8beb6..1a88d27 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -448,7 +448,7 @@ ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ // Sony - /droid.+ ([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i + /droid.+ ([c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [ /sony tablet [ps]/i, /\b(?:sony)?sgp\w+(?: bui|\))/i diff --git a/test/device-test.json b/test/device-test.json index ae9392f..1a26d9a 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1647,6 +1647,15 @@ "type": "mobile" } }, + { + "desc": "Sony Xperia 1ii", + "ua": "Mozilla/5.0 (Linux; Android 10; SOG01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "SOG01", + "type": "mobile" + } + }, { "desc": "Sony Xperia 10ii", "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AU52) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", From ffc03acd64069d287e02c675bb963dfa21103117 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 21 Sep 2021 12:31:16 -0700 Subject: [PATCH 05/24] Add different oculus browser --- test/browser-test.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/browser-test.json b/test/browser-test.json index 2f4c2e0..afd576e 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -789,7 +789,7 @@ } }, { - "desc" : "Oculus Browser", + "desc" : "Oculus Browser", "ua" : "Mozilla/5.0 (Linux; Android 7.0; SM-G920I Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/3.4.9 SamsungBrowser/4.0 Chrome/57.0.2987.146 Mobile VR Safari/537.36", "expect" : { @@ -798,6 +798,16 @@ "major" : "3" } }, + { + "desc" : "Oculus Browser", + "ua" : "Mozilla/5.0 (Linux; Android 7.1.1; Pacific Build/N9F27L) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/4.0.0.17 SamsungBrowser/4.0 Chrome/61.0.3163.109 Mobile VR Safari/537.36", + "expect" : + { + "name" : "Oculus Browser", + "version" : "3.4.9", + "major" : "3" + } + }, { "desc" : "OmniWeb", "ua" : "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-US) AppleWebKit/85 (KHTML, like Gecko) OmniWeb/v558.48", From f57bd9523d81f9e20d5f7aca8a918d38646c8a89 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 21 Sep 2021 15:31:02 -0700 Subject: [PATCH 06/24] Oculus devices --- src/ua-parser.js | 9 +++++++-- test/browser-test.json | 24 ++++++++++++++++++++++-- test/device-test.json | 18 ++++++++++++++++++ test/test.js | 4 ++-- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 7d8beb6..e6108cf 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -56,7 +56,8 @@ SAMSUNG = 'Samsung', SONY = 'Sony', XIAOMI = 'Xiaomi', - ZEBRA = 'Zebra'; + ZEBRA = 'Zebra', + FACEBOOK = 'Facebook'; /////////// // Helper @@ -278,7 +279,7 @@ // WebView /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android - ], [[NAME, 'Facebook'], VERSION], [ + ], [[NAME, FACEBOOK], VERSION], [ /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /(chromium|instagram)[\/ ]([-\w\.]+)/i // Chromium/Instagram @@ -631,6 +632,10 @@ ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [ /droid.+; (wt63?0{2,3})\)/i ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ + /quest 2/i + ], [[MODEL, 'Quest 2'], [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ + /quest/i + ], [[MODEL, 'Quest'], [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ /////////////////// // EMBEDDED diff --git a/test/browser-test.json b/test/browser-test.json index afd576e..ca37777 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -804,8 +804,28 @@ "expect" : { "name" : "Oculus Browser", - "version" : "3.4.9", - "major" : "3" + "version" : "4.0.0.17", + "major" : "4" + } + }, + { + "desc" : "Oculus Browser", + "ua" : "Mozilla/5.0 (Linux; Android 9; SM-N960F) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/6.2.11.181027543 SamsungBrowser/4.0 Chrome/74.0.3729.182 Mobile VR Safari/537.36", + "expect" : + { + "name" : "Oculus Browser", + "version" : "6.2.11.181027543", + "major" : "6" + } + }, + { + "desc" : "Oculus Browser (NOTE PARIS FROM https://developer.oculus.com/documentation/web/browser-specs/)", + "ua" : "Mozilla/5.0 (Linux; Android 10; Quest 2) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/15.0.0.0.22.280317669 SamsungBrowser/4.0 Chrome/89.0.4389.90 VR Safari/537.36", + "expect" : + { + "name" : "Oculus Browser", + "version" : "15.0.0.0.22.280317669", + "major" : "15" } }, { diff --git a/test/device-test.json b/test/device-test.json index ae9392f..3a60d8e 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1053,6 +1053,24 @@ "type": "mobile" } }, + { + "desc": "Oculus Quest", + "ua": "Mozilla/5.0 (Linux; Android 10; Quest) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/15.0.0.0.22.280317669 SamsungBrowser/4.0 Chrome/89.0.4389.90 VR Safari/537.36", + "expect": { + "vendor": "Facebook", + "model": "Quest", + "type": "wearable" + } + }, + { + "desc": "Oculus Quest 2", + "ua": "Mozilla/5.0 (Linux; Android 10; Quest 2) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/15.0.0.0.22.280317669 SamsungBrowser/4.0 Chrome/89.0.4389.90 VR Safari/537.36", + "expect": { + "vendor": "Facebook", + "model": "Quest 2", + "type": "wearable" + } + }, { "desc": "OnePlus One", "ua": "Mozilla/5.0 (Linux; Android 4.4.4; A0001 Build/KTU84Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.59 Mobile Safari/537.36", diff --git a/test/test.js b/test/test.js index ad54ef4..58c9b3d 100644 --- a/test/test.js +++ b/test/test.js @@ -39,7 +39,8 @@ var methods = [ label : 'os', list : os, properties : ['name', 'version'] -}]; + } +]; describe('UAParser()', function () { var ua = 'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6'; @@ -62,7 +63,6 @@ for (var i in methods) { describe('"' + methods[i]['list'][j].ua + '"', function () { var expect = methods[i]['list'][j].expect; var result = parser.setUA(methods[i]['list'][j].ua).getResult()[methods[i]['label']]; - methods[i]['properties'].forEach(function(m) { it('should return ' + methods[i]['label'] + ' ' + m + ': ' + expect[m], function () { assert.strictEqual(result[m], expect[m] != 'undefined' ? expect[m] : undefined); From ee743946e8df499f7b77a521b13ed3de9a2d2149 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 21 Sep 2021 15:40:04 -0700 Subject: [PATCH 07/24] cleanup --- test/browser-test.json | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/test/browser-test.json b/test/browser-test.json index ca37777..393aba7 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -789,7 +789,7 @@ } }, { - "desc" : "Oculus Browser", + "desc" : "Oculus Browser", "ua" : "Mozilla/5.0 (Linux; Android 7.0; SM-G920I Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/3.4.9 SamsungBrowser/4.0 Chrome/57.0.2987.146 Mobile VR Safari/537.36", "expect" : { @@ -800,26 +800,6 @@ }, { "desc" : "Oculus Browser", - "ua" : "Mozilla/5.0 (Linux; Android 7.1.1; Pacific Build/N9F27L) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/4.0.0.17 SamsungBrowser/4.0 Chrome/61.0.3163.109 Mobile VR Safari/537.36", - "expect" : - { - "name" : "Oculus Browser", - "version" : "4.0.0.17", - "major" : "4" - } - }, - { - "desc" : "Oculus Browser", - "ua" : "Mozilla/5.0 (Linux; Android 9; SM-N960F) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/6.2.11.181027543 SamsungBrowser/4.0 Chrome/74.0.3729.182 Mobile VR Safari/537.36", - "expect" : - { - "name" : "Oculus Browser", - "version" : "6.2.11.181027543", - "major" : "6" - } - }, - { - "desc" : "Oculus Browser (NOTE PARIS FROM https://developer.oculus.com/documentation/web/browser-specs/)", "ua" : "Mozilla/5.0 (Linux; Android 10; Quest 2) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/15.0.0.0.22.280317669 SamsungBrowser/4.0 Chrome/89.0.4389.90 VR Safari/537.36", "expect" : { From 79535f5d612128e062ccca921a1c38cfedb2c31f Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 21 Sep 2021 15:40:47 -0700 Subject: [PATCH 08/24] cleanup --- test/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test.js b/test/test.js index 58c9b3d..ad54ef4 100644 --- a/test/test.js +++ b/test/test.js @@ -39,8 +39,7 @@ var methods = [ label : 'os', list : os, properties : ['name', 'version'] - } -]; +}]; describe('UAParser()', function () { var ua = 'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6'; @@ -63,6 +62,7 @@ for (var i in methods) { describe('"' + methods[i]['list'][j].ua + '"', function () { var expect = methods[i]['list'][j].expect; var result = parser.setUA(methods[i]['list'][j].ua).getResult()[methods[i]['label']]; + methods[i]['properties'].forEach(function(m) { it('should return ' + methods[i]['label'] + ' ' + m + ': ' + expect[m], function () { assert.strictEqual(result[m], expect[m] != 'undefined' ? expect[m] : undefined); From 343d584f8f74a15fcaa621e1ad76b425db8119c8 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Mon, 4 Oct 2021 09:06:00 -0700 Subject: [PATCH 09/24] change to single line regex --- src/ua-parser.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index e6108cf..0453e50 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -632,10 +632,8 @@ ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [ /droid.+; (wt63?0{2,3})\)/i ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ - /quest 2/i - ], [[MODEL, 'Quest 2'], [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ - /quest/i - ], [[MODEL, 'Quest'], [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ + /(quest( 2)?)/i // Oculus Quest + ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ /////////////////// // EMBEDDED From 191fed912779a0fd1db46319c956353feb8e4ff2 Mon Sep 17 00:00:00 2001 From: Ryohei Shima Date: Fri, 22 Oct 2021 12:23:36 +0900 Subject: [PATCH 10/24] Enable to detect OPPO Reno5 A correctly. --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index ce13424..8df1885 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -404,7 +404,7 @@ // OPPO /; (\w+) bui.+ oppo/i, - /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007)\b/i + /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [ // Vivo diff --git a/test/device-test.json b/test/device-test.json index d0a5f89..da6a820 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1242,6 +1242,15 @@ "type": "mobile" } }, + { + "desc": "OPPO Reno5 A", + "ua": "Mozilla/5.0 (Linux; Android 11; A101OP) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "A101OP", + "type": "mobile" + } + }, { "desc": "OPPO Find X", "ua": "Mozilla/5.0 (Linux; Android 8.1; PAFM00 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", From 139fbc321a36ff663aac471a61d109728ac17f0b Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 22 Oct 2021 23:14:37 +0700 Subject: [PATCH 11/24] Securing the 0.7.x version (issue #536) --- bower.json | 2 +- package.js | 2 +- package.json | 2 +- SECURITY.md => security.md | 0 src/ua-parser.js | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename SECURITY.md => security.md (100%) diff --git a/bower.json b/bower.json index 6539b1b..d3adc93 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.28", + "version": "0.7.30", "authors": [ "Faisal Salman " ], diff --git a/package.js b/package.js index 8ff9001..c463dd5 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'faisalman:ua-parser-js', - version: '0.7.28', + version: '0.7.30', summary: 'Lightweight JavaScript-based user-agent string parser', git: 'https://github.com/faisalman/ua-parser-js.git', documentation: 'readme.md' diff --git a/package.json b/package.json index 83864f4..ccb22f3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "0.7.28", + "version": "0.7.30", "author": "Faisal Salman (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ diff --git a/SECURITY.md b/security.md similarity index 100% rename from SECURITY.md rename to security.md diff --git a/src/ua-parser.js b/src/ua-parser.js index ce13424..967d940 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -17,7 +17,7 @@ ///////////// - var LIBVERSION = '0.7.28', + var LIBVERSION = '0.7.30', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From 051aa5d284157ea4147f8ee23282f7c4117d71c3 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 22 Oct 2021 23:23:12 +0700 Subject: [PATCH 12/24] Securing the 0.8.x version (issue #536) --- bower.json | 2 +- package.js | 2 +- package.json | 2 +- src/ua-parser.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bower.json b/bower.json index d3adc93..c6b738b 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.30", + "version": "0.8.1", "authors": [ "Faisal Salman " ], diff --git a/package.js b/package.js index c463dd5..180cb62 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'faisalman:ua-parser-js', - version: '0.7.30', + version: '0.8.1', summary: 'Lightweight JavaScript-based user-agent string parser', git: 'https://github.com/faisalman/ua-parser-js.git', documentation: 'readme.md' diff --git a/package.json b/package.json index ccb22f3..d03ca75 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "0.7.30", + "version": "0.8.1", "author": "Faisal Salman (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ diff --git a/src/ua-parser.js b/src/ua-parser.js index 967d940..79cb0e6 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -17,7 +17,7 @@ ///////////// - var LIBVERSION = '0.7.30', + var LIBVERSION = '0.8.1', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From 29d5e43342170414c4b7e88e76d87e4adb43c389 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 22 Oct 2021 23:25:44 +0700 Subject: [PATCH 13/24] Securing the 1.x version (issue #536) --- bower.json | 2 +- package.js | 2 +- package.json | 2 +- src/ua-parser.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bower.json b/bower.json index c6b738b..277a8ae 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.8.1", + "version": "1.0.1", "authors": [ "Faisal Salman " ], diff --git a/package.js b/package.js index 180cb62..40c3678 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'faisalman:ua-parser-js', - version: '0.8.1', + version: '1.0.1', summary: 'Lightweight JavaScript-based user-agent string parser', git: 'https://github.com/faisalman/ua-parser-js.git', documentation: 'readme.md' diff --git a/package.json b/package.json index d03ca75..9faf964 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "0.8.1", + "version": "1.0.1", "author": "Faisal Salman (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ diff --git a/src/ua-parser.js b/src/ua-parser.js index 79cb0e6..1e88c0a 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -17,7 +17,7 @@ ///////////// - var LIBVERSION = '0.8.1', + var LIBVERSION = '1.0.1', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From fbd2c6853c8e6c69646295ba40dc4d6a3a0ee951 Mon Sep 17 00:00:00 2001 From: chenhui9279 Date: Mon, 25 Oct 2021 16:44:54 +0800 Subject: [PATCH 14/24] feat: require the use of `===` and `!==` --- src/ua-parser.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 1e88c0a..ae6066d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -123,7 +123,7 @@ q = props[p]; // check if given property is actually array if (typeof q === OBJ_TYPE && q.length > 0) { - if (q.length == 2) { + if (q.length === 2) { if (typeof q[1] == FUNC_TYPE) { // assign modified match this[q[0]] = q[1].call(this, match); @@ -131,7 +131,7 @@ // assign given value, ignore regex match this[q[0]] = q[1]; } - } else if (q.length == 3) { + } else if (q.length === 3) { // check whether function or regex if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) { // call function (usually string mapper) @@ -140,7 +140,7 @@ // sanitize match using given regex this[q[0]] = match ? match.replace(q[1], q[2]) : undefined; } - } else if (q.length == 4) { + } else if (q.length === 4) { this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined; } } else { From 10c978eca5a44873213b6c077fbf0f3580e4c2b8 Mon Sep 17 00:00:00 2001 From: sunny-mwx <30586210+sunny-mwx@users.noreply.github.com> Date: Tue, 26 Oct 2021 17:35:34 +0800 Subject: [PATCH 15/24] Update ua-parser.js --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 1e88c0a..b110513 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -76,7 +76,7 @@ }, enumerize = function (arr) { var enums = {}; - for (var i in arr) { + for (var i=0; i Date: Tue, 26 Oct 2021 11:36:19 +0200 Subject: [PATCH 16/24] =?UTF-8?q?=E2=9C=A8=20Use=20AST=20to=20verify=20whe?= =?UTF-8?q?ther=20regexes=20are=20safe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 ++ test/test.js | 21 +++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 9faf964..8e9b59c 100644 --- a/package.json +++ b/package.json @@ -160,6 +160,8 @@ ] }, "devDependencies": { + "@babel/parser": "7.15.8", + "@babel/traverse": "7.15.4", "jshint": "~2.12.0", "mocha": "~8.2.0", "requirejs": "^2.3.2", diff --git a/test/test.js b/test/test.js index ad54ef4..71d1f46 100644 --- a/test/test.js +++ b/test/test.js @@ -2,6 +2,8 @@ var fs = require('fs'); var safe = require('safe-regex'); var assert = require('assert'); var requirejs = require('requirejs'); +var parseJS = require('@babel/parser').parse; +var traverse = require('@babel/traverse').default; var UAParser = require('./../src/ua-parser'); var browsers = require('./browser-test.json'); var cpus = require('./cpu-test.json'); @@ -137,12 +139,19 @@ describe('Testing regexes', function () { var regexes; - // todo: use AST-based instead of grep - before('Read main js file', function (done) { - fs.readFile('src/ua-parser.js', 'utf8', function (err, data) { - regexes = data.match(/(\/.+\/[ig]+)(?=[,\s\n])/g); - done(); + before('Read main js file', function () { + var code = fs.readFileSync('src/ua-parser.js', 'utf8').toString(); + var ast = parseJS(code, { sourceType: "script" }); + regexes = []; + traverse(ast, { + RegExpLiteral: (path) => { + regexes.push(path.node.pattern); + } }); + + if (regexes.length === 0) { + throw new Error("Regexes cannot be empty!"); + } }); describe('Begin testing', function () { @@ -156,4 +165,4 @@ describe('Testing regexes', function () { }); }); }); -}) \ No newline at end of file +}); From 97f3368ef053d63e24a04421dec1a55e73dbf2af Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 27 Oct 2021 14:00:19 +0700 Subject: [PATCH 17/24] Bump version 0.7.31 --- bower.json | 2 +- dist/ua-parser.min.js | 4 ++-- dist/ua-parser.pack.js | 4 ++-- package.js | 2 +- package.json | 4 ++-- src/ua-parser.js | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bower.json b/bower.json index 277a8ae..618bac5 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "1.0.1", + "version": "0.7.31", "authors": [ "Faisal Salman " ], diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 14b5e8c..08dc9d5 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,4 +1,4 @@ -/* UAParser.js v0.7.28 +/* UAParser.js v0.7.31 Copyright © 2012-2021 Faisal Salman MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.28",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i in arr){enums[arr[i].toUpperCase()]=arr[i]}return enums},has=function(str1,str2){return typeof str1===STR_TYPE?lowerize(str2).indexOf(lowerize(str1))!==-1:false},lowerize=function(str){return str.toLowerCase()},majorize=function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,EMPTY).split(".")[0]:undefined},trim=function(str,len){if(typeof str===STR_TYPE){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,EMPTY);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},strMapper=function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);UAParser.CPU=enumerize([ARCHITECTURE]);UAParser.DEVICE=enumerize([MODEL,VENDOR,TYPE,CONSOLE,MOBILE,SMARTTV,TABLET,WEARABLE,EMBEDDED]);UAParser.ENGINE=UAParser.OS=enumerize([NAME,VERSION]);if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define===FUNC_TYPE&&define.amd){define(function(){return UAParser})}else if(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(ua){parser.setUA(ua);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file +(function(window,undefined){"use strict";var LIBVERSION="0.7.31",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded",UA_MAX_LENGTH=255;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",FACEBOOK="Facebook";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i=0;i0){if(q.length===2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length===3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length===4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},strMapper=function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);UAParser.CPU=enumerize([ARCHITECTURE]);UAParser.DEVICE=enumerize([MODEL,VENDOR,TYPE,CONSOLE,MOBILE,SMARTTV,TABLET,WEARABLE,EMBEDDED]);UAParser.ENGINE=UAParser.OS=enumerize([NAME,VERSION]);if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define===FUNC_TYPE&&define.amd){define(function(){return UAParser})}else if(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(ua){parser.setUA(ua);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index 34c92c5..da1bb26 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,4 +1,4 @@ -/* UAParser.js v0.7.28 +/* UAParser.js v0.7.31 Copyright © 2012-2021 Faisal Salman MIT License */ -!function(r,d){"use strict";function i(i){var e,o={};for(e in i)o[i[e].toUpperCase()]=i[e];return o}function t(i,e){return typeof i==w&&-1!==B(e).indexOf(B(i))}function n(i,e){if(typeof i==w)return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof e==b?i:i.substring(0,255)}function s(i,e){for(var o,a,r,t,n,s=0;s (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ @@ -156,7 +156,7 @@ ], "regs": [ "^((?:\\$|(\\s*\\*\\s*@)|(\\s*(?:var|,)?\\s+))(?:LIBVERSION|version)[\\s\\:='\"]+)([0-9]+(?:\\.[0-9]+){2,2})", - "^(\\s?\\*.*v)([0-9]+(?:\\.[0-9]+){2,2})" + "^(\\/?\\s?\\*.*v)([0-9]+(?:\\.[0-9]+){2,2})" ] }, "devDependencies": { diff --git a/src/ua-parser.js b/src/ua-parser.js index abedd15..196bb85 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v0.7.28 +/* UAParser.js v0.7.31 Copyright © 2012-2021 Faisal Salman MIT License *//* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. @@ -17,7 +17,7 @@ ///////////// - var LIBVERSION = '1.0.1', + var LIBVERSION = '0.7.31', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From 23ad60ea689e2d25ec9e403bf128d3b974c341cb Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 18 Dec 2021 01:31:40 +0700 Subject: [PATCH 18/24] Fix #559: Sony Xperia 1 III misidentified as Acer tablet --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 196bb85..56fefcc 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -449,7 +449,7 @@ ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ // Sony - /droid.+ ([c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i + /droid.+ (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [ /sony tablet [ps]/i, /\b(?:sony)?sgp\w+(?: bui|\))/i diff --git a/test/device-test.json b/test/device-test.json index da6a820..1b98a76 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1602,6 +1602,15 @@ "type": "mobile" } }, + { + "desc": "SONY Xperia 1 III", + "ua": "Mozilla/5.0 (Linux; Android 11; A101SO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "A101SO", + "type": "mobile" + } + }, { "desc": "Sony G8141 (Xperia XZ Premium)", "ua": "Mozilla/5.0 (Linux; Android 8.0.0; G8141) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36", From 7ddb2575bd1c021a3e5c708ece6f6205103843d3 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 18 Dec 2021 15:13:19 +0700 Subject: [PATCH 19/24] Fix #533: Detect Sony BRAVIA as SmartTV --- src/ua-parser.js | 4 +++- test/device-test.json | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 56fefcc..44599fe 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -488,7 +488,7 @@ // ZTE /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i, - /(alcatel|geeksphone|nexian|panasonic|sony)[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony + /(alcatel|geeksphone|nexian|panasonic|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ // Acer @@ -616,6 +616,8 @@ ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ /\(dtv[\);].+(aquos)/i // Sharp ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ + /(bravia[\w- ]+) bui/i // Sony + ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ diff --git a/test/device-test.json b/test/device-test.json index 1b98a76..988e186 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1746,6 +1746,15 @@ "type": "tablet" } }, + { + "desc": "Sony BRAVIA 4K GB ATV3", + "ua": "Mozilla/5.0 (Linux; Andr0id 9; BRAVIA 4K GB ATV3 Build/PTT1.190515.001.S38) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 OPR/46.0.2207.0 OMI/4.13.0.180.DIA5.104 Model/Sony-BRAVIA-4K-GB-ATV3", + "expect": { + "vendor": "Sony", + "model": "BRAVIA 4K GB ATV3", + "type": "smarttv" + } + }, { "desc" : "Tesla", "ua" : "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/601.1 (KHTML, like Gecko) Tesla QtCarBrowser Safari/601.1", From f761a89ab2c2e53055d83a1d07acf677cb960d5f Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 13 Jan 2022 00:35:56 +0700 Subject: [PATCH 20/24] Fix #562 - Xiaomi Mi CC9 --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 44599fe..05e1e1f 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -397,7 +397,7 @@ /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi - /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi + /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ diff --git a/test/device-test.json b/test/device-test.json index 988e186..d87e616 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1901,6 +1901,15 @@ "type": "mobile" } }, + { + "desc": "Xiaomi Mi CC9", + "ua": "Mozilla/5.0 (Linux; U; Android 11; zh-cn; MI CC 9 Build/RKQ1.200826.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.116 Mobile Safari/537.36 XiaoMi/MiuiBrowser/15.5.18", + "expect": { + "vendor": "Xiaomi", + "model": "MI CC 9", + "type": "mobile" + } + }, { "desc": "Xiaomi MI PAD 2", "ua": "Mozilla/5.0 (Linux; Android 5.1; MI PAD 2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Safari/537.36 [FB_IAB/FB4A;FBAV/137.0.0.24.91;]", From a29213960c7a1b80fded50d82936002fd0ccb939 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 28 Jan 2022 22:16:51 +0700 Subject: [PATCH 21/24] Fix #561 - Increase UA_MAX_LENGTH to 275 --- src/ua-parser.js | 2 +- test/browser-test.json | 10 ++++++++++ test/test.js | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 05e1e1f..881a850 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -37,7 +37,7 @@ SMARTTV = 'smarttv', WEARABLE = 'wearable', EMBEDDED = 'embedded', - UA_MAX_LENGTH = 255; + UA_MAX_LENGTH = 275; var AMAZON = 'Amazon', APPLE = 'Apple', diff --git a/test/browser-test.json b/test/browser-test.json index 393aba7..bce9f22 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1463,5 +1463,15 @@ "version" : "4.2.7", "major" : "4" } + }, + { + "desc" : "IE11 on Windows 7 (ua length >255)", + "ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64; APCPMS=^N201205020840572565478A37A6F9C41BD33F_9975^; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; MARKANYEPS#25118; Zoom 3.6.0; rv:11.0) like Gecko", + "expect" : + { + "name" : "IE", + "version" : "11.0", + "major" : "11" + } } ] diff --git a/test/test.js b/test/test.js index 71d1f46..fc7ebc5 100644 --- a/test/test.js +++ b/test/test.js @@ -109,7 +109,7 @@ describe('Extending Regex', function () { }); describe('User-agent length', function () { - var UA_MAX_LENGTH = 255; + var UA_MAX_LENGTH = 275; // Real data from https://stackoverflow.com/questions/654921/how-big-can-a-user-agent-string-get#answer-6595973 var uaString = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; (R1 1.6); SLCC1; .NET CLR 2.0.50727; InfoPath.2; OfficeLiveConnector.1.3; OfficeLivePatch.0.0; .NET CLR 3.5.30729; .NET CLR 3.0.30618; 66760635803; runtime 11.00294; 876906799603; 97880703; 669602703; 9778063903; 877905603; 89670803; 96690803; 8878091903; 7879040603; 999608065603; 799808803; 6666059903; 669602102803; 888809342903; 696901603; 788907703; 887806555703; 97690214703; 66760903; 968909903; 796802422703; 8868026703; 889803611803; 898706903; 977806408603; 976900799903; 9897086903; 88780803; 798802301603; 9966008603; 66760703; 97890452603; 9789064803; 96990759803; 99960107703; 8868087903; 889801155603; 78890703; 8898070603; 89970603; 89970539603; 89970488703; 8789007603; 87890903; 877904603; 9887077703; 798804903; 97890264603; 967901703; 87890703; 97690420803; 79980706603; 9867086703; 996602846703; 87690803; 6989010903; 977809603; 666601903; 876905337803; 89670603; 89970200903; 786903603; 696901911703; 788905703; 896709803; 96890703; 998601903; 88980703; 666604769703; 978806603; 7988020803; 996608803; 788903297903; 98770043603; 899708803; 66960371603; 9669088903; 69990703; 99660519903; 97780603; 888801803; 9867071703; 79780803; 9779087603; 899708603; 66960456803; 898706824603; 78890299903; 99660703; 9768079803; 977901591603; 89670605603; 787903608603; 998607934903; 799808573903; 878909603; 979808146703; 9996088603; 797803154903; 69790603; 99660565603; 7869028603; 896707703; 97980965603; 976907191703; 88680703; 888809803; 69690903; 889805523703; 899707703; 997605035603; 89970029803; 9699094903; 877906803; 899707002703; 786905857603; 69890803; 97980051903; 997603978803; 9897097903; 66960141703; 7968077603; 977804603; 88980603; 989700803; 999607887803; 78690772803; 96990560903; 98970961603; 9996032903; 9699098703; 69890655603; 978903803; 698905066803; 977806903; 9789061703; 967903747703; 976900550903; 88980934703; 8878075803; 8977028703; 97980903; 9769006603; 786900803; 98770682703; 78790903; 878906967903; 87690399603; 99860976703; 796805703; 87990603; 968906803; 967904724603; 999606603; 988705903; 989702842603; 96790603; 99760703; 88980166703; 9799038903; 98670903; 697905248603; 7968043603; 66860703; 66860127903; 9779048903; 89670123903; 78890397703; 97890603; 87890803; 8789030603; 69990603; 88880763703; 9769000603; 96990203903; 978900405903; 7869022803; 699905422903; 97890703; 87990903; 878908703; 7998093903; 898702507603; 97780637603; 966907903; 896702603; 9769004803; 7869007903; 99660158803; 7899099603; 8977055803; 99660603; 7889080903; 66660981603; 997604603; 6969089803; 899701903; 9769072703; 666603903; 99860803; 997608803; 69790903; 88680756703; 979805677903; 9986047703; 89970803; 66660603; 96690903; 8997051603; 789901209803; 8977098903; 968900326803; 87790703; 98770024803; 697901794603; 69990803; 887805925803; 968908903; 97880603; 897709148703; 877909476903; 66760197703; 977908603; 698902703; 988706504803; 977802026603; 88680964703; 8878068703; 987705107903; 978902878703; 8898069803; 9768031703; 79680803; 79980803; 669609328703; 89870238703; 99960593903; 969904218703; 78890603; 9788000703; 69690630903; 889800982903; 988709748803; 7968052803; 99960007803; 969900800803; 668604817603; 66960903; 78790734603; 8868007703; 79780034903; 8878085903; 976907603; 89670830803; 877900903; 969904889703; 7978033903; 8987043903; 99860703; 979805903; 667603803; 976805348603; 999604127603; 97790701603; 78990342903; 98770672903; 87990253903; 9877027703; 97790803; 877901895603; 8789076903; 896708595603; 997601903; 799806903; 97690603; 87790371703; 667605603; 99760303703; 97680283803; 788902750803; 787909803; 79780603; 79880866903; 9986050903; 87890543903; 979800803; 97690179703; 876901603; 699909903; 96990192603; 878904903; 877904734903; 796801446903; 977904803; 9887044803; 797805565603; 98870789703; 7869093903; 87790727703; 797801232803; 666604803; 9778071903; 9799086703; 6969000903; 89670903; 8799075903; 897708903; 88680903; 97980362603; 97980503903; 889803256703; 88980388703; 789909376803; 69690703; 6969025903; 89970309903; 96690703; 877901847803; 968901903; 96690603; 88680607603; 7889001703; 789904761803; 976807703; 976902903; 878907889703; 9897014903; 896707046603; 696909903; 666603998903; 969902703; 79680421803; 9769075603; 798800192703; 97990903; 9689024903; 668604803; 969908671903; 9996094703; 69990642703; 97890895903; 977805619903; 79980859903; 88980443803; 98970649603; 997602703; 888802169903; 699907803; 667602028803; 786903283903; 997607703; 969909803; 798809925903; 9976045603; 97790903; 9789001903; 966903603; 9789069603; 968906603; 6989091803; 896701603; 6979059803; 978803903; 997606362603; 88980803; 98970803; 88880921703; 8997065703; 899700703; 698908703; 797801027903; 7889050903; 87890603; 78690703; 99660069703; 97980309903; 976800603; 666606803; 898707703; 79880019803; 66960250803; 7978049803; 88780602603; 79680903; 88880792703; 96990903; 667608603; 87790730903; 98970903; 9699032903; 8987004803; 88880703; 89770046603; 978800803; 969908903; 9798022603; 696901903; 799803703; 989703703; 668605903; 79780903; 998601371703; 796803339703; 87890922603; 898708903; 9966061903; 66960891903; 96790903; 8779050803; 98870858803; 976909298603; 9887029903; 669608703; 979806903; 878903803; 99960703; 9789086703; 979801803; 66960008703; 979806830803; 99760212703; 786906603; 797807603; 789907297703; 96990703; 786901603; 796807766603; 896702651603; 789902585603; 66660925903; 9986085703; 66960302703; 69890703; 789900703; 89970903; 9679060703; 9789002903; 979908821603; 986708140803; 976809828703; 7988082803; 79680997903; 99960803; 9788081903; 979805703; 787908603; 66960602803; 9887098703; 978803237703; 888806804603; 999604703; 977904703; 966904635703; 97680291703; 977809345603; 8878046703; 988709803; 976900773603; 989703903; 88780198603; 87790603; 986708703; 78890604703; 87790544803; 976809850903; 887806703; 987707527603; 79880803; 9897059603; 897709820603; 97880804803; 66960026703; 9789062803; 9867090803; 669600603; 8967087703; 78890903; 89770903; 97980703; 976802687603; 66860400803; 979901288603; 96990160903; 99860228903; 966900703; 66760603; 9689035703; 9779064703; 7968023603; 87890791903; 98770870603; 9798005803; 6969087903; 9779097903; 6979065703; 699903252603; 79780989703; 87690901803; 978905763903; 977809703; 97790369703; 899703269603; 8878012703; 78790803; 87690395603; 8888042803; 667607689903; 8977041803; 6666085603; 6999080703; 69990797803; 88680721603; 99660519803; 889807603; 87890146703; 699906325903; 89770603; 669608615903; 9779028803; 88880603; 97790703; 79780703; 97680355603; 6696024803; 78790784703; 97880329903; 9699077703; 89870803; 79680227903; 976905852703; 8997098903; 896704796703; 66860598803; 9897036703; 66960703; 9699094703; 9699008703; 97780485903; 999603179903; 89770834803; 96790445603; 79680460903; 9867009603; 89870328703; 799801035803; 989702903; 66960758903; 66860150803; 6686088603; 9877092803; 96990603; 99860603; 987703663603; 98870903; 699903325603; 87790803; 97680703; 8868030703; 9799030803; 89870703; 97680803; 9669054803; 6979097603; 987708046603; 999608603; 878904803; 998607408903; 968903903; 696900703; 977907491703; 6686033803; 669601803; 99960290603; 887809169903; 979803703; 69890903; 699901447903; 8987064903; 799800603; 98770903; 8997068703; 967903603; 66760146803; 978805087903; 697908138603; 799801603; 88780964903; 989708339903; 8967048603; 88880981603; 789909703; 796806603; 977905977603; 989700603; 97780703; 9669062603; 88980714603; 897709545903; 988701916703; 667604694903; 786905664603; 877900803; 886805490903; 89970559903; 99960531803; 7998033903; 98770803; 78890418703; 669600872803; 996605216603; 78690962703; 667604903; 996600903; 999608903; 9699083803; 787901803; 97780707603; 787905312703; 977805803; 8977033703; 97890708703; 989705521903; 978800703; 698905703; 78890376903; 878907703; 999602903; 986705903; 668602719603; 979901803; 997606903; 66760393903; 987703603; 78790338903; 96890803; 97680596803; 666601603; 977902178803; 877902803; 78790038603; 8868075703; 99960060603)'; From b6bddd8c0912cb0b59462a05e324d16fca724fcd Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Thu, 17 Feb 2022 11:39:01 -0800 Subject: [PATCH 22/24] pr feedback --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 5f8a265..5a59d5c 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -388,7 +388,7 @@ /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /(?:huawei|honor)([-\w ]+)[;\)]/i, - /\b(nexus 6p|lya-l0c|yale?\-a?l\d{2}[ad]?|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b(?!.+d\/s)/i + /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi From f02a431000c3de85b2e6ea8c6a06ecb2c0fadf4d Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Thu, 17 Feb 2022 12:01:10 -0800 Subject: [PATCH 23/24] v100 tests --- test/browser-test.json | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/browser-test.json b/test/browser-test.json index bce9f22..fd413b9 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -189,6 +189,16 @@ "major" : "20" } }, + { + "desc" : "Chrome", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4758.102 Safari/537.36", + "expect" : + { + "name" : "Chrome", + "version" : "100.0.4758.102", + "major" : "100" + } + }, { "desc" : "Chrome Headless", "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome Safari/537.36", @@ -409,6 +419,16 @@ "major" : "15" } }, + { + "desc" : "Firefox", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:100.0) Gecko/20100101 Firefox/100.0", + "expect" : + { + "name" : "Firefox", + "version" : "100.0", + "major" : "100" + } + }, { "desc" : "Firefox Reality", "ua" : "Mozilla/5.0 (Android 7.1.2; Mobile VR; rv:65.0) Gecko/65.0 Firefox/65.0", @@ -1258,6 +1278,16 @@ "major" : "18" } }, + { + "desc" : "Microsoft Edge 100", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.1108.55 Safari/537.36 Edg/100.0.1108.55", + "expect" : + { + "name" : "Edge", + "version" : "100.0.1108.55", + "major" : "100" + } + }, { "desc" : "Microsoft Edge on iOS", "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 11_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 EdgiOS/42.1.1.0 Mobile/15F79 Safari/605.1.15", From 8ee5b01fbc4d6b7c2302bdfc5a5dcb14e8b46a73 Mon Sep 17 00:00:00 2001 From: Dean Shi Date: Thu, 19 May 2022 16:20:32 -0700 Subject: [PATCH 24/24] fix test --- security.md | 5 - src/ua-parser.js | 368 +++++++++++++++++++++++------------------------ 2 files changed, 177 insertions(+), 196 deletions(-) delete mode 100644 security.md diff --git a/security.md b/security.md deleted file mode 100644 index de525bb..0000000 --- a/security.md +++ /dev/null @@ -1,5 +0,0 @@ -# Security Policy - -## Reporting a Vulnerability - -Please report security issues to `f@faisalman.com` diff --git a/src/ua-parser.js b/src/ua-parser.js index 777f0ff..09294c2 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -80,24 +80,18 @@ return enums; }, has = function (str1, str2) { - return typeof str1 === STR_TYPE - ? lowerize(str2).indexOf(lowerize(str1)) !== -1 - : false; + return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false; }, lowerize = function (str) { return str.toLowerCase(); }, majorize = function (version) { - return typeof version === STR_TYPE - ? version.replace(/[^\d\.]/g, EMPTY).split(".")[0] - : undefined; + return typeof version === STR_TYPE ? version.replace(/[^\d\.]/g, EMPTY).split(".")[0] : undefined; }, trim = function (str, len) { if (typeof str === STR_TYPE) { str = str.replace(/^\s\s*/, EMPTY).replace(/\s\s*$/, EMPTY); - return typeof len === UNDEF_TYPE - ? str - : str.substring(0, UA_MAX_LENGTH); + return typeof len === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); } }; @@ -142,17 +136,13 @@ // check whether function or regex if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) { // call function (usually string mapper) - this[q[0]] = match - ? q[1].call(this, match, q[2]) - : undefined; + this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined; } else { // sanitize match using given regex this[q[0]] = match ? match.replace(q[1], q[2]) : undefined; } } else if (q.length === 4) { - this[q[0]] = match - ? q[3].call(this, match.replace(q[1], q[2])) - : undefined; + this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined; } } else { this[q] = match ? match : undefined; @@ -192,7 +182,7 @@ "2.0.2": "/416", "2.0.3": "/417", "2.0.4": "/419", - "?": "/", + "?": "/" }, windowsVersionMap = { ME: "4.90", @@ -205,7 +195,7 @@ 8: "NT 6.2", 8.1: "NT 6.3", 10: ["NT 6.4", "NT 10.0"], - RT: "ARM", + RT: "ARM" }; ////////////// @@ -215,26 +205,26 @@ var regexes = { browser: [ [ - /\b(?:crmo|crios)\/([\w\.]+)/i, // Chrome for Android/iOS + /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS ], [VERSION, [NAME, "Chrome"]], [ - /edg(?:e|ios|a)?\/([\w\.]+)/i, // Microsoft Edge + /edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge ], [VERSION, [NAME, "Edge"]], [ // Presto based /(opera mini)\/([-\w\.]+)/i, // Opera Mini /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i, // Opera Mobi/Tablet - /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i, // Opera + /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i // Opera ], [NAME, VERSION], [ - /opios[\/ ]+([\w\.]+)/i, // Opera mini on iphone >= 8.0 + /opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0 ], [VERSION, [NAME, OPERA + " Mini"]], [ - /\bopr\/([\w\.]+)/i, // Opera Webkit + /\bopr\/([\w\.]+)/i // Opera Webkit ], [VERSION, [NAME, OPERA]], [ @@ -249,139 +239,139 @@ // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([-\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ - /(weibo)__([\d\.]+)/i, // Weibo + /(weibo)__([\d\.]+)/i // Weibo ], [NAME, VERSION], [ - /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i, // UCBrowser + /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser ], [VERSION, [NAME, "UC" + BROWSER]], [ - /\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser + /\bqbcore\/([\w\.]+)/i // WeChat Desktop for Windows Built-in Browser ], [VERSION, [NAME, "WeChat(Win) Desktop"]], [ - /micromessenger\/([\w\.]+)/i, // WeChat + /micromessenger\/([\w\.]+)/i // WeChat ], [VERSION, [NAME, "WeChat"]], [ - /konqueror\/([\w\.]+)/i, // Konqueror + /konqueror\/([\w\.]+)/i // Konqueror ], [VERSION, [NAME, "Konqueror"]], [ - /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i, // IE11 + /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11 ], [VERSION, [NAME, "IE"]], [ - /yabrowser\/([\w\.]+)/i, // Yandex + /yabrowser\/([\w\.]+)/i // Yandex ], [VERSION, [NAME, "Yandex"]], [ - /(avast|avg)\/([\w\.]+)/i, // Avast/AVG Secure Browser + /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser ], [[NAME, /(.+)/, "$1 Secure " + BROWSER], VERSION], [ - /\bfocus\/([\w\.]+)/i, // Firefox Focus + /\bfocus\/([\w\.]+)/i // Firefox Focus ], [VERSION, [NAME, FIREFOX + " Focus"]], [ - /\bopt\/([\w\.]+)/i, // Opera Touch + /\bopt\/([\w\.]+)/i // Opera Touch ], [VERSION, [NAME, OPERA + " Touch"]], [ - /coc_coc\w+\/([\w\.]+)/i, // Coc Coc Browser + /coc_coc\w+\/([\w\.]+)/i // Coc Coc Browser ], [VERSION, [NAME, "Coc Coc"]], [ - /dolfin\/([\w\.]+)/i, // Dolphin + /dolfin\/([\w\.]+)/i // Dolphin ], [VERSION, [NAME, "Dolphin"]], [ - /coast\/([\w\.]+)/i, // Opera Coast + /coast\/([\w\.]+)/i // Opera Coast ], [VERSION, [NAME, OPERA + " Coast"]], [ - /miuibrowser\/([\w\.]+)/i, // MIUI Browser + /miuibrowser\/([\w\.]+)/i // MIUI Browser ], [VERSION, [NAME, "MIUI " + BROWSER]], [ - /fxios\/([-\w\.]+)/i, // Firefox for iOS + /fxios\/([-\w\.]+)/i // Firefox for iOS ], [VERSION, [NAME, FIREFOX]], [ - /\bqihu|(qi?ho?o?|360)browser/i, // 360 + /\bqihu|(qi?ho?o?|360)browser/i // 360 ], [[NAME, "360 " + BROWSER]], [/(oculus|samsung|sailfish)browser\/([\w\.]+)/i], [[NAME, /(.+)/, "$1 " + BROWSER], VERSION], [ // Oculus/Samsung/Sailfish Browser - /(comodo_dragon)\/([\w\.]+)/i, // Comodo Dragon + /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, " "], VERSION], [ /(electron)\/([\w\.]+) safari/i, // Electron-based App /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla - /m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i, // QQBrowser/Baidu App/2345 Browser + /m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser ], [NAME, VERSION], [ /(metasr)[\/ ]?([\w\.]+)/i, // SouGouBrowser - /(lbbrowser)/i, // LieBao Browser + /(lbbrowser)/i // LieBao Browser ], [NAME], [ // WebView - /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i, // Facebook App for iOS & Android + /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android ], [[NAME, FACEBOOK], VERSION], [ /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android - /(chromium|instagram)[\/ ]([-\w\.]+)/i, // Chromium/Instagram + /(chromium|instagram)[\/ ]([-\w\.]+)/i // Chromium/Instagram ], [NAME, VERSION], [ - /\bgsa\/([\w\.]+) .*safari\//i, // Google Search Appliance on iOS + /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS ], [VERSION, [NAME, "GSA"]], [ - /headlesschrome(?:\/([\w\.]+)| )/i, // Chrome Headless + /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless ], [VERSION, [NAME, CHROME + " Headless"]], [ - / wv\).+(chrome)\/([\w\.]+)/i, // Chrome WebView + / wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView ], [[NAME, CHROME + " WebView"], VERSION], [ - /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i, // Android Browser + /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser ], [VERSION, [NAME, "Android " + BROWSER]], [ - /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i, // Chrome/OmniWeb/Arora/Tizen/Nokia + /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia ], [NAME, VERSION], [ - /version\/([\w\.]+) .*mobile\/\w+ (safari)/i, // Mobile Safari + /version\/([\w\.]+) .*mobile\/\w+ (safari)/i // Mobile Safari ], [VERSION, [NAME, "Mobile Safari"]], [ - /version\/([\w\.]+) .*(mobile ?safari|safari)/i, // Safari & Safari Mobile + /version\/([\w\.]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile ], [VERSION, NAME], [ - /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i, // Safari < 3.0 + /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 ], [NAME, [VERSION, strMapper, oldSafariMap]], [/(webkit|khtml)\/([\w\.]+)/i], [NAME, VERSION], [ // Gecko based - /(navigator|netscape\d?)\/([-\w\.]+)/i, // Netscape + /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape ], [[NAME, "Netscape"], VERSION], [ - /mobile vr; rv:([\w\.]+)\).+firefox/i, // Firefox Reality + /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality ], [VERSION, [NAME, FIREFOX + " Reality"]], [ @@ -397,50 +387,50 @@ // Other /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser - /(links) \(([\w\.]+)/i, // Links + /(links) \(([\w\.]+)/i // Links ], - [NAME, VERSION], + [NAME, VERSION] ], cpu: [ [ - /(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i, // AMD64 (x64) + /(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i // AMD64 (x64) ], [[ARCHITECTURE, "amd64"]], [ - /(ia32(?=;))/i, // IA32 (quicktime) + /(ia32(?=;))/i // IA32 (quicktime) ], [[ARCHITECTURE, lowerize]], [ - /((?:i[346]|x)86)[;\)]/i, // IA32 (x86) + /((?:i[346]|x)86)[;\)]/i // IA32 (x86) ], [[ARCHITECTURE, "ia32"]], [ - /\b(aarch64|arm(v?8e?l?|_?64))\b/i, // ARM64 + /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64 ], [[ARCHITECTURE, "arm64"]], [ - /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i, // ARMHF + /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF ], [[ARCHITECTURE, "armhf"]], [ // PocketPC mistakenly identified as PowerPC - /windows (ce|mobile); ppc;/i, + /windows (ce|mobile); ppc;/i ], [[ARCHITECTURE, "arm"]], [ - /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i, // PowerPC + /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [ - /(sun4\w)[;\)]/i, // SPARC + /(sun4\w)[;\)]/i // SPARC ], [[ARCHITECTURE, "sparc"]], [ - /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i, + /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC ], - [[ARCHITECTURE, lowerize]], + [[ARCHITECTURE, lowerize]] ], device: [ @@ -451,42 +441,42 @@ ///////////////////////// // Samsung - /\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i, + /\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [ /\b((?:s[cgp]h|gt|sm)-\w+|galaxy nexus)/i, /samsung[- ]([-\w]+)/i, - /sec-(sgh\w+)/i, + /sec-(sgh\w+)/i ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [ // Apple - /((ipod|iphone)\d+,\d+)/i, // iPod/iPhone model + /((ipod|iphone)\d+,\d+)/i // iPod/iPhone model ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [ - /(ipad\d+,\d+)/i, // iPad model + /(ipad\d+,\d+)/i // iPad model ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ - /\((ip(?:hone|od)[\w ]*);/i, // iPod/iPhone + /\((ip(?:hone|od)[\w ]*);/i // iPod/iPhone ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [ /\((ipad);[-\w\),; ]+apple/i, // iPad /applecoremedia\/[\w\.]+ \((ipad)/i, - /\b(ipad)\d\d?,\d\d?[;\]].+ios/i, + /\b(ipad)\d\d?,\d\d?[;\]].+ios/i ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ // Huawei - /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i, + /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /(?:huawei|honor)([-\w ]+)[;\)]/i, - /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i, + /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ @@ -495,135 +485,135 @@ /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi - /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i, // Xiaomi Mi + /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi ], [ [MODEL, /_/g, " "], [VENDOR, XIAOMI], - [TYPE, MOBILE], + [TYPE, MOBILE] ], [ - /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i, // Mi Pad tablets + /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets ], [ [MODEL, /_/g, " "], [VENDOR, XIAOMI], - [TYPE, TABLET], + [TYPE, TABLET] ], [ // OPPO /; (\w+) bui.+ oppo/i, - /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i, + /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i ], [MODEL, [VENDOR, "OPPO"], [TYPE, MOBILE]], [ // Vivo /vivo (\w+)(?: bui|\))/i, - /\b(v[12]\d{3}\w?[at])(?: bui|;)/i, + /\b(v[12]\d{3}\w?[at])(?: bui|;)/i ], [MODEL, [VENDOR, "Vivo"], [TYPE, MOBILE]], [ // Realme - /\b(rmx[12]\d{3})(?: bui|;|\))/i, + /\b(rmx[12]\d{3})(?: bui|;|\))/i ], [MODEL, [VENDOR, "Realme"], [TYPE, MOBILE]], [ // Motorola /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i, /\bmot(?:orola)?[- ](\w*)/i, - /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i, + /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [/\b(mz60\d|xoom[2 ]{0,2}) build\//i], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [ // LG - /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i, + /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i, - /\blg-?([\d\w]+) bui/i, + /\blg-?([\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ // Lenovo /(ideatab[-\w ]+)/i, - /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i, + /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i ], [MODEL, [VENDOR, "Lenovo"], [TYPE, TABLET]], [ // Nokia /(?:maemo|nokia).*(n900|lumia \d+)/i, - /nokia[-_ ]?([-\w\.]*)/i, + /nokia[-_ ]?([-\w\.]*)/i ], [ [MODEL, /_/g, " "], [VENDOR, "Nokia"], - [TYPE, MOBILE], + [TYPE, MOBILE] ], [ // Google - /(pixel c)\b/i, // Google Pixel C + /(pixel c)\b/i // Google Pixel C ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [ - /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i, // Google Pixel + /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i // Google Pixel ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ // Sony - /droid.+ (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i, + /droid.+ (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [/sony tablet [ps]/i, /\b(?:sony)?sgp\w+(?: bui|\))/i], [ [MODEL, "Xperia Tablet"], [VENDOR, SONY], - [TYPE, TABLET], + [TYPE, TABLET] ], [ // OnePlus / (kb2005|in20[12]5|be20[12][59])\b/i, - /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i, + /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i ], [MODEL, [VENDOR, "OnePlus"], [TYPE, MOBILE]], [ // Amazon /(alexa)webm/i, /(kf[a-z]{2}wi)( bui|\))/i, // Kindle Fire without Silk - /(kf[a-z]+)( bui|\)).+silk\//i, // Kindle Fire HD + /(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [ - /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i, // Fire Phone + /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone ], [ [MODEL, /(.+)/g, "Fire Phone $1"], [VENDOR, AMAZON], - [TYPE, MOBILE], + [TYPE, MOBILE] ], [ // BlackBerry - /(playbook);[-\w\),; ]+(rim)/i, // BlackBerry PlayBook + /(playbook);[-\w\),; ]+(rim)/i // BlackBerry PlayBook ], [MODEL, VENDOR, [TYPE, TABLET]], [ /\b((?:bb[a-f]|st[hv])100-\d)/i, - /\(bb10; (\w+)/i, // BlackBerry 10 + /\(bb10; (\w+)/i // BlackBerry 10 ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [ // Asus - /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i, + /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [ // HTC - /(nexus 9)/i, // HTC Nexus 9 + /(nexus 9)/i // HTC Nexus 9 ], [MODEL, [VENDOR, "HTC"], [TYPE, TABLET]], [ @@ -631,23 +621,23 @@ // ZTE /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i, - /(alcatel|geeksphone|nexian|panasonic|sony(?!-bra))[-_ ]?([-\w]*)/i, // Alcatel/GeeksPhone/Nexian/Panasonic/Sony + /(alcatel|geeksphone|nexian|panasonic|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony ], [VENDOR, [MODEL, /_/g, " "], [TYPE, MOBILE]], [ // Acer - /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i, + /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i ], [MODEL, [VENDOR, "Acer"], [TYPE, TABLET]], [ // Meizu /droid.+; (m[1-5] note) bui/i, - /\bmz-([-\w]{2,})/i, + /\bmz-([-\w]{2,})/i ], [MODEL, [VENDOR, "Meizu"], [TYPE, MOBILE]], [ // Sharp - /\b(sh-?[altvz]?\d\d[a-ekm]?)/i, + /\b(sh-?[altvz]?\d\d[a-ekm]?)/i ], [MODEL, [VENDOR, "Sharp"], [TYPE, MOBILE]], [ @@ -659,7 +649,7 @@ /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia /(lenovo)[-_ ]?([-\w]+)/i, // Lenovo /(jolla)/i, // Jolla - /(oppo) ?([\w ]+) bui/i, // OPPO + /(oppo) ?([\w ]+) bui/i // OPPO ], [VENDOR, MODEL, [TYPE, MOBILE]], [ @@ -671,118 +661,118 @@ /(le[- ]+pan)[- ]+(\w{1,9}) bui/i, // Le Pan Tablets /(trinity)[- ]*(t\d{3}) bui/i, // Trinity Tablets /(gigaset)[- ]+(q\w{1,9}) bui/i, // Gigaset Tablets - /(vodafone) ([\w ]+)(?:\)| bui)/i, // Vodafone + /(vodafone) ([\w ]+)(?:\)| bui)/i // Vodafone ], [VENDOR, MODEL, [TYPE, TABLET]], [ - /(surface duo)/i, // Surface Duo + /(surface duo)/i // Surface Duo ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [ - /droid [\d\.]+; (fp\du?)(?: b|\))/i, // Fairphone + /droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone ], [MODEL, [VENDOR, "Fairphone"], [TYPE, MOBILE]], [ - /(u304aa)/i, // AT&T + /(u304aa)/i // AT&T ], [MODEL, [VENDOR, "AT&T"], [TYPE, MOBILE]], [ - /\bsie-(\w*)/i, // Siemens + /\bsie-(\w*)/i // Siemens ], [MODEL, [VENDOR, "Siemens"], [TYPE, MOBILE]], [ - /\b(rct\w+) b/i, // RCA Tablets + /\b(rct\w+) b/i // RCA Tablets ], [MODEL, [VENDOR, "RCA"], [TYPE, TABLET]], [ - /\b(venue[\d ]{2,7}) b/i, // Dell Venue Tablets + /\b(venue[\d ]{2,7}) b/i // Dell Venue Tablets ], [MODEL, [VENDOR, "Dell"], [TYPE, TABLET]], [ - /\b(q(?:mv|ta)\w+) b/i, // Verizon Tablet + /\b(q(?:mv|ta)\w+) b/i // Verizon Tablet ], [MODEL, [VENDOR, "Verizon"], [TYPE, TABLET]], [ - /\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i, // Barnes & Noble Tablet + /\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i // Barnes & Noble Tablet ], [MODEL, [VENDOR, "Barnes & Noble"], [TYPE, TABLET]], [/\b(tm\d{3}\w+) b/i], [MODEL, [VENDOR, "NuVision"], [TYPE, TABLET]], [ - /\b(k88) b/i, // ZTE K Series Tablet + /\b(k88) b/i // ZTE K Series Tablet ], [MODEL, [VENDOR, "ZTE"], [TYPE, TABLET]], [ - /\b(nx\d{3}j) b/i, // ZTE Nubia + /\b(nx\d{3}j) b/i // ZTE Nubia ], [MODEL, [VENDOR, "ZTE"], [TYPE, MOBILE]], [ - /\b(gen\d{3}) b.+49h/i, // Swiss GEN Mobile + /\b(gen\d{3}) b.+49h/i // Swiss GEN Mobile ], [MODEL, [VENDOR, "Swiss"], [TYPE, MOBILE]], [ - /\b(zur\d{3}) b/i, // Swiss ZUR Tablet + /\b(zur\d{3}) b/i // Swiss ZUR Tablet ], [MODEL, [VENDOR, "Swiss"], [TYPE, TABLET]], [ - /\b((zeki)?tb.*\b) b/i, // Zeki Tablets + /\b((zeki)?tb.*\b) b/i // Zeki Tablets ], [MODEL, [VENDOR, "Zeki"], [TYPE, TABLET]], [ /\b([yr]\d{2}) b/i, - /\b(dragon[- ]+touch |dt)(\w{5}) b/i, // Dragon Touch Tablet + /\b(dragon[- ]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet ], [[VENDOR, "Dragon Touch"], MODEL, [TYPE, TABLET]], [ - /\b(ns-?\w{0,9}) b/i, // Insignia Tablets + /\b(ns-?\w{0,9}) b/i // Insignia Tablets ], [MODEL, [VENDOR, "Insignia"], [TYPE, TABLET]], [ - /\b((nxa|next)-?\w{0,9}) b/i, // NextBook Tablets + /\b((nxa|next)-?\w{0,9}) b/i // NextBook Tablets ], [MODEL, [VENDOR, "NextBook"], [TYPE, TABLET]], [ - /\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i, // Voice Xtreme Phones + /\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones ], [[VENDOR, "Voice"], MODEL, [TYPE, MOBILE]], [ - /\b(lvtel\-)?(v1[12]) b/i, // LvTel Phones + /\b(lvtel\-)?(v1[12]) b/i // LvTel Phones ], [[VENDOR, "LvTel"], MODEL, [TYPE, MOBILE]], [ - /\b(ph-1) /i, // Essential PH-1 + /\b(ph-1) /i // Essential PH-1 ], [MODEL, [VENDOR, "Essential"], [TYPE, MOBILE]], [ - /\b(v(100md|700na|7011|917g).*\b) b/i, // Envizen Tablets + /\b(v(100md|700na|7011|917g).*\b) b/i // Envizen Tablets ], [MODEL, [VENDOR, "Envizen"], [TYPE, TABLET]], [ - /\b(trio[-\w\. ]+) b/i, // MachSpeed Tablets + /\b(trio[-\w\. ]+) b/i // MachSpeed Tablets ], [MODEL, [VENDOR, "MachSpeed"], [TYPE, TABLET]], [ - /\btu_(1491) b/i, // Rotor Tablets + /\btu_(1491) b/i // Rotor Tablets ], [MODEL, [VENDOR, "Rotor"], [TYPE, TABLET]], [ - /(shield[\w ]+) b/i, // Nvidia Shield Tablets + /(shield[\w ]+) b/i // Nvidia Shield Tablets ], [MODEL, [VENDOR, "Nvidia"], [TYPE, TABLET]], [ - /(sprint) (\w+)/i, // Sprint Phones + /(sprint) (\w+)/i // Sprint Phones ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - /(kin\.[onetw]{3})/i, // Microsoft Kin + /(kin\.[onetw]{3})/i // Microsoft Kin ], [ [MODEL, /\./g, " "], [VENDOR, MICROSOFT], - [TYPE, MOBILE], + [TYPE, MOBILE] ], [ - /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i, // Zebra + /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra ], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i], @@ -793,19 +783,19 @@ /////////////////// /(ouya)/i, // Ouya - /(nintendo) ([wids3utch]+)/i, // Nintendo + /(nintendo) ([wids3utch]+)/i // Nintendo ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ - /droid.+; (shield) bui/i, // Nvidia + /droid.+; (shield) bui/i // Nvidia ], [MODEL, [VENDOR, "Nvidia"], [TYPE, CONSOLE]], [ - /(playstation [345portablevi]+)/i, // Playstation + /(playstation [345portablevi]+)/i // Playstation ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [ - /\b(xbox(?: one)?(?!; xbox))[\); ]/i, // Microsoft Xbox + /\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [ @@ -813,57 +803,57 @@ // SMARTTVS /////////////////// - /smart-tv.+(samsung)/i, // Samsung + /smart-tv.+(samsung)/i // Samsung ], [VENDOR, [TYPE, SMARTTV]], [/hbbtv.+maple;(\d+)/i], [ [MODEL, /^/, "SmartTV"], [VENDOR, SAMSUNG], - [TYPE, SMARTTV], + [TYPE, SMARTTV] ], [ - /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i, // LG SmartTV + /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i // LG SmartTV ], [ [VENDOR, LG], - [TYPE, SMARTTV], + [TYPE, SMARTTV] ], [ - /(apple) ?tv/i, // Apple TV + /(apple) ?tv/i // Apple TV ], [VENDOR, [MODEL, APPLE + " TV"], [TYPE, SMARTTV]], [ - /crkey/i, // Google Chromecast + /crkey/i // Google Chromecast ], [ [MODEL, CHROME + "cast"], [VENDOR, GOOGLE], - [TYPE, SMARTTV], + [TYPE, SMARTTV] ], [ - /droid.+aft(\w)( bui|\))/i, // Fire TV + /droid.+aft(\w)( bui|\))/i // Fire TV ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ - /\(dtv[\);].+(aquos)/i, // Sharp + /\(dtv[\);].+(aquos)/i // Sharp ], [MODEL, [VENDOR, "Sharp"], [TYPE, SMARTTV]], [ - /(bravia[\w- ]+) bui/i, // Sony + /(bravia[\w- ]+) bui/i // Sony ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku - /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i, // HbbTV devices + /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i // HbbTV devices ], [ [VENDOR, trim], [MODEL, trim], - [TYPE, SMARTTV], + [TYPE, SMARTTV] ], [ - /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i, // SmartTV from Unidentified Vendors + /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors ], [[TYPE, SMARTTV]], [ @@ -871,17 +861,17 @@ // WEARABLES /////////////////// - /((pebble))app/i, // Pebble + /((pebble))app/i // Pebble ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ - /droid.+; (glass) \d/i, // Google Glass + /droid.+; (glass) \d/i // Google Glass ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [/droid.+; (wt63?0{2,3})\)/i], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ - /(quest( 2)?)/i, // Oculus Quest + /(quest( 2)?)/i // Oculus Quest ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ @@ -889,7 +879,7 @@ // EMBEDDED /////////////////// - /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i, // Tesla + /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i // Tesla ], [VENDOR, [TYPE, EMBEDDED]], [ @@ -897,34 +887,34 @@ // MIXED (GENERIC) /////////////////// - /droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i, // Android Phones from Unidentified Vendors + /droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors ], [MODEL, [TYPE, MOBILE]], [ - /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i, // Android Tablets from Unidentified Vendors + /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors ], [MODEL, [TYPE, TABLET]], [ - /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i, // Unidentifiable Tablet + /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet ], [[TYPE, TABLET]], [ - /(phone|mobile(?:[;\/]| safari)|pda(?=.+windows ce))/i, // Unidentifiable Mobile + /(phone|mobile(?:[;\/]| safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile ], [[TYPE, MOBILE]], [ - /(android[-\w\. ]{0,9});.+buil/i, // Generic Android Device + /(android[-\w\. ]{0,9});.+buil/i // Generic Android Device ], - [MODEL, [VENDOR, "Generic"]], + [MODEL, [VENDOR, "Generic"]] ], engine: [ [ - /windows.+ edge\/([\w\.]+)/i, // EdgeHTML + /windows.+ edge\/([\w\.]+)/i // EdgeHTML ], [VERSION, [NAME, EDGE + "HTML"]], [ - /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i, // Blink + /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink ], [VERSION, [NAME, "Blink"]], [ @@ -932,52 +922,52 @@ /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna /ekioh(flow)\/([\w\.]+)/i, // Flow /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links - /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab + /(icab)[\/ ]([23]\.[\d\.]+)/i // iCab ], [NAME, VERSION], [ - /rv\:([\w\.]{1,9})\b.+(gecko)/i, // Gecko + /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko ], - [VERSION, NAME], + [VERSION, NAME] ], os: [ [ // Windows - /microsoft (windows) (vista|xp)/i, // Windows (iTunes) + /microsoft (windows) (vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ /(windows) nt 6\.2; (arm)/i, // Windows RT /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i, // Windows Phone - /(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i, + /(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i ], [NAME, [VERSION, strMapper, windowsVersionMap]], [/(win(?=3|9|n)|win 9x )([nt\d\.]+)/i], [ [NAME, "Windows"], - [VERSION, strMapper, windowsVersionMap], + [VERSION, strMapper, windowsVersionMap] ], [ // iOS/macOS /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS - /cfnetwork\/.+darwin/i, + /cfnetwork\/.+darwin/i ], [ [VERSION, /_/g, "."], - [NAME, "iOS"], + [NAME, "iOS"] ], [ /(mac os x) ?([\w\. ]*)/i, - /(macintosh|mac_powerpc\b)(?!.+haiku)/i, // Mac OS + /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS ], [ [NAME, "Mac OS"], - [VERSION, /_/g, "."], + [VERSION, /_/g, "."] ], [ // Mobile OSes - /droid ([\w\.]+)\b.+(android[- ]x86)/i, // Android-x86 + /droid ([\w\.]+)\b.+(android[- ]x86)/i // Android-x86 ], [VERSION, NAME], [ @@ -985,33 +975,33 @@ /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS - /\((series40);/i, // Series 40 + /\((series40);/i // Series 40 ], [NAME, VERSION], [ - /\(bb(10);/i, // BlackBerry 10 + /\(bb(10);/i // BlackBerry 10 ], [VERSION, [NAME, BLACKBERRY]], [ - /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i, // Symbian + /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i // Symbian ], [VERSION, [NAME, "Symbian"]], [ - /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i, // Firefox OS + /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS ], [VERSION, [NAME, FIREFOX + " OS"]], [ /web0s;.+rt(tv)/i, - /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i, // WebOS + /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS ], [VERSION, [NAME, "webOS"]], [ // Google Chromecast - /crkey\/([\d\.]+)/i, // Google Chromecast + /crkey\/([\d\.]+)/i // Google Chromecast ], [VERSION, [NAME, CHROME + "cast"]], [ - /(cros) [\w]+ ([\w\.]+\w)/i, // Chromium OS + /(cros) [\w]+ ([\w\.]+\w)/i // Chromium OS ], [[NAME, "Chromium OS"], VERSION], [ @@ -1028,21 +1018,21 @@ /(hurd|linux) ?([\w\.]*)/i, // Hurd/Linux /(gnu) ?([\w\.]*)/i, // GNU /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly - /(haiku) (\w+)/i, // Haiku + /(haiku) (\w+)/i // Haiku ], [NAME, VERSION], [ - /(sunos) ?([\w\.\d]*)/i, // Solaris + /(sunos) ?([\w\.\d]*)/i // Solaris ], [[NAME, "Solaris"], VERSION], [ /((?:open)?solaris)[-\/ ]?([\w\.]*)/i, // Solaris /(aix) ((\d)(?=\.|\)| )[\w\.])*/i, // AIX /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX - /(unix) ?([\w\.]*)/i, // UNIX + /(unix) ?([\w\.]*)/i // UNIX ], - [NAME, VERSION], - ], + [NAME, VERSION] + ] }; ///////////////// @@ -1063,9 +1053,7 @@ ua || (typeof window !== UNDEF_TYPE && window.navigator && - window.navigator.userAgent - ? window.navigator.userAgent - : EMPTY); + window.navigator.userAgent ? window.navigator.userAgent : EMPTY); var _rgxmap = extensions ? extend(regexes, extensions) : regexes; this.getBrowser = function () { @@ -1111,7 +1099,7 @@ engine: this.getEngine(), os: this.getOS(), device: this.getDevice(), - cpu: this.getCPU(), + cpu: this.getCPU() }; }; this.getUA = function () { @@ -1119,9 +1107,7 @@ }; this.setUA = function (ua) { _ua = - typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH - ? trim(ua, UA_MAX_LENGTH) - : ua; + typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH ? trim(ua, UA_MAX_LENGTH) : ua; return this; }; this.setUA(_ua); @@ -1140,7 +1126,7 @@ SMARTTV, TABLET, WEARABLE, - EMBEDDED, + EMBEDDED ]); UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);