fix(config): tolerate invalid OPENCODE_PERMISSION JSON (#28388)
This commit is contained in:
@@ -21,7 +21,6 @@ export const Flag = {
|
|||||||
OPENCODE_DISABLE_PRUNE: truthy("OPENCODE_DISABLE_PRUNE"),
|
OPENCODE_DISABLE_PRUNE: truthy("OPENCODE_DISABLE_PRUNE"),
|
||||||
OPENCODE_DISABLE_TERMINAL_TITLE: truthy("OPENCODE_DISABLE_TERMINAL_TITLE"),
|
OPENCODE_DISABLE_TERMINAL_TITLE: truthy("OPENCODE_DISABLE_TERMINAL_TITLE"),
|
||||||
OPENCODE_SHOW_TTFD: truthy("OPENCODE_SHOW_TTFD"),
|
OPENCODE_SHOW_TTFD: truthy("OPENCODE_SHOW_TTFD"),
|
||||||
OPENCODE_PERMISSION: process.env["OPENCODE_PERMISSION"],
|
|
||||||
OPENCODE_DISABLE_AUTOCOMPACT: truthy("OPENCODE_DISABLE_AUTOCOMPACT"),
|
OPENCODE_DISABLE_AUTOCOMPACT: truthy("OPENCODE_DISABLE_AUTOCOMPACT"),
|
||||||
OPENCODE_DISABLE_MODELS_FETCH: truthy("OPENCODE_DISABLE_MODELS_FETCH"),
|
OPENCODE_DISABLE_MODELS_FETCH: truthy("OPENCODE_DISABLE_MODELS_FETCH"),
|
||||||
OPENCODE_DISABLE_MOUSE: truthy("OPENCODE_DISABLE_MOUSE"),
|
OPENCODE_DISABLE_MOUSE: truthy("OPENCODE_DISABLE_MOUSE"),
|
||||||
@@ -59,6 +58,9 @@ export const Flag = {
|
|||||||
get OPENCODE_PURE() {
|
get OPENCODE_PURE() {
|
||||||
return truthy("OPENCODE_PURE")
|
return truthy("OPENCODE_PURE")
|
||||||
},
|
},
|
||||||
|
get OPENCODE_PERMISSION() {
|
||||||
|
return process.env["OPENCODE_PERMISSION"]
|
||||||
|
},
|
||||||
get OPENCODE_PLUGIN_META_FILE() {
|
get OPENCODE_PLUGIN_META_FILE() {
|
||||||
return process.env["OPENCODE_PLUGIN_META_FILE"]
|
return process.env["OPENCODE_PLUGIN_META_FILE"]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -703,7 +703,11 @@ export const layer = Layer.effect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Flag.OPENCODE_PERMISSION) {
|
if (Flag.OPENCODE_PERMISSION) {
|
||||||
result.permission = mergeDeep(result.permission ?? {}, JSON.parse(Flag.OPENCODE_PERMISSION))
|
try {
|
||||||
|
result.permission = mergeDeep(result.permission ?? {}, JSON.parse(Flag.OPENCODE_PERMISSION))
|
||||||
|
} catch (err) {
|
||||||
|
log.warn("OPENCODE_PERMISSION contains invalid JSON, skipping", { err })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.tools) {
|
if (result.tools) {
|
||||||
|
|||||||
@@ -2079,6 +2079,34 @@ describe("OPENCODE_DISABLE_PROJECT_CONFIG", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Regression for #28206: malformed OPENCODE_PERMISSION JSON used to crash
|
||||||
|
// the app on startup with an unhandled SyntaxError. Loading the config with
|
||||||
|
// an invalid JSON value in this env var should not throw.
|
||||||
|
describe("OPENCODE_PERMISSION env var", () => {
|
||||||
|
test("does not crash when OPENCODE_PERMISSION contains invalid JSON", async () => {
|
||||||
|
const original = process.env["OPENCODE_PERMISSION"]
|
||||||
|
process.env["OPENCODE_PERMISSION"] = "{invalid"
|
||||||
|
try {
|
||||||
|
await using tmp = await tmpdir()
|
||||||
|
await withTestInstance({
|
||||||
|
directory: tmp.path,
|
||||||
|
fn: async (ctx) => {
|
||||||
|
const config = await load(ctx)
|
||||||
|
// We don't assert on permission shape; the regression is that
|
||||||
|
// load() throws before returning anything.
|
||||||
|
expect(config).toBeDefined()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
if (original !== undefined) {
|
||||||
|
process.env["OPENCODE_PERMISSION"] = original
|
||||||
|
} else {
|
||||||
|
delete process.env["OPENCODE_PERMISSION"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("OPENCODE_CONFIG_CONTENT token substitution", () => {
|
describe("OPENCODE_CONFIG_CONTENT token substitution", () => {
|
||||||
test("substitutes {env:} tokens in OPENCODE_CONFIG_CONTENT", async () => {
|
test("substitutes {env:} tokens in OPENCODE_CONFIG_CONTENT", async () => {
|
||||||
const originalEnv = process.env["OPENCODE_CONFIG_CONTENT"]
|
const originalEnv = process.env["OPENCODE_CONFIG_CONTENT"]
|
||||||
|
|||||||
Reference in New Issue
Block a user