Files
WeHub Mirror 6bf8bebf51
CI / Test and Build (push) Failing after 1s
CI / Migrate Dev DB (push) Has been skipped
CI / Migrate DB (push) Has been skipped
CodeQL / Analyze actions (push) Has been cancelled
CodeQL / Analyze javascript-typescript (push) Has been cancelled
CI / Detect Version (push) Has been cancelled
CI / Detect Desktop Changes (push) Has been cancelled
CI / Build AMD64 (blacksmith-2vcpu-ubuntu-2404, ./docker/cron.Dockerfile, ubuntu-latest, ghcr.io/simstudioai/cron) (push) Has been cancelled
CI / Build AMD64 (blacksmith-2vcpu-ubuntu-2404, ./docker/db.Dockerfile, ECR_MIGRATIONS, ubuntu-latest, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (blacksmith-4vcpu-ubuntu-2404, ./docker/pii.Dockerfile, ECR_PII, ubuntu-latest, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (blacksmith-4vcpu-ubuntu-2404, ./docker/realtime.Dockerfile, ECR_REALTIME, ubuntu-latest, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build AMD64 (blacksmith-8vcpu-ubuntu-2404, ./docker/app.Dockerfile, ECR_APP, linux-x64-8-core, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-4vcpu-ubuntu-2404-arm, ./docker/cron.Dockerfile, ubuntu-24.04-arm, ghcr.io/simstudioai/cron) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-4vcpu-ubuntu-2404-arm, ./docker/db.Dockerfile, ubuntu-24.04-arm, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-4vcpu-ubuntu-2404-arm, ./docker/pii.Dockerfile, ubuntu-24.04-arm, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-4vcpu-ubuntu-2404-arm, ./docker/realtime.Dockerfile, ubuntu-24.04-arm, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-8vcpu-ubuntu-2404-arm, ./docker/app.Dockerfile, linux-arm64-8-core, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
Helm Chart / Lint, test, and validate chart (push) Has been cancelled
Helm Chart / Chart version bumped (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
CI / Build Dev ECR (blacksmith-8vcpu-ubuntu-2404, ./docker/app.Dockerfile, ECR_APP, linux-x64-8-core) (push) Has been cancelled
CI / Promote Images (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/cron) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build Dev ECR (blacksmith-2vcpu-ubuntu-2404, ./docker/db.Dockerfile, ECR_MIGRATIONS, ubuntu-latest) (push) Has been cancelled
CI / Build Dev ECR (blacksmith-4vcpu-ubuntu-2404, ./docker/pii.Dockerfile, ECR_PII, ubuntu-latest) (push) Has been cancelled
CI / Build Dev ECR (blacksmith-4vcpu-ubuntu-2404, ./docker/realtime.Dockerfile, ECR_REALTIME, ubuntu-latest) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Check Desktop Signing Secrets (push) Has been cancelled
CI / Desktop Release (push) Has been cancelled
CI / Create Desktop Prerelease (push) Has been cancelled
CI / Desktop Prerelease Build (push) Has been cancelled
CI / Publish Desktop Prerelease (push) Has been cancelled
CI / Prune Desktop Prereleases (push) Has been cancelled
Helm Chart / Install on kind and run helm test (push) Has been cancelled
WeHub snapshot of cb28d14c6f2c081de7a0d8729a8c816c9adef67a
2026-08-10 11:17:50 +08:00

1081 lines
39 KiB
TypeScript

/**
* @vitest-environment node
*/
import { spawnSync } from 'node:child_process'
import { hasPython3, PYTHON_SKIP_REASON } from '@sim/testing/environment'
import { afterEach, describe, expect, it } from 'vitest'
import {
analyzeCodePlaceholders,
type CodePlaceholderRuntimeBinding,
compileCodePlaceholders,
} from '@/lib/execution/code-placeholders'
import { CodeLanguage } from '@/lib/execution/languages'
const installedGlobals = new Set<string>()
async function executeJavaScript(
code: string,
bindings: ReadonlyArray<{ name: string; value: string }>,
runtimeBindings: readonly CodePlaceholderRuntimeBinding[] = []
): Promise<unknown> {
for (const binding of bindings) {
Object.defineProperty(globalThis, binding.name, {
configurable: true,
value: binding.value,
writable: true,
})
installedGlobals.add(binding.name)
}
for (const binding of runtimeBindings) {
const templateObjects: unknown[] = []
const value = Object.freeze({
RegExp,
freeze: Object.freeze.bind(Object),
defineProperty: Object.defineProperty.bind(Object),
template: (index: number, create: () => unknown) =>
templateObjects[index] ?? (templateObjects[index] = create()),
})
Object.defineProperty(globalThis, binding.name, {
configurable: true,
value,
writable: false,
})
installedGlobals.add(binding.name)
}
return new Function(`return (async () => {\n${code}\n})()`)()
}
function executeShell(
code: string,
bindings: ReadonlyArray<{ name: string; value: string }>
): string {
const result = spawnSync('/bin/bash', ['-c', code], {
encoding: 'utf8',
env: {
...process.env,
...Object.fromEntries(bindings.map(({ name, value }) => [name, value])),
},
})
if (result.error) throw result.error
if (result.status !== 0) throw new Error(result.stderr)
return result.stdout
}
function executePython(
code: string,
bindings: ReadonlyArray<{ name: string; value: string }>
): string {
const prologue = [
'import os as _sim_test_os',
...bindings.map(({ name }) => `${name} = _sim_test_os.environ[${JSON.stringify(name)}]`),
].join('\n')
const result = spawnSync('python3', ['-c', `${prologue}\n${code}`], {
encoding: 'utf8',
env: {
...process.env,
...Object.fromEntries(bindings.map(({ name, value }) => [name, value])),
},
})
if (result.error) throw result.error
if (result.status !== 0) throw new Error(result.stderr)
return result.stdout
}
afterEach(() => {
for (const name of installedGlobals) Reflect.deleteProperty(globalThis, name)
installedGlobals.clear()
})
describe('code placeholder compiler', () => {
it('preserves bare, quoted, embedded, template, string types, and one-pass JavaScript values', async () => {
const value = 'a"\\\n{{OTHER}}'
const compiled = await compileCodePlaceholders({
code: [
'const bare = {{KEY}}',
'const quoted = "{{KEY}}"',
'const embedded = "Bearer {{KEY}}"',
'const template = `Token {{KEY}}`',
'return { bare, quoted, embedded, template, numeric: {{NUM}}, boolean: {{BOOL}} }',
].join('\n'),
language: CodeLanguage.JavaScript,
environmentVariables: { KEY: value, NUM: '123', BOOL: 'true', OTHER: 'must-not-resolve' },
})
expect(compiled.code).not.toContain(value)
expect(compiled.code).not.toContain('__var_')
expect(compiled.resolvedSecretNames).toEqual(['KEY', 'NUM', 'BOOL'])
await expect(
executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings)
).resolves.toEqual({
bare: value,
quoted: value,
embedded: `Bearer ${value}`,
template: `Token ${value}`,
numeric: '123',
boolean: 'true',
})
})
it('compiles JavaScript regex literals without escaping the bound pattern', async () => {
const compiled = await compileCodePlaceholders({
code: [
'const RegExp = null',
'const matcher = /^{{PATTERN}}$/im',
'return [matcher.flags, matcher.test("aZZb")]',
].join('\n'),
language: CodeLanguage.JavaScript,
environmentVariables: { PATTERN: 'a.+b' },
})
expect(compiled.runtimeBindings).toEqual([
expect.objectContaining({ kind: 'javascript-runtime' }),
])
expect(compiled.code).not.toContain('a.+b')
await expect(
executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings)
).resolves.toEqual(['im', true])
})
it('captures the JavaScript regex intrinsic before user code mutates its prototype', async () => {
const compiled = await compileCodePlaceholders({
code: [
'const originalConstructor = RegExp.prototype.constructor',
'RegExp.prototype.constructor = null',
'try {',
' return /^{{PATTERN}}$/.test("secret")',
'} finally {',
' RegExp.prototype.constructor = originalConstructor',
'}',
].join('\n'),
language: CodeLanguage.JavaScript,
environmentVariables: { PATTERN: 'secret' },
})
await expect(
executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings)
).resolves.toBe(true)
})
it('rejects resolved placeholders in a static import without exposing the value', async () => {
const secret = 'must-not-appear-in-the-diagnostic'
const error = await compileCodePlaceholders({
code: 'import value from "{{MODULE}}"',
language: CodeLanguage.JavaScript,
environmentVariables: { MODULE: secret },
}).catch((caught) => caught)
expect(error).toBeInstanceOf(Error)
expect(String(error)).toContain('is not supported')
expect(String(error)).not.toContain(secret)
})
it('preserves tagged-template cooked, raw, substitution, and receiver semantics', async () => {
const secret = 'quote"\\\n{{OTHER}}'
const compiled = await compileCodePlaceholders({
code: [
'let calls = 0',
'const receiver = {',
' tag(strings, value) {',
' return {',
' cooked: [...strings],',
' raw: [...strings.raw],',
' value,',
' calls,',
' receiver: this === receiver,',
' frozen: ({}).constructor.isFrozen(strings) && ({}).constructor.isFrozen(strings.raw),',
' }',
' },',
'}',
'const Object = null',
'return receiver.tag`line\\n{{KEY}}:$' + '{++calls}:\\x41{{KEY}}`',
].join('\n'),
language: CodeLanguage.JavaScript,
environmentVariables: { KEY: secret, OTHER: 'must-not-resolve' },
})
expect(compiled.code).not.toContain(secret)
await expect(
executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings)
).resolves.toEqual({
cooked: [`line\n${secret}:`, `:A${secret}`],
raw: [`line\\n${secret}:`, `:\\x41${secret}`],
value: 1,
calls: 1,
receiver: true,
frozen: true,
})
})
it('round-trips source-sensitive string and tagged-template characters', async () => {
const sourceText = `</script>${String.fromCharCode(0x2028, 0x2029)}`
const secret = `secret"\\\n${sourceText}`
const literalText = `before ${sourceText} {{KEY}} after`
const compiled = await compileCodePlaceholders({
code: [
`const quoted = ${JSON.stringify(literalText)}`,
'const tag = (strings) => ({ cooked: strings[0], raw: strings.raw[0] })',
`const tagged = tag\`${literalText}\``,
'return { quoted, tagged }',
].join('\n'),
language: CodeLanguage.JavaScript,
environmentVariables: { KEY: secret },
})
const expected = `before ${sourceText} ${secret} after`
expect(compiled.code).toContain('\\u003c/script\\u003e')
expect(compiled.code).toContain('\\u2028\\u2029')
expect(compiled.code).not.toContain('</script>')
expect(compiled.code).not.toContain(String.fromCharCode(0x2028))
expect(compiled.code).not.toContain(String.fromCharCode(0x2029))
expect(compiled.code).not.toContain(secret)
await expect(
executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings)
).resolves.toEqual({
quoted: expected,
tagged: { cooked: expected, raw: expected },
})
})
it('leaves JavaScript comments and missing placeholders untouched', async () => {
const code = [
'// {{COMMENT}}',
'const missing = "{{MISSING}}"',
'const mixed = "{{MISSING}}/{{KEY}}"',
'const reverseMixed = "{{KEY}}/{{LONG_MISSING}}"',
'const template = `{{MISSING}}/{{KEY}}`',
'return { key: {{KEY}}, mixed, reverseMixed, template }',
].join('\n')
const compiled = await compileCodePlaceholders({
code,
language: CodeLanguage.JavaScript,
environmentVariables: { COMMENT: 'hidden', KEY: 'ok' },
})
expect(compiled.code).toContain('// {{COMMENT}}')
expect(compiled.code).toContain('"{{MISSING}}"')
expect(compiled.resolvedSecretNames).toEqual(['KEY'])
await expect(executeJavaScript(compiled.code, compiled.bindings)).resolves.toEqual({
key: 'ok',
mixed: '{{MISSING}}/ok',
reverseMixed: 'ok/{{LONG_MISSING}}',
template: '{{MISSING}}/ok',
})
})
it('keeps opaque binding names collision-free and applies env-over-param precedence', async () => {
const compiled = await compileCodePlaceholders({
code: 'return [{{A-B}}, {{A_B}}, {{__proto__}}]',
language: CodeLanguage.JavaScript,
params: Object.fromEntries([
['A-B', 1],
['A_B', false],
['__proto__', 'param'],
]),
environmentVariables: Object.fromEntries([
['A-B', 'env'],
['A_B', 'two'],
['__proto__', 'safe'],
]),
reservedNames: ['__sim_code_0_binding_0'],
})
expect(new Set(compiled.bindings.map((binding) => binding.name)).size).toBe(3)
expect(compiled.bindings.every((binding) => !binding.name.includes('A_B'))).toBe(true)
await expect(executeJavaScript(compiled.code, compiled.bindings)).resolves.toEqual([
'env',
'two',
'safe',
])
})
it('produces identical compiler artifacts for identical inputs', async () => {
const input = {
code: [
'const existing = __sim_code_0_binding_0',
'const quoted = "Bearer {{TOKEN}}"',
'const matcher = /^{{PATTERN}}$/i',
'return [existing, quoted, matcher.source, {{MISSING}}]',
].join('\n'),
language: CodeLanguage.JavaScript,
environmentVariables: { TOKEN: 'secret', PATTERN: 'a.+b' },
reservedNames: ['__sim_code_1_runtime_0'],
} as const
const first = await compileCodePlaceholders(input)
const second = await compileCodePlaceholders(input)
expect(second).toEqual(first)
})
it('keeps variable-length JavaScript parser sentinels scoped to their own syntax nodes', async () => {
const compiled = await compileCodePlaceholders({
code: 'const short = {{A}}; const long = "{{LONGER}}"; return [short, long]',
language: CodeLanguage.JavaScript,
environmentVariables: { A: 'short-value', LONGER: 'long-value' },
})
await expect(executeJavaScript(compiled.code, compiled.bindings)).resolves.toEqual([
'short-value',
'long-value',
])
})
it('keeps decoded JavaScript tokens and regex comment syntax collision-free', async () => {
const compiled = await compileCodePlaceholders({
code: [
"const \\u005f\\u005fsim_code_0_binding_0 = 'shadow'",
'const slash = /[//]/',
'const tag = (strings) => strings[1]',
'return [\\u005f\\u005fsim_code_0_binding_0, slash.test("/"), tag`head$' +
'{1}\\x2400000\\x24{{KEY}}`]',
].join('\n'),
language: CodeLanguage.JavaScript,
environmentVariables: { KEY: 'secret' },
})
expect(compiled.bindings[0].name).not.toBe('__sim_code_0_binding_0')
await expect(
executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings)
).resolves.toEqual(['shadow', true, '$00000$secret'])
})
it('preserves tagged-template precedence when the tag result is constructed', async () => {
const compiled = await compileCodePlaceholders({
code: [
'function Tag(strings) {',
' if (new.target) throw new Error("tag was constructed")',
' return class Result { constructor() { this.value = strings[0] } }',
'}',
'const instance = new Tag`{{KEY}}`',
'return [instance.constructor.name, instance.value]',
].join('\n'),
language: CodeLanguage.JavaScript,
environmentVariables: { KEY: 'secret' },
})
await expect(
executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings)
).resolves.toEqual(['Result', 'secret'])
})
it('rejects JavaScript placeholders used as write targets', async () => {
for (const code of [
'{{KEY}} = 1',
'{{KEY}}++',
'for ({{KEY}} of []) {}',
'({ x: {{KEY}} } = { x: 1 })',
'[{{KEY}}] = [1]',
'for ({ x: {{KEY}} } of []) {}',
'({ {{KEY}} } = {})',
]) {
await expect(
compileCodePlaceholders({
code,
language: CodeLanguage.JavaScript,
environmentVariables: { KEY: 'secret' },
})
).rejects.toThrow('is not supported')
}
const computedKey = await compileCodePlaceholders({
code: 'let target; ({ [{{KEY}}]: target } = { secret: 7 }); return target',
language: CodeLanguage.JavaScript,
environmentVariables: { KEY: 'secret' },
})
await expect(executeJavaScript(computedKey.code, computedKey.bindings)).resolves.toBe(7)
})
it('uses unshadowable JavaScript bindings in optional access and destructuring keys', async () => {
const compiled = await compileCodePlaceholders({
code: [
'const globalThis = {}',
'const object = { field: 7 }',
'const missing = null',
'const { "{{KEY}}": picked } = object',
'return [{{KEY}}, object?.{{KEY}}, missing?.{{KEY}}, picked]',
].join('\n'),
language: CodeLanguage.JavaScript,
environmentVariables: { KEY: 'field' },
})
await expect(executeJavaScript(compiled.code, compiled.bindings)).resolves.toEqual([
'field',
7,
undefined,
7,
])
})
it('keeps template interpolation active after an odd source backslash', async () => {
const oneBackslash = await compileCodePlaceholders({
code: 'return `\\{{KEY}}`',
language: CodeLanguage.JavaScript,
environmentVariables: { KEY: 'secret' },
})
const twoBackslashes = await compileCodePlaceholders({
code: 'return `\\\\{{KEY}}`',
language: CodeLanguage.JavaScript,
environmentVariables: { KEY: 'secret' },
})
await expect(executeJavaScript(oneBackslash.code, oneBackslash.bindings)).resolves.toBe(
'secret'
)
await expect(executeJavaScript(twoBackslashes.code, twoBackslashes.bindings)).resolves.toBe(
'\\secret'
)
expect(oneBackslash.code).not.toContain(`\\\${${oneBackslash.bindings[0].name}}`)
})
it('leaves JavaScript shebang placeholders untouched', async () => {
const compiled = await compileCodePlaceholders({
code: '#!/usr/bin/env node {{COMMENT}}\nconst value = {{KEY}}',
language: CodeLanguage.JavaScript,
environmentVariables: { COMMENT: 'hidden', KEY: 'visible-at-runtime-only' },
})
expect(compiled.code).toContain('#!/usr/bin/env node {{COMMENT}}')
expect(compiled.code).not.toContain('visible-at-runtime-only')
expect(compiled.resolvedSecretNames).toEqual(['KEY'])
})
it('rejects malformed JavaScript instead of repairing it during placeholder compilation', async () => {
await expect(
compileCodePlaceholders({
code: 'return "unterminated {{KEY}}',
language: CodeLanguage.JavaScript,
environmentVariables: { KEY: 'secret' },
})
).rejects.toThrow('Invalid JavaScript syntax: Unterminated string literal')
const compiled = await compileCodePlaceholders({
code: 'return {{KEY}}',
language: CodeLanguage.JavaScript,
environmentVariables: { KEY: 'secret' },
})
await expect(executeJavaScript(compiled.code, compiled.bindings)).resolves.toBe('secret')
})
it('keeps matching secret names and values out of source in JavaScript and Python', async () => {
const javascript = await compileCodePlaceholders({
code: 'return {{Test}}',
language: CodeLanguage.JavaScript,
environmentVariables: { Test: 'Test' },
})
const python = await compileCodePlaceholders({
code: 'def read():\n return {{Test}}\nprint(read())',
language: CodeLanguage.Python,
environmentVariables: { Test: 'Test' },
})
expect(javascript.code).not.toContain('Test')
expect(python.code).not.toContain('Test')
await expect(executeJavaScript(javascript.code, javascript.bindings)).resolves.toBe('Test')
expect(executePython(python.code, python.bindings)).toBe('Test\n')
})
it('preserves placeholders in Annex B HTML comments and normalizes them for modules', async () => {
const compiled = await compileCodePlaceholders({
code: [
'<!-- {{OPEN_COMMENT}}',
'const value = "<!-- {{KEY}}"',
'const matcher = /<!-- {{PATTERN}}/',
' --> {{CLOSE_COMMENT}}',
'return [value, matcher.test("<!-- token")]',
].join('\n'),
language: CodeLanguage.JavaScript,
environmentVariables: {
OPEN_COMMENT: 'must-remain-a-comment',
CLOSE_COMMENT: 'must-also-remain-a-comment',
KEY: 'secret',
PATTERN: 'token',
},
})
expect(compiled.code).toMatch(/^\/\/\s+\{\{OPEN_COMMENT\}\}/)
expect(compiled.code).toMatch(/^\s*\/\/\s+\{\{CLOSE_COMMENT\}\}/m)
expect(compiled.resolvedSecretNames).toEqual(['KEY', 'PATTERN'])
await expect(
executeJavaScript(compiled.code, compiled.bindings, compiled.runtimeBindings)
).resolves.toEqual(['<!-- secret', true])
const commentOnly = await compileCodePlaceholders({
code: '<!-- ordinary comment\nreturn 1',
language: CodeLanguage.JavaScript,
environmentVariables: {},
})
expect(commentOnly.code).toMatch(/^\/\/\s+ordinary comment/)
await expect(executeJavaScript(commentOnly.code, commentOnly.bindings)).resolves.toBe(1)
})
it('compiles Python bare, normal, raw, triple, bytes, f-string, and adjacent literals out of band', async () => {
const value = 'quote" slash\\ newline\n{{OTHER}}'
const compiled = await compileCodePlaceholders({
code: [
'bare = {{KEY}}',
'normal = "Bearer {{KEY}}"',
'raw = r"{{KEY}}\\path"',
'triple = """{{KEY}}\nend"""',
'binary = b"{{KEY}}"',
'formatted = f"Token {{KEY}}"',
'adjacent = ("{{KEY}}" "!")',
'# {{COMMENT}}',
].join('\n'),
language: CodeLanguage.Python,
environmentVariables: { KEY: value, OTHER: 'must-not-resolve', COMMENT: 'hidden' },
})
expect(compiled.code).not.toContain(value)
expect(compiled.code).not.toContain('__var_')
expect(compiled.code).toContain(compiled.bindings[0].name)
expect(compiled.code).not.toContain('__import__')
expect(compiled.code).toContain('# {{COMMENT}}')
expect(compiled.resolvedSecretNames).toEqual(['KEY'])
})
it('uses unshadowable Python bindings in strings, expressions, and format specs', async () => {
const compiled = await compileCodePlaceholders({
code: [
'globals = lambda: {}',
'__import__ = None',
'normal = "{{KEY}}"',
'bare = {{KEY}}',
'formatted = f"{7:{{WIDTH}}}"',
'print(repr((normal, bare, formatted)))',
].join('\n'),
language: CodeLanguage.Python,
environmentVariables: { KEY: 'secret-value', WIDTH: '03' },
})
expect(executePython(compiled.code, compiled.bindings)).toBe(
"('secret-value', 'secret-value', '007')\n"
)
})
it('accepts Python bare placeholders after value-taking keywords', async () => {
const compiled = await compileCodePlaceholders({
code: [
'def returned():',
' return {{KEY}}',
'def yielded():',
' yield {{KEY}}',
'def raised():',
' try:',
' raise ValueError({{KEY}})',
' except ValueError as error:',
' return str(error)',
'def selected():',
' assert {{FLAG}}',
' if {{FLAG}}:',
' return {{KEY}}',
' while {{EMPTY}}:',
' raise RuntimeError("unreachable")',
'print(repr((returned(), next(yielded()), raised(), selected())))',
].join('\n'),
language: CodeLanguage.Python,
environmentVariables: { KEY: 'secret', FLAG: 'true', EMPTY: '' },
})
expect(executePython(compiled.code, compiled.bindings)).toBe(
"('secret', 'secret', 'secret', 'secret')\n"
)
})
it('distinguishes Python lambda identifiers, match guards, and soft keywords from names', async (ctx) => {
if (!hasPython3()) ctx.skip(PYTHON_SKIP_REASON)
const compiled = await compileCodePlaceholders({
code: [
'lambda_value = "prefix-"',
'def my_lambda(value):',
' return value',
'combined = lambda_value + {{KEY}}',
'literal = "lambda" + {{KEY}}',
'formatted = f\'{"lambda" + {{KEY}}}\'',
'called = my_lambda({{KEY}})',
'case = {{KEY}}',
'match case:',
' case _ if {{FLAG}}:',
' guarded = {{KEY}}',
'print(repr((combined, literal, formatted, called, case, guarded)))',
].join('\n'),
language: CodeLanguage.Python,
environmentVariables: { KEY: 'secret', FLAG: 'true' },
})
expect(executePython(compiled.code, compiled.bindings)).toBe(
"('prefix-secret', 'lambdasecret', 'lambdasecret', 'secret', 'secret', 'secret')\n"
)
})
it('keeps Python bindings stable inside class scopes', async () => {
const compiled = await compileCodePlaceholders({
code: [
'class Box:',
' quoted = "{{KEY}}"',
' bare = {{KEY}}',
' formatted = f"value={{KEY}}"',
' def read(self):',
' return {{KEY}}',
'print(repr((Box.quoted, Box.bare, Box.formatted, Box().read())))',
].join('\n'),
language: CodeLanguage.Python,
environmentVariables: { KEY: 'secret' },
})
expect(compiled.bindings.every(({ name }) => name.endsWith('__'))).toBe(true)
expect(executePython(compiled.code, compiled.bindings)).toBe(
"('secret', 'secret', 'value=secret', 'secret')\n"
)
})
it('preserves Python raw-string escapes, alternate format flags, and dynamic attributes', async () => {
const compiled = await compileCodePlaceholders({
code: [
'class Box:',
' field = "attribute"',
'box = Box()',
'print(r"before\\\"{{KEY}}")',
'print(f"{255:#0{{WIDTH}}x}")',
'print(box . {{FIELD}})',
].join('\n'),
language: CodeLanguage.Python,
environmentVariables: { KEY: 'secret', WIDTH: '6', FIELD: 'field' },
})
expect(executePython(compiled.code, compiled.bindings)).toBe(
'before\\"secret\n0x00ff\nattribute\n'
)
})
it('uses non-assignable Python runtime expressions and rejects write positions', async () => {
for (const code of [
'{{KEY}} = 1',
'obj.{{KEY}} = 1',
'del obj . {{KEY}}',
'print(f"{({{KEY}} := 1)}")',
'def build({{KEY}}): pass',
'lambda first, {{KEY}}: first',
'for first, {{KEY}} in []: pass',
'match value:\n case {{KEY}}: pass',
]) {
await expect(
compileCodePlaceholders({
code,
language: CodeLanguage.Python,
environmentVariables: { KEY: 'secret' },
})
).rejects.toThrow('is not supported')
}
})
it('interpolates many Python placeholders without recursive source evaluation', async () => {
const count = 500
const compiled = await compileCodePlaceholders({
code: `print("${'{{KEY}}'.repeat(count)}")`,
language: CodeLanguage.Python,
environmentVariables: { KEY: 'x' },
})
expect(executePython(compiled.code, compiled.bindings)).toBe(`${'x'.repeat(count)}\n`)
})
it('keeps placeholders inside nested dynamic format fields as expressions', async () => {
const compiled = await compileCodePlaceholders({
code: 'print(f"{7:{int({{WIDTH}})}}")',
language: CodeLanguage.Python,
environmentVariables: { WIDTH: '3' },
})
expect(compiled.code).not.toContain(`{${compiled.bindings[0].name}}`)
expect(executePython(compiled.code, compiled.bindings)).toBe(' 7\n')
})
it('supports quoted and embedded strings inside Python f-string expressions', async (ctx) => {
if (!hasPython3()) ctx.skip(PYTHON_SKIP_REASON)
const value = 'quote"\\\n{{OTHER}}'
const compiled = await compileCodePlaceholders({
code: [
'import json',
'quoted = f"{\'prefix {{KEY}} suffix\'}"',
'same_quote = f"{ "same {{KEY}} suffix" }"',
"adjacent = f\"{('left {{KEY}}' ' right {{KEY}}')}\"",
'nested = f"{f\'nested {{KEY}}\'}"',
'print(json.dumps([quoted, same_quote, adjacent, nested], separators=(",", ":")))',
].join('\n'),
language: CodeLanguage.Python,
environmentVariables: { KEY: value, OTHER: 'must-not-resolve' },
})
expect(compiled.code).not.toContain(value)
expect(executePython(compiled.code, compiled.bindings)).toBe(
`${JSON.stringify([
`prefix ${value} suffix`,
`same ${value} suffix`,
`left ${value} right ${value}`,
`nested ${value}`,
])}\n`
)
})
it('keeps Python f-string operators valid and rejects unsafe conversion and debug positions', async () => {
const valid = await compileCodePlaceholders({
code: 'print(f"{1 != {{KEY}}}")',
language: CodeLanguage.Python,
environmentVariables: { KEY: '2' },
})
expect(executePython(valid.code, valid.bindings)).toBe('True\n')
for (const code of ['print(f"{1!{{KEY}}}")', 'print(f"{ {{KEY}} =}")']) {
const error = await compileCodePlaceholders({
code,
language: CodeLanguage.Python,
environmentVariables: { KEY: 'must-not-appear' },
}).catch((caught) => caught)
expect(error).toBeInstanceOf(Error)
expect(String(error)).toContain('is not supported')
expect(String(error)).not.toContain('must-not-appear')
}
})
it('ignores Python f-string comments and does not group adjacent strings across dedents', async (ctx) => {
if (!hasPython3()) ctx.skip(PYTHON_SKIP_REASON)
const code = [
'def build():',
' value = "{{KEY}}"',
'print("outside")',
'commented = f"""{(',
' 1 # {{COMMENT}}',
')}"""',
].join('\n')
const compiled = await compileCodePlaceholders({
code,
language: CodeLanguage.Python,
environmentVariables: { KEY: 'secret', COMMENT: 'hidden' },
})
expect(compiled.code).toContain('# {{COMMENT}}')
expect(compiled.resolvedSecretNames).toEqual(['KEY'])
expect(executePython(compiled.code, compiled.bindings)).toBe('outside\n')
})
it('preserves Python implicit string concatenation across comments inside brackets', async () => {
const compiled = await compileCodePlaceholders({
code: [
'value = (',
' "prefix {{KEY}}"',
' # an intervening comment',
' " suffix {{KEY}}"',
')',
'print(value)',
].join('\n'),
language: CodeLanguage.Python,
environmentVariables: { KEY: 'secret' },
})
expect(executePython(compiled.code, compiled.bindings)).toBe('prefix secret suffix secret\n')
})
it('compiles shell quote contexts and preserves comments', async () => {
const secret = 'a"\\ newline\n$()`;*'
const compiled = await compileCodePlaceholders({
code: [
"printf '<%s>\\n' {{BARE}}",
'printf \'<%s>\\n\' "{{KEY}}"',
"printf '<%s>\\n' '{{KEY}}'",
"printf '<%s>\\n' $'{{KEY}}'",
'# {{COMMENT}}',
'echo {{MISSING}}',
].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: { BARE: 'bare', KEY: secret, COMMENT: 'hidden' },
})
expect(compiled.code).not.toContain('a"\\')
expect(compiled.code).toContain('# {{COMMENT}}')
expect(compiled.code).not.toContain('echo {{MISSING}}')
expect(compiled.resolvedSecretNames).toEqual(['BARE', 'KEY'])
expect(executeShell(compiled.code, compiled.bindings)).toBe(
`<bare>\n${`<${secret}>\n`.repeat(3)}\n`
)
})
it('lowers supported missing shell placeholders to legacy empty values', async () => {
const compiled = await compileCodePlaceholders({
code: [
"printf '<%s>\\n' {{MISSING}}",
'printf \'<%s>\\n\' "{{MISSING}}"',
"printf '<%s>\\n' '{{MISSING}}'",
"printf '<%s>\\n' $'{{MISSING}}'",
'printf \'<%s>\\n\' "before{{MISSING}}after"',
"printf '<%s>\\n' 'before{{MISSING}}after'",
"printf '<%s>\\n' prefix{{MISSING}}suffix",
'# {{MISSING}}',
"cat <<'PAYLOAD'",
'quoted-{{MISSING}}-body',
'$UNRELATED `printf unsafe`',
'PAYLOAD',
'cat <<PAYLOAD',
'unquoted-{{MISSING}}-body',
'PAYLOAD',
"cat <<'{{DELIMITER}}'",
'delimiter-body',
'{{DELIMITER}}',
].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: {},
})
expect(compiled.bindings).toEqual([])
expect(compiled.privateInputs).toEqual([])
expect(compiled.resolvedSecretNames).toEqual([])
expect(compiled.code).not.toContain("printf '<%s>\\n' {{MISSING}}")
expect(compiled.code).not.toContain('quoted-{{MISSING}}-body')
expect(compiled.code).not.toContain('unquoted-{{MISSING}}-body')
expect(compiled.code).toContain('# {{MISSING}}')
expect(compiled.code).toContain('$UNRELATED `printf unsafe`')
expect(compiled.code).toContain("cat <<'{{DELIMITER}}'")
expect(compiled.code).toContain('\n{{DELIMITER}}')
expect(executeShell(compiled.code, compiled.bindings)).toBe(
`${'<>\n'.repeat(4)}${'<beforeafter>\n'.repeat(2)}<prefixsuffix>\n` +
'quoted--body\n$UNRELATED `printf unsafe`\nunquoted--body\ndelimiter-body\n'
)
})
it('trims valid shell placeholder names and leaves invalid names literal', async () => {
const compiled = await compileCodePlaceholders({
code: ['printf \'<%s>\\n\' "{{ KEY }}"', 'printf \'<%s>\\n\' "{{API-KEY}}"'].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: { KEY: 'secret', 'API-KEY': 'hyphen-secret' },
})
expect(compiled.bindings).toHaveLength(1)
expect(compiled.resolvedSecretNames).toEqual(['KEY'])
expect(executeShell(compiled.code, compiled.bindings)).toBe('<secret>\n<{{API-KEY}}>\n')
await expect(
analyzeCodePlaceholders('{{ KEY }} {{API-KEY}}', CodeLanguage.Shell)
).resolves.toEqual(['KEY'])
})
it('preserves legacy unquoted shell regex, word-splitting, and empty-value semantics', async () => {
const compiled = await compileCodePlaceholders({
code: [
'[[ abc =~ {{PATTERN}} ]] && echo matched',
'set -- {{WORDS}}',
'printf "words=%s\\n" "$#"',
'set -- before {{EMPTY}} after',
'printf "empty=%s\\n" "$#"',
].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: { PATTERN: 'a.*', WORDS: 'one two', EMPTY: '' },
})
expect(executeShell(compiled.code, compiled.bindings)).toBe('matched\nwords=2\nempty=2\n')
})
it('does not mistake shell arithmetic shifts for heredocs', async () => {
const compiled = await compileCodePlaceholders({
code: [': $(( x << 1 ))', '(( y = 1 << 2 ))', "printf '<%s>\\n' '{{KEY}}'"].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: { KEY: 'secret-value' },
})
expect(compiled.privateInputs).toEqual([])
expect(executeShell(compiled.code, compiled.bindings)).toBe('<secret-value>\n')
})
it('tracks nested shell command substitutions and their own quote contexts', async () => {
const compiled = await compileCodePlaceholders({
code: [
'printf "<%s>\\n" "$(printf %s \'{{KEY}}\')"',
'printf "<%s>\\n" "`printf %s \'{{KEY}}\'`"',
'cat <<PAYLOAD',
"$(printf %s '{{KEY}}')",
"$'{{KEY}}'",
"'{{KEY}}'",
'PAYLOAD',
].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: { KEY: 'a b$`' },
})
expect(compiled.code).not.toContain('__var_')
expect(executeShell(compiled.code, compiled.bindings)).toBe(
"<a b$`>\n<a b$`>\na b$`\n$'a b$`'\n'a b$`'\n"
)
})
it('rejects shell NUL values without including the value in the diagnostic', async () => {
const error = await compileCodePlaceholders({
code: 'printf %s {{KEY}}',
language: CodeLanguage.Shell,
environmentVariables: { KEY: 'before\0after' },
}).catch((caught) => caught)
expect(error).toBeInstanceOf(Error)
expect(String(error)).toContain('cannot contain NUL')
expect(String(error)).not.toContain('before')
expect(String(error)).not.toContain('after')
})
it('renders quoted shell heredocs through a private file without enabling shell expansion', async () => {
const compiled = await compileCodePlaceholders({
code: [
"cat <<'PAYLOAD'",
'Bearer {{KEY}}',
'$UNRELATED `touch /tmp/never` $(touch /tmp/never-either)',
'PAYLOAD',
'echo done',
].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: { KEY: 'a"\\\n{{OTHER}}', OTHER: 'must-not-resolve' },
})
expect(compiled.privateInputs).toHaveLength(1)
expect(compiled.privateInputs[0].content).toBe(
'Bearer a"\\\n{{OTHER}}\n$UNRELATED `touch /tmp/never` $(touch /tmp/never-either)\n'
)
expect(compiled.code).toContain(`< "\${${compiled.privateInputs[0].environmentVariable}}"`)
expect(compiled.code).not.toContain('$UNRELATED')
expect(compiled.code).toContain('echo done')
expect(compiled.resolvedSecretNames).toEqual(['KEY'])
})
it('deduplicates identical quoted shell heredoc payloads', async () => {
const compiled = await compileCodePlaceholders({
code: ["cat <<'ONE'", '{{KEY}}', 'ONE', "cat <<'TWO'", '{{KEY}}', 'TWO'].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: { KEY: 'secret' },
})
expect(compiled.privateInputs).toHaveLength(1)
const environmentVariable = compiled.privateInputs[0].environmentVariable
expect(compiled.code.match(new RegExp(environmentVariable, 'g'))).toHaveLength(2)
})
it('recognizes ANSI-C, locale, and empty quoted shell heredoc delimiters', async () => {
const compiled = await compileCodePlaceholders({
code: [
String.raw`cat <<$'PAY\x4cOAD'`,
'{{FIRST}}',
'PAYLOAD',
'cat <<$"LOCALIZED"',
'{{SECOND}}',
'LOCALIZED',
"cat <<''",
'{{THIRD}}',
'',
'',
].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: { FIRST: 'one', SECOND: 'two', THIRD: 'three' },
})
expect(compiled.privateInputs.map(({ content }) => content)).toEqual([
'one\n',
'two\n',
'three\n',
])
expect(compiled.code).not.toContain('PAYLOAD')
expect(compiled.code).not.toContain('LOCALIZED')
expect(compiled.resolvedSecretNames).toEqual(['FIRST', 'SECOND', 'THIRD'])
})
it('recognizes quoted shell heredoc delimiters across a continued header', async () => {
const compiled = await compileCodePlaceholders({
code: ['cat <<\\', "'PAYLOAD'", '{{KEY}}', 'PAYLOAD'].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: { KEY: 'secret' },
})
expect(compiled.privateInputs).toHaveLength(1)
expect(compiled.privateInputs[0].content).toBe('secret\n')
expect(compiled.code).toContain(` \\\n`)
})
it('does not parse heredoc-looking text inside a multiline shell quote', async () => {
const compiled = await compileCodePlaceholders({
code: ['printf "%s\\n" "literal', "<<'PAYLOAD'", '{{KEY}}', 'PAYLOAD"'].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: { KEY: 'secret' },
})
expect(compiled.privateInputs).toEqual([])
expect(executeShell(compiled.code, compiled.bindings)).toBe(
"literal\n<<'PAYLOAD'\nsecret\nPAYLOAD\n"
)
})
it('rejects ambiguous shell parameter and parser-name positions', async () => {
for (const code of ['printf %s $' + '{{KEY}}', 'for {{KEY}} in value; do :; done']) {
await expect(
compileCodePlaceholders({
code,
language: CodeLanguage.Shell,
environmentVariables: { KEY: 'secret' },
})
).rejects.toThrow('is not supported')
}
})
it('renders quoted shell heredocs nested in double-quoted command substitutions', async () => {
const compiled = await compileCodePlaceholders({
code: [
"output=\"$(cat <<'PAYLOAD'",
'Bearer {{KEY}}',
'$UNRELATED `printf unsafe` $(printf unsafe)',
'PAYLOAD',
')"',
'printf \'%s\\n\' "$output"',
].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: { KEY: 'secret value' },
})
expect(compiled.privateInputs).toHaveLength(1)
expect(compiled.privateInputs[0].content).toBe(
'Bearer secret value\n$UNRELATED `printf unsafe` $(printf unsafe)\n'
)
expect(compiled.code).toContain(
`output="$(cat < "\${${compiled.privateInputs[0].environmentVariable}}"`
)
expect(compiled.code).not.toContain('$UNRELATED')
})
it('keeps unquoted shell heredocs on native expansion semantics', async () => {
const compiled = await compileCodePlaceholders({
code: ['cat <<PAYLOAD', '{{KEY}}', '$UNRELATED', 'PAYLOAD'].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: { KEY: 'secret' },
})
expect(compiled.privateInputs).toEqual([])
expect(compiled.code).toContain(`\${${compiled.bindings[0].name}}`)
expect(compiled.code).toContain('$UNRELATED')
})
it('keeps shell provenance in source order and rejects escaped placeholder contexts', async () => {
const error = await compileCodePlaceholders({
code: ['printf %s {{FIRST}}', 'cat <<PAYLOAD', '\\{{SECOND}}', 'PAYLOAD'].join('\n'),
language: CodeLanguage.Shell,
environmentVariables: { FIRST: 'first', SECOND: 'second' },
}).catch((caught) => caught)
expect(error).toBeInstanceOf(Error)
expect(String(error)).toContain('escaped shell sequence')
expect(String(error)).not.toContain('first')
expect(String(error)).not.toContain('second')
})
it('analyzes unsupported resolved syntax without failing missing-variable discovery', async () => {
await expect(
analyzeCodePlaceholders(
['// {{COMMENT}}', 'import value from "{{MODULE}}"', 'String.raw`{{TAGGED}}`'].join('\n'),
CodeLanguage.JavaScript
)
).resolves.toEqual(['MODULE', 'TAGGED'])
await expect(
analyzeCodePlaceholders("cat <<'{{DELIMITER}}'\nbody\n{{DELIMITER}}", CodeLanguage.Shell)
).resolves.toEqual(['DELIMITER'])
})
})