Security & Execution Limits
KodiScript provides built-in mechanisms to protect your application from infinite loops, overly complex scripts, and long-running execution. This is essential when executing untrusted code or allowing user-defined scripts.
Instruction Counter (Max Operations)
You can limit the number of operations (instructions) a script executes. This is a deterministic way to prevent infinite loops.
Usage
result := kodi.New(script).
WithMaxOperations(10000).
Execute()If the limit is exceeded, execution stops immediately and an error is returned (e.g., MaxOperationsExceeded).
Time-based Timeout
You can also set a maximum duration for script execution. This is useful for ensuring latency SLAs.
Usage
result := kodi.New(script).
WithTimeout(5 * time.Second).
Execute()If the timeout is exceeded, execution stops and a TimeoutError (or equivalent) is returned.
Recursion Guard
Deeply (or infinitely) recursive scripts are stopped before they can exhaust the host’s native stack. Call depth is capped at 1000 frames; exceeding it raises a runtime error (maximum call depth exceeded) that you can catch or inspect, instead of crashing the host process.
fn loop() {
return loop() // unbounded recursion
}
loop() // -> runtime error: maximum call depth exceededSafe Arithmetic
To keep behaviour deterministic and identical across engines, invalid arithmetic raises a runtime error rather than producing Infinity or NaN:
10 / 0 // -> runtime error: division by zero
10 % 0 // -> runtime error: modulo by zeroCombine this with try/catch to recover gracefully.
Typed Error Kinds
Every result exposes an error kind so you can react programmatically instead of matching on message strings. The categories are:
| Kind | Meaning |
|---|---|
none | Execution succeeded |
parse | The script failed to lex/parse |
runtime | A runtime error occurred (bad operation, undefined variable, recursion guard, …) |
timeout | The execution timeout was exceeded |
max_operations | The operation limit was exceeded |
result := kodi.New(script).WithMaxOperations(1000).Execute()
if result.Kind == kodi.ErrorKindMaxOperations {
// handle the limit being hit
}Best Practices
- Always set limits when running untrusted code.
- Combine both: Use
maxOpsfor deterministic protection against logic errors (loops) andtimeoutas a failsafe for heavy computation. - Branch on the error kind: Check
result.errorKind/result.Kindrather than parsing error message text — it’s stable across versions and engines. - Sandbox by default: Scripts can only touch the variables and functions you explicitly inject. See Extensibility for scoping guidance.