Proof-of-fix · Finding #1 remediation

Hardened Engine Lab

a real parser, not new Function()

The v12 report's #1 Critical finding is that Ophis compiles .oph-controlled formula strings with new Function(). This page implements the recommended fix — a sandboxed recursive-descent evaluator over the Ophis grammar — and proves two things at load: it computes identically to the current engine on every shipped operation, and it rejects injection payloads that new Function() would execute. Open it; the tests run themselves.

§A · Results

Self-checking scoreboard

§B · Parity

Safe parser ≡ current engine, on every operation

Each shipped/cookbook operation is evaluated over several interval values Y by both the current new Function() path and the new safeEval parser. They must agree to the last decimal. This is the guarantee that hardening changes nothing a user sees.

OperationY=1319Y=1656Y=6940Result
§C · Security

Injection payloads: executed vs blocked

The same strings fed to both engines. The current new Function() path (and the rewrites' regex-allowlist) treats these as code; the parser rejects anything outside the grammar — numbers, Y, the four constants, the oph_* functions, and + − * / ( ). A blocked in the right column is a win.

Payload (after X2+)What it targetsnew Function()safeEval

Why the current regex filter isn't enough

The PSYFR rewrites gate input with a character-allowlist (blank the known tokens, reject leftover letters). That stops casual misuse, but it's a denylist in front of a live compiler — one new function alias, or a payload built only from allowed characters, and it's back to arbitrary code. A parser that only ever produces an AST it knows how to walk has no such escape hatch.

§D · Try it

Type an operation

Anything legal computes with Y = 1656. Anything outside the grammar is rejected with a reason — never executed.

# The whole safe evaluator is ~90 lines, no dependencies, no eval/new Function.
# Grammar:  expr := term (('+'|'-') term)*   term := factor (('*'|'/') factor)*
#           factor := number | 'Y' | CONST | func '(' expr ')' | '(' expr ')' | '-' factor