Skip to content

bug (batch, low): Extism empty-input, Starlark dict key collision, Risor uint64 wrap, and minor edge cases #165

Description

@robbyt

A batch of confirmed low-severity correctness edge cases, grouped to limit issue noise. Split out any that warrant a dedicated fix.

1. Extism sends zero bytes instead of {} when input is empty

engines/extism/internal/converters.go:9-11:

if len(inputData) == 0 { return nil, nil }

Eval with no static or context data passes nil to CallWithContext; a guest that would accept {} fails to parse empty input.

Repro (confirmed): Eval with no data → execution failed: unexpected end of JSON input.

Fix: marshal the empty map to {} when the intent is "no data ⇒ empty object"; otherwise document the behavior.

2. Starlark dict → map collides stringified keys and drops unreadable entries

engines/starlark/internal/converters.go:79-97: non-string keys are stringified via k.String(); distinct keys that render identically overwrite each other, and v.Get(k) errors are silently skipped.

Repro (confirmed): _ = {1: "a", "1": "b"}Interface() == map[1:b] (one entry; 1: "a" lost).

Fix: disambiguate non-string keys (or return an error), and propagate Get errors.

3. Risor uint64 values above MaxInt64 wrap silently

engines/risor/internal/converters.go passes input straight to Risor, whose TypeRegistry.fromGoByKind does NewInt(int64(rv.Uint())).

Repro (confirmed): static data {"big": uint64(math.MaxUint64)}, script ctx["big"]-1. The wrap is upstream in Risor v2, but go-polyscript feeds the value in unguarded, whereas Starlark's converter rejects uint64. Consider a guard or warning for uint64 values exceeding int64 range, for cross-engine consistency.

4. Starlark eval_data universe entry is dead code

engines/starlark/evaluator/evaluator.go:44 adds eval_data to the runtime universe, but it's never in the compile-time predeclared set (compiler/internal/compile/compile.go), so any script referencing it fails to compile. Remove it or wire it into the predeclared set.

5. Extism execHelper misattributes call failures as cancellation

engines/extism/evaluator/evaluator.go:114-118: when the guest fails for its own reason while ctx is cancelled, the real error is replaced with "execution cancelled: context canceled", discarding the cause. (Root cause that cancellation doesn't actually interrupt execution is #155.) Fix: wrap both errors, or prefer ctx.Err() only for wazero's exit-code-canceled sentinel.

Impact

Low individually — edge cases with clear repros, none covered by existing tests. Worth fixing for robustness and cross-engine consistency.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions