























11// Gmail hook helpers manage Gmail OAuth setup and watcher launch state.
22import { randomBytes } from "node:crypto";
3-import path from "node:path";
4-import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
53import { normalizeUniqueStringEntries } from "@openclaw/normalization-core/string-normalization";
64import {
75type OpenClawConfig,
@@ -10,7 +8,11 @@ import {
108resolveGatewayPort,
119} from "../config/config.js";
1210import { resolveExecutable } from "../infra/executable-path.js";
13-import { getWindowsInstallRoots } from "../infra/windows-install-roots.js";
11+import {
12+buildWindowsCmdExeCommandLine,
13+isWindowsBatchCommand,
14+resolveTrustedWindowsCmdExe,
15+} from "../process/windows-command.js";
14161517export const DEFAULT_GMAIL_LABEL = "INBOX";
1618export const DEFAULT_GMAIL_TOPIC = "gog-gmail-watch";
@@ -22,7 +24,6 @@ export const DEFAULT_GMAIL_MAX_BYTES = 20_000;
2224export const DEFAULT_GMAIL_RENEW_MINUTES = 12 * 60;
2325const DEFAULT_HOOKS_PATH = "/hooks";
2426const GMAIL_WATCH_SENSITIVE_FLAGS = new Set(["--token", "--hook-url", "--hook-token"]);
25-const WINDOWS_UNSAFE_CMD_CHARS_RE = /[&|<>^%\r\n]/;
2627let gogBin: string | undefined;
27282829export type GmailHookOverrides = {
@@ -271,31 +272,19 @@ export function resolveGogExecutable(): string {
271272return (gogBin ??= resolveExecutable("gog"));
272273}
273274274-function escapeForCmdExe(arg: string): string {
275-if (WINDOWS_UNSAFE_CMD_CHARS_RE.test(arg)) {
276-throw new Error(`Unsafe Windows cmd.exe argument detected: ${JSON.stringify(arg)}`);
277-}
278-if (!arg.includes(" ") && !arg.includes('"')) {
279-return arg;
280-}
281-return `"${arg.replace(/"/g, '""')}"`;
282-}
283-284275export function resolveGogServeInvocation(args: string[]): {
285276args: string[];
286277command: string;
287278windowsHide?: true;
288279windowsVerbatimArguments?: true;
289280} {
290281const command = resolveGogExecutable();
291-const ext = normalizeLowercaseStringOrEmpty(path.extname(command));
292-if (process.platform !== "win32" || (ext !== ".cmd" && ext !== ".bat")) {
282+if (!isWindowsBatchCommand(command)) {
293283return { command, args, windowsHide: process.platform === "win32" ? true : undefined };
294284}
295-const cmdExe = path.win32.join(getWindowsInstallRoots().systemRoot, "System32", "cmd.exe");
296285return {
297-command: cmdExe,
298-args: ["/d", "/s", "/c", [command, ...args].map(escapeForCmdExe).join(" ")],
286+command: resolveTrustedWindowsCmdExe(),
287+args: ["/d", "/s", "/c", buildWindowsCmdExeCommandLine(command, args)],
299288windowsHide: true,
300289windowsVerbatimArguments: true,
301290};
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。