Language GuideSecurity & Limits

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 exceeded

Safe 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 zero

Combine 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:

KindMeaning
noneExecution succeeded
parseThe script failed to lex/parse
runtimeA runtime error occurred (bad operation, undefined variable, recursion guard, …)
timeoutThe execution timeout was exceeded
max_operationsThe 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 maxOps for deterministic protection against logic errors (loops) and timeout as a failsafe for heavy computation.
  • Branch on the error kind: Check result.errorKind / result.Kind rather 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.