Skip to content

Commit b0e2b4b

Browse files
committed
fix: handle objects created by Object.create(null) that can throw an error
`TypeError: Cannot convert object to primitive value` in Chromium `TypeError: can't convert Object to string` in Firefox
1 parent 1a9a066 commit b0e2b4b

2 files changed

Lines changed: 12 additions & 3 deletions

File tree

userscript/source/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export function RunTinyShieldUserscript(BrowserWindow: typeof window, Userscript
2424
const OriginalArrayMap = BrowserWindow.Array.prototype.map
2525
const OriginalString = BrowserWindow.String
2626
const OriginalArrayJoin = BrowserWindow.Array.prototype.join
27+
const OriginalObjectGetPrototypeOf = BrowserWindow.Object.getPrototypeOf
2728

2829
const ProtectedFunctionStrings = ['toString', 'get', 'set']
2930

@@ -49,7 +50,7 @@ export function RunTinyShieldUserscript(BrowserWindow: typeof window, Userscript
4950
return Reflect.apply(Target, ThisArg, Args)
5051
}
5152

52-
let ArgText = SafeArrayToString(Args, { OriginalArrayMap, OriginalString, OriginalArrayJoin })
53+
let ArgText = SafeArrayToString(Args, { OriginalArrayMap, OriginalString, OriginalArrayJoin, OriginalObjectGetPrototypeOf })
5354
if (ASInitPositiveRegExps.filter(ASInitPositiveRegExp => ASInitPositiveRegExp.filter(Index => OriginalRegExpTest.call(Index, ArgText) as boolean).length >= 2).length === 1) {
5455
console.debug(`[${UserscriptName}]: Map.prototype.get:`, ThisArg, Args)
5556
throw new Error()
@@ -71,7 +72,7 @@ export function RunTinyShieldUserscript(BrowserWindow: typeof window, Userscript
7172
BrowserWindow.Map.prototype.set = new Proxy(BrowserWindow.Map.prototype.set, {
7273
apply(Target: (key: unknown, value: unknown) => Map<unknown, unknown>, ThisArg: Map<unknown, unknown>, Args: [unknown, unknown]) {
7374
let ArgText = ''
74-
ArgText = SafeArrayToString(Args, { OriginalArrayMap, OriginalString, OriginalArrayJoin })
75+
ArgText = SafeArrayToString(Args, { OriginalArrayMap, OriginalString, OriginalArrayJoin, OriginalObjectGetPrototypeOf })
7576
if (ASReinsertedAdvInvenPositiveRegExps.filter(ASReinsertedAdvInvenPositiveRegExp => ASReinsertedAdvInvenPositiveRegExp.filter(Index => OriginalRegExpTest.call(Index, ArgText) as boolean).length >= 3).length === 1) {
7677
console.debug(`[${UserscriptName}]: Map.prototype.set:`, ThisArg, Args)
7778
throw new Error()

userscript/source/safe-ArrayToString.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,20 @@ type OriginalAPI = {
22
OriginalArrayMap: typeof Array.prototype.map
33
OriginalString: typeof String
44
OriginalArrayJoin: typeof Array.prototype.join
5+
OriginalObjectGetPrototypeOf: typeof Object.getPrototypeOf
56
}
67

78
export function SafeArrayToString(This: unknown[], OriginalAPI: OriginalAPI): string {
9+
810
const Mapped = OriginalAPI.OriginalArrayMap.call(
911
This,
10-
(Value: unknown) => OriginalAPI.OriginalString(Value)
12+
(Value: unknown) => {
13+
if (Value && typeof Value === 'object' && OriginalAPI.OriginalObjectGetPrototypeOf(Value) === null) {
14+
return '[Object: null prototype]'
15+
}
16+
17+
return OriginalAPI.OriginalString(Value)
18+
}
1119
) as string[]
1220

1321
return OriginalAPI.OriginalArrayJoin.call(Mapped) as string

0 commit comments

Comments
 (0)