fix: guard Slack cmdarg decode
This commit is contained in:
@@ -197,4 +197,27 @@ describe("Slack native command argument menus", () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("treats malformed percent-encoding as an invalid button (no throw)", async () => {
|
||||||
|
const { actions, postEphemeral, ctx, account } = createHarness();
|
||||||
|
registerSlackMonitorSlashCommands({ ctx: ctx as never, account: account as never });
|
||||||
|
|
||||||
|
const handler = actions.get("clawdbot_cmdarg");
|
||||||
|
if (!handler) throw new Error("Missing arg-menu action handler");
|
||||||
|
|
||||||
|
await handler({
|
||||||
|
ack: vi.fn().mockResolvedValue(undefined),
|
||||||
|
action: { value: "cmdarg|%E0%A4%A|mode|on|U1" },
|
||||||
|
body: { user: { id: "U1" }, channel: { id: "C1" } },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(postEphemeral).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
token: "bot-token",
|
||||||
|
channel: "C1",
|
||||||
|
user: "U1",
|
||||||
|
text: "Sorry, that button is no longer valid.",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -72,11 +72,23 @@ function parseSlackCommandArgValue(raw?: string | null): {
|
|||||||
if (parts.length !== 5 || parts[0] !== SLACK_COMMAND_ARG_VALUE_PREFIX) return null;
|
if (parts.length !== 5 || parts[0] !== SLACK_COMMAND_ARG_VALUE_PREFIX) return null;
|
||||||
const [, command, arg, value, userId] = parts;
|
const [, command, arg, value, userId] = parts;
|
||||||
if (!command || !arg || !value || !userId) return null;
|
if (!command || !arg || !value || !userId) return null;
|
||||||
|
const decode = (text: string) => {
|
||||||
|
try {
|
||||||
|
return decodeURIComponent(text);
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const decodedCommand = decode(command);
|
||||||
|
const decodedArg = decode(arg);
|
||||||
|
const decodedValue = decode(value);
|
||||||
|
const decodedUserId = decode(userId);
|
||||||
|
if (!decodedCommand || !decodedArg || !decodedValue || !decodedUserId) return null;
|
||||||
return {
|
return {
|
||||||
command: decodeURIComponent(command),
|
command: decodedCommand,
|
||||||
arg: decodeURIComponent(arg),
|
arg: decodedArg,
|
||||||
value: decodeURIComponent(value),
|
value: decodedValue,
|
||||||
userId: decodeURIComponent(userId),
|
userId: decodedUserId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user