-
Notifications
You must be signed in to change notification settings - Fork 0
/
version.go
138 lines (118 loc) · 3.79 KB
/
version.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package useragent
// ReplaceIndexes replaces the runes at the given indexes with empty strings.
func ReplaceIndexes(ua string, indexes []int) string {
// Remove the version numbers from the user agent string.
for _, i := range indexes {
ua = ua[:i] + ua[i+1:]
// Update the indexes of the remaining runes.
for j := range indexes {
if indexes[j] > i {
indexes[j]--
}
}
}
return ua
}
// RemoveVersions removes the version numbers from the user agent string.
func RemoveVersions(ua string) string {
// Number of runes to skip when iterating over the trie. This is used
// to skip over version numbers or language codes.
var skipCount uint8
// Indexes of the runes to replace with an empty string.
indexesToReplace := []int{}
for i, r := range ua {
if skipCount > 0 {
skipCount--
continue
}
// We want to strip any other version numbers from other products to get more hits
// to the trie.
if IsDigit(r) || (r == '.' && len(ua) > i+1 && IsDigit(rune(ua[i+1]))) {
indexesToReplace = append(indexesToReplace, i)
continue
}
// Identify and skip language codes e.g. en-US, zh-cn, en_US, ZH_cn
if len(ua) > i+6 && r == ' ' && IsLetter(rune(ua[i+1])) && IsLetter(rune(ua[i+2])) && (ua[i+3] == '-' || ua[i+3] == '_') && IsLetter(rune(ua[i+4])) && IsLetter(rune(ua[i+5])) && (ua[i+6] == ' ' || ua[i+6] == ')' || ua[i+6] == ';') {
// Add the number of runes to skip to the skip count.
skipCount += 6
indexesToReplace = append(indexesToReplace, i, i+1, i+2, i+3, i+4, i+5, i+6)
continue
}
// Skip whitespace
switch r {
case ' ', ';', ')', '(', ',', '_', '-', '/':
indexesToReplace = append(indexesToReplace, i)
continue
}
// Replace all non-latin characters with a space. The trie function will automatically
// skip over any characters it can't find, so this is a safe operation.
if !IsLetter(r) {
indexesToReplace = append(indexesToReplace, i)
continue
}
}
ua = ReplaceIndexes(ua, indexesToReplace)
return ua
}
// RemoveMobileIdentifiers removes the device identifiers from the user agent string.
// This specifically removes any strings that follow the Mobile tokens.
// For example, "Mobile/14F89" should be "Mobile".
func RemoveMobileIdentifiers(ua string) string {
tokens := MatchTokenIndexes(ua)
// Find mobile token.
for _, token := range tokens {
var skipUntilWhitespace bool
var indexesToReplace []int
if token.Match == Mobile {
// Iterate over the user agent string and remove all characters
// after the mobile token until we encounter whitespace.
for i, r := range ua {
if skipUntilWhitespace {
if r == ' ' {
skipUntilWhitespace = false
} else {
indexesToReplace = append(indexesToReplace, i)
continue
}
}
if i == token.EndIndex-1 {
skipUntilWhitespace = true
}
}
ua = ReplaceIndexes(ua, indexesToReplace)
return ua
}
}
return ua
}
// RemoveAndroidIdentifiers removes the device identifiers from the user agent string.
// This specifically removes any strings that follow the Android tokens.
func RemoveAndroidIdentifiers(ua string) string {
tokens := MatchTokenIndexes(ua)
// Find mobile token.
for _, token := range tokens {
var skipUntilClosingParenthesis bool
var indexesToReplace []int
if token.Match == Android {
// Iterate over the user agent string and remove all characters
// after the Android token until we encounter a closing parenthesis
// to remove device identifiers.
for i, r := range ua {
if skipUntilClosingParenthesis {
if r == ')' {
skipUntilClosingParenthesis = false
} else {
indexesToReplace = append(indexesToReplace, i)
continue
}
}
if i == token.EndIndex-1 {
skipUntilClosingParenthesis = true
}
}
ua = ReplaceIndexes(ua, indexesToReplace)
return ua
}
}
return ua
}