Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 10 additions & 32 deletions userscript/source/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
/return *[A-Za-z.-9]+ *\( *[0-9a-fx *+-]+ *, *[A-Za-z.-9]+ *, *[A-Za-z.-9]+ *, *[0-9a-fx *+-]+ *,[A-Za-z.-9]+ *, *[A-Za-z.-9]+ * *\) *; *}/
]]

function PowerLinkElementFromArg(Arg: unknown): HTMLElement | null {

Check warning on line 34 in userscript/source/index.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

'PowerLinkElementFromArg' is defined but never used

Check warning on line 34 in userscript/source/index.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

'PowerLinkElementFromArg' is defined but never used
if (typeof Arg !== 'object' || Arg === null) return null
if (typeof OriginalReflectApply(OriginalObjectGetOwnPropertyDescriptor, BrowserWindow.Object, [Arg, '_'])?.get === 'function') return null

Expand Down Expand Up @@ -285,50 +285,31 @@
return Stringified.includes('https://ader.naver.com/')
}

function ProxySetHandlerTargetCheck(Target: object): boolean {
for (const PropertyName of Object.keys(Target)) {
const Value = (Target as Record<string, unknown>)[PropertyName]
const Descriptor = OriginalObjectGetOwnPropertyDescriptor(Target, PropertyName)

if (
typeof Value === 'object' &&
Value !== null &&
typeof Descriptor?.get !== 'function'
) {
if (ProxySetHandlerTargetCheck(Value)) {
return true
}
} else if (
typeof Value === 'string' &&
Value.includes('ader.naver.com')
) {
return true
}
function ProxySetHandlerTargetCheck(
Target: object,
Visited = new WeakSet<object>()
): boolean {
if (Visited.has(Target)) {
return false
}
Visited.add(Target)

return false
}

function ProxySetHandlerTargetCheckAndReplace(Target: object, NewValue: string): boolean {
const Record = Target as Record<string, unknown>

for (const PropertyName of Object.keys(Record)) {
const Value = Record[PropertyName]
for (const PropertyName of Object.keys(Target)) {
const Value = (Target as Record<string, unknown>)[PropertyName]
const Descriptor = OriginalObjectGetOwnPropertyDescriptor(Target, PropertyName)

if (
Comment on lines +297 to 301
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ProxySetHandlerTargetCheck reads Target[PropertyName] before checking whether the property is an accessor (descriptor.get). If the property has a getter, this access will invoke it (side effects / possible exceptions) even though the later logic tries to skip getters. Consider fetching the descriptor first and, when it has a getter, skipping the property without reading it; for data descriptors, prefer descriptor.value to avoid accidental getter execution.

Copilot uses AI. Check for mistakes.
typeof Value === 'object' &&
Value !== null &&
typeof Descriptor?.get !== 'function'
) {
if (ProxySetHandlerTargetCheckAndReplace(Value, NewValue)) {
if (ProxySetHandlerTargetCheck(Value, Visited)) {
return true
}
} else if (
typeof Value === 'string' &&
Value.includes('ader.naver.com')
) {
Record[PropertyName] = NewValue
return true
}
}
Expand Down Expand Up @@ -438,9 +419,6 @@
BrowserWindow.document.dispatchEvent(new CustomEvent('PL2PlaceHolderProxy'))
return
}
else if (ProxySetHandlerTargetCheckAndReplace(SetArgs[0], '')) {
console.debug(`[${UserscriptName}]: Proxy set called for PowerLink Skeleton (target check and replace):`, SetArgs)
}
return OriginalReflectApply(OriginalSet, this, SetArgs)
}
}
Expand Down
Loading