Skip to main content

XfaJsRuntime

Trait XfaJsRuntime 

Source
pub trait XfaJsRuntime {
    // Required methods
    fn init(&mut self) -> Result<(), SandboxError>;
    fn reset_for_new_document(&mut self) -> Result<(), SandboxError>;
    fn execute_script(
        &mut self,
        activity: Option<&str>,
        body: &str,
    ) -> Result<RuntimeOutcome, SandboxError>;
    fn take_metadata(&mut self) -> RuntimeMetadata;

    // Provided methods
    fn set_form_handle(
        &mut self,
        _form: *mut FormTree,
        _root_id: FormNodeId,
    ) -> Result<(), SandboxError> { ... }
    fn set_data_handle(&mut self, _dom: *const DataDom) { ... }
    fn set_declared_subform_names(&mut self, _names: HashSet<String>) { ... }
    fn reset_per_script(
        &mut self,
        _current_id: FormNodeId,
        _activity: Option<&str>,
    ) -> Result<(), SandboxError> { ... }
    fn set_static_page_count(
        &mut self,
        _page_count: u32,
    ) -> Result<(), SandboxError> { ... }
    fn set_presave_gate(&mut self, _enabled: bool) { ... }
    fn take_occur_mutations(&mut self) -> Vec<(usize, String, i64)> { ... }
    fn take_diag_logs(&mut self) -> RuntimeDiagLogs { ... }
}
Expand description

The host-side adapter the dispatch path calls. A minimal contract chosen so that swapping backends (rquickjs ↔ boa ↔ external sandbox) is one Cargo feature flag away.

Required Methods§

Source

fn init(&mut self) -> Result<(), SandboxError>

One-time initialisation. Idempotent.

Source

fn reset_for_new_document(&mut self) -> Result<(), SandboxError>

Reset per-document state (memory budget, instruction counter, any cached compiled scripts). Called once per flatten.

Source

fn execute_script( &mut self, activity: Option<&str>, body: &str, ) -> Result<RuntimeOutcome, SandboxError>

Execute one script body inside the sandbox.

activity is the enclosing <event activity="..."> value if any. The dispatch site has already filtered against activity_allowed_for_sandbox; backends may treat unknown activities as PhaseDenied for defence-in-depth.

Source

fn take_metadata(&mut self) -> RuntimeMetadata

Take the cumulative metadata since the last take_metadata call (or since reset_for_new_document, whichever was later).

Provided Methods§

Source

fn set_form_handle( &mut self, _form: *mut FormTree, _root_id: FormNodeId, ) -> Result<(), SandboxError>

Phase C: install the FormTree the runtime should resolve paths against and mutate. The dispatch path owns the mutable borrow and clears the handle before returning.

Source

fn set_data_handle(&mut self, _dom: *const DataDom)

Phase D-γ: install a read-only view of the DataDom for the current document. Called once per document after set_form_handle, before any scripts run. Default: no-op (backends without DataDom support ignore it).

§Safety

Callers must guarantee that dom outlives all script execution for this document (i.e. it must remain alive until set_form_handle(null) is called). The runtime stores the pointer read-only and never writes through it.

Source

fn set_declared_subform_names(&mut self, _names: HashSet<String>)

BE-1 tranche #1 (benign zero-instance SOM): install the set of template-declared container names (subform/subformSet/exclGroup/ area) for the current document. Backends that resolve implicit SOM identifiers use it to return a benign empty-node façade for a declared-but-absent reference instead of undefined (Adobe semantics), so guarded scripts (if (!Sub.Child.isNull) {...} else {...}) run their else branch instead of throwing. Like set_data_handle, the caller installs this before script execution. Default: no-op (the static NullRuntime ignores it, so the default/non-sandboxed path is unaffected and stays byte-identical).

Source

fn reset_per_script( &mut self, _current_id: FormNodeId, _activity: Option<&str>, ) -> Result<(), SandboxError>

Phase C: reset per-script host counters and install the current script context node / activity. Backends without host bindings ignore it.

Source

fn set_static_page_count( &mut self, _page_count: u32, ) -> Result<(), SandboxError>

Phase C page-count foundation. The current flatten order runs scripts before layout, so callers normally leave this at 0.

Source

fn set_presave_gate(&mut self, _enabled: bool)

D1.B gated allow. Inform the runtime whether the XFA_PRESAVE_DURING_FLATTEN=1 opt-in is active for the current flatten. The dispatch path computes this once per document via presave_during_flatten_enabled and forwards it here so the host binding layer can mirror the dispatch decision (defence-in-depth).

Default: no-op. Backends without a host-binding gate ignore it. The contract for backends that DO mirror the gate:

  1. Default OFF: every call to HostBindings::write_activity_allowed with current_activity = Some("preSave") MUST return false.
  2. Gate ON: the same call MUST return true ONLY for Some("preSave"). Every other denylist activity (preSubmit, click, …) MUST continue to return false.

Cross-ref: docs/INST_MGR_ACTIVITY_POLICY.md v5 §6.1 (D1.B).

Source

fn take_occur_mutations(&mut self) -> Vec<(usize, String, i64)>

D6: drain captured occur.min/occur.max write intents (node_index, prop, value) recorded during the script pass. The dispatch path applies them (only when XFA_OCCUR_APPLY=1) after the rollback decision. Default: none (non-sandboxed runtimes capture nothing).

Source

fn take_diag_logs(&mut self) -> RuntimeDiagLogs

Epic A E-2/E-3: drain verbose per-entry diagnostic logs. Only populated when XFA_RUNTIME_DIAG=1 is set at the host call sites. Default impl returns empty logs (NullRuntime, non-sandboxed paths).

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§