From feaa51adaecffdd360a44866aff01e4268b0cd96 Mon Sep 17 00:00:00 2001 From: Josh Fyne Date: Fri, 1 Sep 2023 11:12:27 +0100 Subject: [PATCH] Handling non-standard and rare user agents. --- ua.go | 26 ++++++++++++++++++++++++-- ua_test.go | 6 ++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/ua.go b/ua.go index 4dcfcf9..c866ef7 100644 --- a/ua.go +++ b/ua.go @@ -32,6 +32,7 @@ const ( IOS = "iOS" Linux = "Linux" ChromeOS = "ChromeOS" + BlackBerry = "BlackBerry" Opera = "Opera" OperaMini = "Opera Mini" @@ -118,6 +119,10 @@ func Parse(userAgent string) UserAgent { ua.OS = ChromeOS ua.OSVersion = tokens.get("CrOS") ua.Desktop = true + case tokens.exists("BlackBerry"): + ua.OS = BlackBerry + ua.OSVersion = tokens.get("BlackBerry") + ua.Mobile = true } switch { @@ -260,6 +265,10 @@ func Parse(userAgent string) UserAgent { ua.Version = tokens.get("HuaweiBrowser") ua.Mobile = tokens.existsAny("Mobile", "Mobile Safari") + case tokens.exists("BlackBerry"): + ua.Name = "BlackBerry" + ua.Version = tokens.get("Version") + // if chrome and Safari defined, find any other token sent descr case tokens.exists(Chrome) && tokens.exists(Safari): name := tokens.findBestMatch(true) @@ -303,7 +312,10 @@ func Parse(userAgent string) UserAgent { ua.Name = ua.String } ua.Bot = strings.Contains(strings.ToLower(ua.Name), "bot") - ua.Mobile = tokens.existsAny("Mobile", "Mobile Safari") + // If mobile flag has already been set, don't override it. + if !ua.Mobile { + ua.Mobile = tokens.existsAny("Mobile", "Mobile Safari") + } } } @@ -390,6 +402,16 @@ func parse(userAgent string) properties { addToken() braOpen = false + case c == 58: // : + if bytes.HasSuffix(buff.Bytes(), []byte("http")) || bytes.HasSuffix(buff.Bytes(), []byte("https")) { + // If we are part of a URL just write the character. + buff.WriteByte(c) + } else if i != len(bua)-1 && bua[i+1] != ' ' { + // If the following character is not a space, change to a space. + buff.WriteByte(' ') + } + // Otherwise don't write as its probably a badly formatted key value separator. + case slash && c == 32: addToken() @@ -424,7 +446,7 @@ func checkVer(s string) (name, v string) { switch s[:i] { case "Linux", "Windows NT", "Windows Phone OS", "MSIE", "Android": return s[:i], s[i+1:] - case "CrOS x86_64", "CrOS aarch64": + case "CrOS x86_64", "CrOS aarch64", "CrOS armv7l": j := strings.LastIndex(s[:i], " ") return s[:j], s[j+1 : i] default: diff --git a/ua_test.go b/ua_test.go index e92cea8..9e9a35b 100644 --- a/ua_test.go +++ b/ua_test.go @@ -121,6 +121,12 @@ var testTable = [][]string{ // unstandard stuff {"BUbiNG (+http://law.di.unimi.it/BUbiNG.html)", "BUbiNG", "", "", ""}, //{"Aweme 8.2.0 rv:82017 (iPhone6,2; iOS 12.4; zh_CN) Cronet", "Aweme", "", "", ""}, + {"surveyon/3.1.0 Mobile (Android: 6.0.1; MODEL:SM-G532G; PRODUCT:grandppltedx; MANUFACTURER:samsung;)", "surveyon", "3.1.0", "mobile", ua.Android}, + {"surveyon/3.1.0 Mobile (Android: 9; MODEL:CPH1923; PRODUCT:CPH1923; MANUFACTURER:OPPO;)", "surveyon", "3.1.0", "mobile", ua.Android}, + {"surveyon/3.1.0 Mobile (Android: 13; MODEL:SM-M127F; PRODUCT:m12nnxx; MANUFACTURER:samsung;)", "surveyon", "3.1.0", "mobile", ua.Android}, + {"surveyon/2.9.5 (iPhone; CPU iPhone OS 12_5_7 like Mac OS X)", "surveyon", "2.9.5", "mobile", ua.IOS}, + {"Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0.187 Mobile Safari/534.11+", "BlackBerry", "7.0.0.187", "mobile", "BlackBerry"}, + {"Mozilla/5.0 (X11; CrOS armv7l 13099.110.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.136 Safari/537.36", ua.Chrome, "84.0.4147.136", "desktop", ua.ChromeOS}, // Device names {"Mozilla/5.0 (Linux; Android 10; 8092) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", "Chrome", "112.0.0.0", "mobile", ua.Android, "8092"},