mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-23 00:11:28 -07:00
fix: harden preload argv parsing for popup windows
This commit is contained in:
16
src/preload-args.test.ts
Normal file
16
src/preload-args.test.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import test from 'node:test';
|
||||||
|
import { resolveOverlayLayerFromArgv } from './preload-args';
|
||||||
|
|
||||||
|
test('resolveOverlayLayerFromArgv returns null when argv is unavailable', () => {
|
||||||
|
assert.equal(resolveOverlayLayerFromArgv(null), null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('resolveOverlayLayerFromArgv returns parsed overlay layer when present', () => {
|
||||||
|
assert.equal(resolveOverlayLayerFromArgv(['electron', '--overlay-layer=modal']), 'modal');
|
||||||
|
assert.equal(resolveOverlayLayerFromArgv(['electron', '--overlay-layer=visible']), 'visible');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('resolveOverlayLayerFromArgv ignores unsupported overlay layers', () => {
|
||||||
|
assert.equal(resolveOverlayLayerFromArgv(['electron', '--overlay-layer=secondary']), null);
|
||||||
|
});
|
||||||
10
src/preload-args.ts
Normal file
10
src/preload-args.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export function resolveOverlayLayerFromArgv(
|
||||||
|
argv: readonly string[] | null | undefined,
|
||||||
|
): 'visible' | 'modal' | null {
|
||||||
|
const overlayLayerArg = argv?.find((arg) => arg.startsWith('--overlay-layer='));
|
||||||
|
const overlayLayerFromArg = overlayLayerArg?.slice('--overlay-layer='.length);
|
||||||
|
|
||||||
|
return overlayLayerFromArg === 'visible' || overlayLayerFromArg === 'modal'
|
||||||
|
? overlayLayerFromArg
|
||||||
|
: null;
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron';
|
import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron';
|
||||||
|
import { resolveOverlayLayerFromArgv } from './preload-args';
|
||||||
import type {
|
import type {
|
||||||
SubtitleData,
|
SubtitleData,
|
||||||
SubtitlePosition,
|
SubtitlePosition,
|
||||||
@@ -51,13 +52,13 @@ import type {
|
|||||||
ControllerConfigUpdate,
|
ControllerConfigUpdate,
|
||||||
ControllerPreferenceUpdate,
|
ControllerPreferenceUpdate,
|
||||||
ResolvedControllerConfig,
|
ResolvedControllerConfig,
|
||||||
|
YoutubePickerOpenPayload,
|
||||||
|
YoutubePickerResolveRequest,
|
||||||
|
YoutubePickerResolveResult,
|
||||||
} from './types';
|
} from './types';
|
||||||
import { IPC_CHANNELS } from './shared/ipc/contracts';
|
import { IPC_CHANNELS } from './shared/ipc/contracts';
|
||||||
|
|
||||||
const overlayLayerArg = process.argv.find((arg) => arg.startsWith('--overlay-layer='));
|
const overlayLayer = resolveOverlayLayerFromArgv(process.argv);
|
||||||
const overlayLayerFromArg = overlayLayerArg?.slice('--overlay-layer='.length);
|
|
||||||
const overlayLayer =
|
|
||||||
overlayLayerFromArg === 'visible' || overlayLayerFromArg === 'modal' ? overlayLayerFromArg : null;
|
|
||||||
|
|
||||||
type EmptyListener = () => void;
|
type EmptyListener = () => void;
|
||||||
type PayloadedListener<T> = (payload: T) => void;
|
type PayloadedListener<T> = (payload: T) => void;
|
||||||
@@ -121,6 +122,13 @@ function createQueuedIpcListenerWithPayload<T>(
|
|||||||
|
|
||||||
const onOpenRuntimeOptionsEvent = createQueuedIpcListener(IPC_CHANNELS.event.runtimeOptionsOpen);
|
const onOpenRuntimeOptionsEvent = createQueuedIpcListener(IPC_CHANNELS.event.runtimeOptionsOpen);
|
||||||
const onOpenJimakuEvent = createQueuedIpcListener(IPC_CHANNELS.event.jimakuOpen);
|
const onOpenJimakuEvent = createQueuedIpcListener(IPC_CHANNELS.event.jimakuOpen);
|
||||||
|
const onOpenYoutubeTrackPickerEvent = createQueuedIpcListenerWithPayload<YoutubePickerOpenPayload>(
|
||||||
|
IPC_CHANNELS.event.youtubePickerOpen,
|
||||||
|
(payload) => payload as YoutubePickerOpenPayload,
|
||||||
|
);
|
||||||
|
const onCancelYoutubeTrackPickerEvent = createQueuedIpcListener(
|
||||||
|
IPC_CHANNELS.event.youtubePickerCancel,
|
||||||
|
);
|
||||||
const onKeyboardModeToggleRequestedEvent = createQueuedIpcListener(
|
const onKeyboardModeToggleRequestedEvent = createQueuedIpcListener(
|
||||||
IPC_CHANNELS.event.keyboardModeToggleRequested,
|
IPC_CHANNELS.event.keyboardModeToggleRequested,
|
||||||
);
|
);
|
||||||
@@ -313,10 +321,16 @@ const electronAPI: ElectronAPI = {
|
|||||||
},
|
},
|
||||||
onOpenRuntimeOptions: onOpenRuntimeOptionsEvent,
|
onOpenRuntimeOptions: onOpenRuntimeOptionsEvent,
|
||||||
onOpenJimaku: onOpenJimakuEvent,
|
onOpenJimaku: onOpenJimakuEvent,
|
||||||
|
onOpenYoutubeTrackPicker: onOpenYoutubeTrackPickerEvent,
|
||||||
|
onCancelYoutubeTrackPicker: onCancelYoutubeTrackPickerEvent,
|
||||||
onKeyboardModeToggleRequested: onKeyboardModeToggleRequestedEvent,
|
onKeyboardModeToggleRequested: onKeyboardModeToggleRequestedEvent,
|
||||||
onLookupWindowToggleRequested: onLookupWindowToggleRequestedEvent,
|
onLookupWindowToggleRequested: onLookupWindowToggleRequestedEvent,
|
||||||
appendClipboardVideoToQueue: (): Promise<ClipboardAppendResult> =>
|
appendClipboardVideoToQueue: (): Promise<ClipboardAppendResult> =>
|
||||||
ipcRenderer.invoke(IPC_CHANNELS.request.appendClipboardVideoToQueue),
|
ipcRenderer.invoke(IPC_CHANNELS.request.appendClipboardVideoToQueue),
|
||||||
|
youtubePickerResolve: (
|
||||||
|
request: YoutubePickerResolveRequest,
|
||||||
|
): Promise<YoutubePickerResolveResult> =>
|
||||||
|
ipcRenderer.invoke(IPC_CHANNELS.request.youtubePickerResolve, request),
|
||||||
notifyOverlayModalClosed: (modal) => {
|
notifyOverlayModalClosed: (modal) => {
|
||||||
ipcRenderer.send(IPC_CHANNELS.command.overlayModalClosed, modal);
|
ipcRenderer.send(IPC_CHANNELS.command.overlayModalClosed, modal);
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user