Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v0 source pure

Package foreign provides the realm-side helper for emitting the gno-foreign sandbox block. Realm authors wrap externa...

Overview

Package foreign provides the realm-side helper for emitting the gno-foreign sandbox block. Realm authors wrap externally-built markdown (markdown returned by an interface method on a foreign realm, fetched from chain storage owned by another realm, etc.) in Foreign before flowing it into rendered output, so gnoweb renders the body inside its own goldmark sub-instance with structural extensions selectively loaded.

The renderer-side contract lives in gno.land/pkg/gnoweb/markdown/ext_foreign.go. This helper produces bytes that satisfy the parser's opener requirements (CommonMark §4.6 Type-7 HTML block, no attribute fall-through) and neutralizes any literal sentinel lines in the body so the foreign markdown cannot terminate the outer block prematurely.

Functions 3

func Foreign

1func Foreign(body string) string
source

Foreign wraps body in a `<gno-foreign>` ... `</gno-foreign>` sandbox block. The returned string is ready to concatenate into a larger markdown document.

Three normalization steps apply to body:

  1. \r\n and bare \r line endings are normalized to \n. The parser uses byte-equal matching against the sentinel close tag, so mixed line endings would otherwise change the match boundary.

  2. Any line whose trimmed content looks like a gno-foreign tag opener OR closer — bare (`<gno-foreign>`, `</gno-foreign>`) or attribute-bearing (`<gno-foreign label="x">`, `</gno-foreign attr="…">`, etc.) — is neutralized by HTML-escaping the leading `<` to `<`. The parser tokenizes line bytes literally, so the escaped form is seen as text and cannot terminate the outer block or open an unintended inner block.

    Crucially, BOTH open-tag and close-tag attribute-bearing forms are neutralized. The parser recognizes a bare `<gno-foreign>` opener, a labeled `<gno-foreign label="x">` opener, and ANY `</gno-foreign…>` closer (golang.org/x/net/html drops attrs on end tags before our recognizer sees them, so attr-bearing closers are sentinel-equivalent). Leaving any of those forms un-neutralized in body bytes would let attacker-supplied markdown adjust the parser's framing-depth counter and either consume the helper's own close (capturing trailing realm content into the sandbox) or close the outer block early (escaping the sandbox entirely).

    There is therefore NO nesting via the helper: Foreign(Foreign(x)) escapes the inner call's own `<gno-foreign>`/`</gno-foreign>` lines, so the inner block renders as visible literal text inside one sandbox, not as a nested sandbox. This is intended — wrapping foreign-built markdown that itself contains gno-foreign sentinels must neutralize them, not honor them.

  3. A leading and trailing blank line are emitted around the opener / closer. CommonMark §4.6 forbids Type-7 HTML blocks from interrupting a paragraph; without the blank line, an opener following a non-blank line is absorbed into the preceding paragraph instead of opening a sandbox.

The renderer caps cross-family nesting at 4 levels and per-Convert foreign blocks at 256. Beyond those caps, the opener falls through to raw HTML and is stripped by the renderer's safe mode.

func ForeignWithLabel

1func ForeignWithLabel(label, body string) string
source

ForeignWithLabel wraps body like Foreign but emits an explicit `label="…"` attribute on the opener so the rendered sandbox carries a caller-supplied label (e.g., "Pulled from /r/foo") shown as a strip above the body. The label is sanitized so it cannot inject HTML or break out of the attribute value:

  • NUL bytes are dropped.
  • Other control characters (U+0000–U+001F, U+007F) become spaces.
  • `&`, `<`, `>`, and `"` are replaced with their HTML entities.
  • Leading/trailing whitespace is trimmed.

A label that is empty after sanitization behaves identically to Foreign: no attribute is emitted, and the renderer shows the sandbox box with NO label strip (there is no default label text).

func MaxBlocksPerRender

1func MaxBlocksPerRender() int
source

MaxBlocksPerRender is gnoweb's per-render cap on the number of <gno-foreign> blocks a single page render admits; beyond it, later blocks fall through to raw HTML and are dropped. A realm emitting many foreign blocks (e.g. one per comment) should keep its rendered total under this. Re-exports chain/markdown.MaxForeignBlocksPerConvert — the single source of truth the gnoweb renderer also reads — so callers get the cap without importing chain/markdown directly.

Imports 2

  • chain/markdown stdlib
  • strings stdlib

Source Files 3