Skip to content

fix(reliability): bound converter MIME metadata before payload reads #369

Description

@seonghobae

Current authoritative state

Protected shipped truth remains exact main@3b38ead2d00f44eb578d0689087b9293b3dabe1e. The canonical converter writer is active Draft #160 on fix/blob-size-preflight-20260811, current exact head 42b3a5004ec1b93181cd1ae52227b0fac2506227. This repair is not protected-main shipped behavior until #160 integrates under live governance.

The framework-neutral converter now applies one local MIME-metadata resource ceiling consistently across its input surfaces:

  • platform Blob.type: at most 1,024 UTF-16 code units, read through the intrinsic getter after genuine Blob-slot validation and before payload reads;
  • explicit EncodeOptions.mimeType: at most 1,024 UTF-16 code units through descriptor-safe runtime option handling;
  • declared data-URI MIME metadata: at most 1,024 UTF-16 code units, rejected by parseDataUri() before base64 or percent payload decoding.

The exact 1,024 boundary remains accepted. An omitted data-URI media type retains the existing text/plain default. A non-empty valid explicit MIME override retains precedence over platform Blob metadata.

The same canonical lane obtains Blob size through the intrinsic platform getter, reads Blob bytes through a Blob.prototype.arrayBuffer method captured at module evaluation, classifies ArrayBuffer views through a captured ArrayBuffer.isView, captures the TextDecoder instance plus intrinsic decode method used for bounded SVG/XML sniffing, and captures Node Buffer.from authority through a declaration-portable structural helper. Caller/host replacement of those capabilities therefore cannot become converter payload or classification authority.

This remains Inkspan-local deterministic converter/resource policy. It adds no network, persistence, authorization, tenancy, credentials, model/provider, deployment, migration, retention, or durable-audit authority.

Executable contracts

src/converter/base64BlobTypeMetadata.test.ts machine-checks the Blob MIME boundary:

  • a genuine Blob whose platform type is 1,025 code units is rejected before Blob.prototype.arrayBuffer is reached;
  • the exact 1,024-code-unit platform boundary is accepted;
  • caller-overridden Blob type accessors are not evaluated; and
  • an explicit valid MIME override remains authoritative without consulting oversized platform metadata.

src/converter/base64DataUriMimeMetadata.test.ts machine-checks the declared data-URI boundary:

  • a 1,025-code-unit MIME declaration paired with malformed %GG is rejected for oversized MIME metadata before payload decoding;
  • the exact 1,024-code-unit declaration is accepted; and
  • an omitted declaration retains the text/plain default.

The canonical fallback regression corpus additionally proves that caller-owned arrayBuffer accessors are not evaluated, later replacement of Blob.prototype.arrayBuffer, ArrayBuffer.isView, global TextDecoder, or global/Buffer.from cannot substitute converter authority, and Node/browser base64 behavior stays deterministic.

Test-first lineage

Latest declared data-URI MIME resource-bound lineage:

  • test-only RED 5321c9dede813e88b7474b165a3ea8431fc34104, CI 32558481749, build/test job 96996286302, checked out that exact head and failed exactly because the oversized declaration reached payload decoding and raised malformed percent-encoding; the exact-boundary/default assertions passed;
  • narrow repair 42b3a5004ec1b93181cd1ae52227b0fac2506227 reuses MAX_MIME_TYPE_CODE_UNITS in parseDataUri() before payload handling.

Earlier classifier-authority, Blob-MIME, false-green coverage, and strict packed-consumer TypeScript RED→GREEN lineages remain historical behavior provenance only. No predecessor workflow/review evidence transfers to the current head.

Exact-current-head evidence

For unchanged exact head 42b3a5004ec1b93181cd1ae52227b0fac2506227 against protected main@3b38ead2d00f44eb578d0689087b9293b3dabe1e at the latest fresh observation:

  • CI 32558675130: completed / success;
  • build-and-test 96996743975: exact checkout, 163 test files / 912 tests, 100% statements / branches / functions / lines, including src/converter/base64.ts and the dedicated data-URI MIME regression corpus;
  • packed-package ESM/CommonJS/subpath/strict-TypeScript consumers, library build and demo build: completed / success;
  • Cross-engine Clipboard / Playwright 1.62.0: completed / success;
  • Office Python 3.11, 3.12, 3.13 and 3.14: completed / success;
  • Security Scan 32558675113: completed / success;
  • SAST Semgrep 32558675118: completed / success;
  • formal submitted reviews: 0;
  • unresolved inline review threads: 0;
  • GitHub reports fix(reliability): preflight converter payload allocations #160 mechanically mergeable and still Draft.

Repository exact-head technical success is not a substitute for separately applicable central required workflows, qualifying independent approval, or then-live organization governance. Pending, queued, skipped, cancelled, absent, stale, predecessor-only, status-only, model-only, or vacuous evidence remains non-passing.

Integration boundary

Keep this issue open until #160 integrates under then-live governance. Keep #160 Draft/unmerged while #118 owns the frozen protected v0.6.0 publication/provenance boundary and qualifying independent approval plus every then-applicable governance/workflow gate remain incomplete. Any #160 head/base/ruleset movement invalidates corresponding exact-head evidence and requires fresh revalidation. Do not create a competing converter writer, transfer predecessor evidence, self-approve, weaken gates, move protected main, or fabricate release identity.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: apiAPI, protocol, event, or external contractarea: authAuthentication, authorization, identity, or tenant isolationarea: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: securitySecurity boundary, hardening, or vulnerability preventionbugSomething isn't workingpriority: mediumNormal-priority or P2 workstatus: triagedOpen issue has an organization taxonomy assignmenttype: bugDefect or incorrect behavior

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions