Liking cljdoc? Tell your friends :D

vaelii.impl.io.thaw

The class-name door on every nippy thaw the engine runs over a file.

A frozen nippy value can name a class in three of its type ids, and reading one resolves that name and builds an instance of it: a record frame (Class/forName, then the static create), a deftype frame (Class/forName, then the first public constructor over the fields that follow), and a Serializable frame (an ObjectInputStream over the bytes that follow). nippy 3.8.1 gates the third behind *thaw-serializable-allowlist* and the first two behind nothing at all.

Every file the engine reads is untrusted input — a store directory or a dump arrives from wherever an operator copied it — so all three are gated here, and the gate is the tightest one there is:

A vaelii frame never carries a class name.

That is already the export format's stated rule (vaelii.impl.io.export), and the disk codec writes a record's fields positionally for a size reason (vaelii.impl.disk.codec), so nothing the engine writes states a class either. A frame that names one therefore came from somewhere else, and allowed-classes is empty: the name is refused (:disallowed-class) before the class is resolved.

The Serializable allowlist is pinned rather than inherited. nippy's default is a safe set, but it lives in a dynamic var an embedding application is invited to widen — nippy documents allow-and-record-any-serializable-class-unsafe for exactly that migration — and a host that widened it would widen the engine's file readers with it. Binding it per read makes the door this namespace's rather than the host's.

How the first two are gated, since nippy exposes no hook for them: the readers taoensso.nippy.io dispatches to are vars, and this namespace installs a checked reader in place of each. A refusal is thrown from there, which is before nippy's own try — so it travels rather than becoming the {:nippy/unthawable …} placeholder a failed resolution otherwise reads as, and no class is loaded on the way. The replacement calls straight through to the reader it replaced unless with-guard is in force, so a host application thawing its own records in this JVM is unaffected.

The class-name door on every nippy thaw the engine runs over a file.

A frozen nippy value can **name a class** in three of its type ids, and reading one
resolves that name and builds an instance of it: a record frame (`Class/forName`, then
the static `create`), a deftype frame (`Class/forName`, then the first public
constructor over the fields that follow), and a `Serializable` frame (an
`ObjectInputStream` over the bytes that follow).  nippy 3.8.1 gates the third behind
`*thaw-serializable-allowlist*` and the first two behind nothing at all.

Every file the engine reads is **untrusted input** — a store directory or a dump
arrives from wherever an operator copied it — so all three are gated here, and the
gate is the tightest one there is:

> **A vaelii frame never carries a class name.**

That is already the export format's stated rule (`vaelii.impl.io.export`), and the
disk codec writes a record's fields **positionally** for a size reason
(`vaelii.impl.disk.codec`), so nothing the engine writes states a class either.  A
frame that names one therefore came from somewhere else, and `allowed-classes` is
empty: the name is refused (`:disallowed-class`) before the class is resolved.

**The `Serializable` allowlist is pinned rather than inherited.**  nippy's default is
a safe set, but it lives in a dynamic var an embedding application is invited to
widen — nippy documents `allow-and-record-any-serializable-class-unsafe` for exactly
that migration — and a host that widened it would widen the engine's file readers with
it.  Binding it per read makes the door this namespace's rather than the host's.

**How the first two are gated**, since nippy exposes no hook for them: the readers
`taoensso.nippy.io` dispatches to are vars, and this namespace installs a checked
reader in place of each.  A refusal is thrown from there, which is *before* nippy's own
`try` — so it travels rather than becoming the `{:nippy/unthawable …}` placeholder a
failed resolution otherwise reads as, and no class is loaded on the way.  The
replacement calls straight through to the reader it replaced unless `with-guard` is in
force, so a host application thawing its own records in this JVM is unaffected.
raw docstring

*guarding*clj

Is a thaw inside with-guard? The checked readers below stand in for nippy's own process-wide, so this is what keeps the gate the engine's own: false — a host application's thaw — calls straight through.

Is a thaw inside `with-guard`?  The checked readers below stand in for nippy's own
process-wide, so this is what keeps the gate the engine's own: false — a host
application's thaw — calls straight through.
sourceraw docstring

allowed-classesclj

The class names a file the engine wrote may state — none.

Measured rather than asserted: a store built on each of the four durable backends and a dump written in each variant and codec drive nippy's three class-name readers zero times. A dump frame is a field map, a log frame is a positional vector, and every leaf a sentence may carry is a type nippy has an id for (vaelii.impl.checks' check-encodable refuses the rest at the front door). So the allowlist is empty, and a name is a name this engine did not write.

A set rather than false because the refusal names the class either way, and because a format that one day carried one would add it here and nowhere else.

The class names a file the engine wrote may state — **none**.

Measured rather than asserted: a store built on each of the four durable backends and
a dump written in each variant and codec drive nippy's three class-name readers zero
times.  A dump frame is a field map, a log frame is a positional vector, and every
leaf a sentence may carry is a type nippy has an id for (`vaelii.impl.checks`'
`check-encodable` refuses the rest at the front door).  So the allowlist is empty, and
a name is a name this engine did not write.

A set rather than `false` because the refusal names the class either way, and because
a format that one day carried one would add it here and nowhere else.
sourceraw docstring

guardedclj

(guarded f)

Run f — a thunk that thaws — behind the door, raising a :disallowed-class refusal as itself rather than as whatever wrapped it.

The entry point for a caller reading many frames off one stream (vaelii.impl.io.frames): the door is opened once for the run instead of once per frame, which is one binding frame for ten thousand of them.

Run `f` — a thunk that thaws — behind the door, raising a `:disallowed-class` refusal
as itself rather than as whatever wrapped it.

The entry point for a caller reading **many** frames off one stream
(`vaelii.impl.io.frames`): the door is opened once for the run instead of once per
frame, which is one binding frame for ten thousand of them.
sourceraw docstring

thawclj

(thaw bs)

nippy/thaw of bs behind the door.

`nippy/thaw` of `bs` behind the door.
sourceraw docstring

thaw-from-in!clj

(thaw-from-in! in)

nippy/thaw-from-in! from in behind the door.

`nippy/thaw-from-in!` from `in` behind the door.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close