Skip to content
Merged
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ refused in every mode, including `allow_all`, and the browser's WebRTC traffic n
filter instead of around it. A computer run without an API server can set
`EGRESS_POLICY_REQUIRED=0` to keep the old behaviour.

### Provider and Bot lookups ignore inherited object properties

Unknown names such as `constructor` and `__proto__` no longer return an inherited
JavaScript object as a provider or Bot entry. Unknown providers return no spec, and
missing Bots raise the existing startup error. Configured providers and Bots are unchanged.

### A malformed `%` in a stream URL no longer returns a 500

A request to `/api/computers/<id>/stream` whose id held a broken percent-escape, such as `%zz`, made the server throw and answer 500. It is now treated as not matching the stream route and goes through normal routing. Valid ids behave as before.
Expand Down
15 changes: 15 additions & 0 deletions shared/model-providers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,18 @@ describe("what a Bot runs from the spec file", () => {
);
});
});

describe("registry lookups ignore inherited object properties", () => {
test("prototype names are not providers", () => {
for (const name of ["constructor", "__proto__", "toString", "valueOf"]) {
expect(providerSpec(name)).toBeUndefined();
expect(keyVariableFor(name)).toBeUndefined();
expect(baseUrlVariableFor(name)).toBeUndefined();
}
});
test("prototype names are not Bot entries", () => {
for (const name of ["constructor", "__proto__", "toString", "valueOf"]) {
expect(() => botSettings(name, {})).toThrow(`bots has no ${name} entry`);
}
});
});
8 changes: 6 additions & 2 deletions shared/model-providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,9 @@ export function providerSpec(
provider: string | undefined,
): ProviderSpec | undefined {
const normalized = provider?.trim().toLowerCase() || "openai";
return MODEL_PROVIDERS[normalized as ModelProviderId];
return Object.hasOwn(MODEL_PROVIDERS, normalized)
? MODEL_PROVIDERS[normalized as ModelProviderId]
: undefined;
}

/** The environment variable this provider's key arrives in, or nothing for a provider unknown. */
Expand Down Expand Up @@ -248,7 +250,9 @@ export function botSettings(
env: Readonly<Record<string, string | undefined>> = process.env,
pinnedProvider?: string,
): BotSettings {
const entry = BOT_ENTRIES[botId];
const entry = Object.hasOwn(BOT_ENTRIES, botId)
? BOT_ENTRIES[botId]
: undefined;
if (!entry) {
fail(
`bots has no ${botId} entry. Add one before this Bot reads the spec file.`,
Expand Down