Skip to content

fix(core): escapeDkgRdfLiteral covers only ECHAR; non-ECHAR ASCII controls leak through #416

Description

@Jurij89

Summary

The canonical RDF literal escaper at packages/core/src/publisher-extension.ts:252 only covers the seven ECHAR characters: backslash, double-quote, newline (LF), carriage-return, tab, form-feed, backspace. Other ASCII control bytes — NUL (0x00), VT (0x0B), DEL (0x7F), plus 0x01-0x07 and 0x0E-0x1F — are left raw in the output, which produces invalid N-Triples literals at the storage layer.

This was discovered during Codex review on PR #413 (the OpenClaw dkg_share addition). The OpenClaw handler now wraps the call with a defensive UCHAR-encoding post-pass, but every other consumer of escapeDkgRdfLiteral and normalizeDkgPublisherObject has the same gap. Fixing it in core eliminates the per-call-site workaround.

Proposed fix

Extend the helper to UCHAR-encode every ASCII control byte that isn't already covered by an ECHAR shortcut. Sketch:

escapeDkgRdfLiteral(value):
  // Step 1: escape backslash and double-quote first (ECHARs introducing the escape char).
  // Step 2: replace each remaining control byte 0x00-0x1F or 0x7F:
  //   - 0x08 -> \b
  //   - 0x09 -> \t
  //   - 0x0A -> \n
  //   - 0x0C -> \f
  //   - 0x0D -> \r
  //   - any other -> \uXXXX (uppercase hex, 4 digits)

Order matters: the backslash/quote replacements run first so the UCHAR escape sequences (which start with backslash) don't get themselves escaped a second time.

Acceptance criteria

  • Input containing a NUL byte (0x00) produces output with the 6-char sequence: backslash, u, 0, 0, 0, 0.
  • Input containing VT (0x0B) produces backslash, u, 0, 0, 0, B.
  • Input containing DEL (0x7F) produces backslash, u, 0, 0, 7, F.
  • Existing ECHAR coverage unchanged (\b, \t, \n, \f, \r, \\, \" still produce the canonical short forms).
  • Tests added in packages/core/test/publisher-extension.test.ts (or wherever the helper is exercised) covering at least the three non-ECHAR cases above plus a mixed-content round-trip.
  • No existing call site that relies on the helper changes behavior — only previously-broken inputs (raw control bytes) now produce well-formed output.

Out of scope

  • Removing the per-call-site UCHAR workaround in packages/adapter-openclaw/src/DkgNodePlugin.ts handleShare once this lands. Should be done as a small follow-up after this fix merges so the workaround can lean on the canonical helper without redundant work.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    pre-mainnetMust land before mainnet launchpriority:mediumReal defect or gap; fix planned but not release-gating on its own

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions