browser_sniffer 2.5.1 → 2.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/browser_sniffer/patterns.rb +3 -3
- data/lib/browser_sniffer/version.rb +1 -1
- data/lib/browser_sniffer.rb +7 -1
- data/test/browser_sniffer_test.rb +62 -0
- data/test/test_helper.rb +1 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f1fa6f0ef701270fad08c72634ccbb5c9a01a8748eb5368ccff0d62066065c9a
|
|
4
|
+
data.tar.gz: 7915b883d825b1776b6833ea89cdde0be71ebed046fd06e73627cdc6b52c07ad
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 53940f3356cabe18354c764930c2acbfb0e09c884147d63e5556f139c41df51a0c437fa05b77bf50a10e117e6d3aec2a8f2e4450be2f762a909e2ac9f64eb8ab
|
|
7
|
+
data.tar.gz: 6cb0b817ae2c25c0163d7a70e6db1952878ce2a96d19981d158b0de53d45943d587584ff64e66076c1b5e5d68cfc47ad7e2c220babff87e4ffe5c0aba4f3efa1
|
data/Gemfile.lock
CHANGED
|
@@ -222,10 +222,10 @@ class BrowserSniffer
|
|
|
222
222
|
%r{.*Shopify POS\/[\d\.]+ \((iPod touch)\;.*Scale/([\d\.]+)}i,
|
|
223
223
|
], [[:type, :handheld], :scale], [
|
|
224
224
|
# Shopify POS for Android (SmartWebView)
|
|
225
|
-
%r{.*Shopify\sPOS
|
|
225
|
+
%r{.*Shopify\sPOS[^\(]*\((?:[^()]*)(Android)\s[\d\.]+\;\s(?:[^;()]*\;\s)*([^;()]*)\sBuild/[^)]*\)\sPOS[^\d]*[\d+\.]+}i,
|
|
226
226
|
], [[:type, :handheld], :model], [
|
|
227
227
|
# Shopify POS for Android (Native App)
|
|
228
|
-
%r{.*\(
|
|
228
|
+
%r{.*\((?:[^()]*)(Android)\s[\d\.]+\;\s(?:[^;()]*\;\s)*([^;()]*)\sBuild/[^)]*\)\sPOS[^\d]*[\d+\.]+}i,
|
|
229
229
|
], [[:type, :handheld], :model], [
|
|
230
230
|
# New tablet patterns (must come early to avoid generic matches)
|
|
231
231
|
# Xiaomi Tablets
|
|
@@ -496,7 +496,7 @@ class BrowserSniffer
|
|
|
496
496
|
# BSD based
|
|
497
497
|
/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i # FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly
|
|
498
498
|
], [:name, :version],[
|
|
499
|
-
/(ip[honead]+)(?:.*os\s*([\w]+)
|
|
499
|
+
/(ip[honead]+)(?:.*os\s*([\w]+)\slike\smac|;\sopera)/i # iOS
|
|
500
500
|
], [[:name, 'iOS'], [:version, lambda {|str| str && str.gsub(/_/, '.') }], [:type, :ios]], [
|
|
501
501
|
/(mac\sos\sx)\s?([\w\s\.]+\w)*/i # Mac OS
|
|
502
502
|
], [:name, [:version, lambda {|str| str && str.gsub(/_/, '.') }], [:type, :mac]], [
|
data/lib/browser_sniffer.rb
CHANGED
|
@@ -2,10 +2,16 @@ require "browser_sniffer/version"
|
|
|
2
2
|
require "browser_sniffer/patterns"
|
|
3
3
|
|
|
4
4
|
class BrowserSniffer
|
|
5
|
+
MAX_USER_AGENT_LENGTH = 512
|
|
6
|
+
|
|
5
7
|
attr_reader :user_agent
|
|
6
8
|
|
|
7
9
|
def initialize(user_agent)
|
|
8
|
-
@user_agent = user_agent
|
|
10
|
+
@user_agent = if user_agent.is_a?(String)
|
|
11
|
+
user_agent[0, MAX_USER_AGENT_LENGTH]
|
|
12
|
+
else
|
|
13
|
+
user_agent
|
|
14
|
+
end
|
|
9
15
|
end
|
|
10
16
|
|
|
11
17
|
def ios?
|
|
@@ -1439,8 +1439,70 @@ class BrowserSnifferTest < Minitest::Test
|
|
|
1439
1439
|
:device_vendor => 'Onyx',
|
|
1440
1440
|
:device_name => 'NoteAir3C',
|
|
1441
1441
|
},
|
|
1442
|
+
:shopify_pos_android_native => {
|
|
1443
|
+
:user_agent => "Mozilla/5.0 (Linux; Android 10; SM-G973U Build/QP1A.190711.020) POS 1.0",
|
|
1444
|
+
:form_factor => :handheld,
|
|
1445
|
+
:ios? => false,
|
|
1446
|
+
:android? => true,
|
|
1447
|
+
:desktop? => false,
|
|
1448
|
+
:os => :android,
|
|
1449
|
+
:os_version => "10",
|
|
1450
|
+
:device_name => 'SM-G973U',
|
|
1451
|
+
},
|
|
1452
|
+
:shopify_pos_android_native_with_locale => {
|
|
1453
|
+
:user_agent => "Mozilla/5.0 (Linux; U; Android 7.1.1; en-US; SM-T560NU Build/NMF26X) POS 2.4.10",
|
|
1454
|
+
:form_factor => :handheld,
|
|
1455
|
+
:ios? => false,
|
|
1456
|
+
:android? => true,
|
|
1457
|
+
:desktop? => false,
|
|
1458
|
+
:os => :android,
|
|
1459
|
+
:os_version => "7.1.1",
|
|
1460
|
+
:device_name => 'SM-T560NU',
|
|
1461
|
+
},
|
|
1462
|
+
:shopify_pos_android_smartwebview => {
|
|
1463
|
+
:user_agent => "Shopify POS/1.0 Mozilla/5.0 (Linux; Android 10; SM-G973U Build/QP1A.190711.020) POS 1.0",
|
|
1464
|
+
:form_factor => :handheld,
|
|
1465
|
+
:ios? => false,
|
|
1466
|
+
:android? => true,
|
|
1467
|
+
:desktop? => false,
|
|
1468
|
+
:os => :android,
|
|
1469
|
+
:os_version => "10",
|
|
1470
|
+
:device_name => 'SM-G973U',
|
|
1471
|
+
},
|
|
1472
|
+
:shopify_pos_android_smartwebview_with_locale => {
|
|
1473
|
+
:user_agent => "Shopify POS/2.4.10 Mozilla/5.0 (Linux; U; Android 7.1.1; en-US; SM-T560NU Build/NMF26X) POS 2.4.10",
|
|
1474
|
+
:form_factor => :handheld,
|
|
1475
|
+
:ios? => false,
|
|
1476
|
+
:android? => true,
|
|
1477
|
+
:desktop? => false,
|
|
1478
|
+
:os => :android,
|
|
1479
|
+
:os_version => "7.1.1",
|
|
1480
|
+
:device_name => 'SM-T560NU',
|
|
1481
|
+
},
|
|
1442
1482
|
}
|
|
1443
1483
|
|
|
1484
|
+
def test_nil_user_agent_is_preserved
|
|
1485
|
+
assert_nil BrowserSniffer.new(nil).user_agent
|
|
1486
|
+
end
|
|
1487
|
+
|
|
1488
|
+
def test_user_agent_length_is_capped
|
|
1489
|
+
long_user_agent = "a" * 10_000
|
|
1490
|
+
sniffer = BrowserSniffer.new(long_user_agent)
|
|
1491
|
+
assert_equal BrowserSniffer::MAX_USER_AGENT_LENGTH, sniffer.user_agent.length
|
|
1492
|
+
end
|
|
1493
|
+
|
|
1494
|
+
def test_pos_android_regex_does_not_backtrack_catastrophically
|
|
1495
|
+
malicious_user_agent = ("(Android 1.0; a Build/" * 160) + "!"
|
|
1496
|
+
time = Benchmark.realtime { BrowserSniffer.new(malicious_user_agent).form_factor }
|
|
1497
|
+
assert time < 0.1, "Expected POS Android regex to reject crafted UA quickly, took #{time}s"
|
|
1498
|
+
end
|
|
1499
|
+
|
|
1500
|
+
def test_ios_os_regex_does_not_backtrack_catastrophically
|
|
1501
|
+
malicious_user_agent = "iphone os " + ("a" * 320) + "!"
|
|
1502
|
+
time = Benchmark.realtime { BrowserSniffer.new(malicious_user_agent).os }
|
|
1503
|
+
assert time < 0.1, "Expected iOS OS regex to reject crafted UA quickly, took #{time}s"
|
|
1504
|
+
end
|
|
1505
|
+
|
|
1444
1506
|
AGENTS.each do |agent, attributes|
|
|
1445
1507
|
define_method "test_sniff_#{agent}_correctly" do
|
|
1446
1508
|
sniffer = BrowserSniffer.new(attributes[:user_agent])
|
data/test/test_helper.rb
CHANGED