Skip to content

fix(parser): strip leading UTF-8 BOM before JSON.parse#40

Open
dmchaledev wants to merge 1 commit into
mainfrom
claude/magical-ptolemy-3wuham
Open

fix(parser): strip leading UTF-8 BOM before JSON.parse#40
dmchaledev wants to merge 1 commit into
mainfrom
claude/magical-ptolemy-3wuham

Conversation

@dmchaledev

Copy link
Copy Markdown
Contributor

Summary

SBOM files exported by some generators and by Windows text tooling carry a leading UTF-8 byte order mark (U+FEFF, bytes EF BB BF). Such files are perfectly valid on disk, but parse() (src/parser.ts) passes the raw string straight to JSON.parse, which throws a cryptic error:

Unexpected token '', "{"bomForm"... is not valid JSON

For a tool whose core operation is diffing SBOM files, this means an entire class of real-world inputs is undiffable and the CLI hard-crashes on the happy path. The error message doesn't even hint that a BOM is the cause.

This is orthogonal to the other in-flight PRs/issues — none touch pre-JSON.parse input handling. It is distinct from #21 (which is about wrong-format JSON): a BOM-prefixed SBOM is a valid SBOM that the tool rejects.

Reproduction (before this change)

import { parse } from '@hailbytes/sbom-diff';
const withBom = '' + JSON.stringify({ bomFormat: 'CycloneDX', components: [] });
parse(withBom); // throws: Unexpected token '', ... is not valid JSON
$ sbom-diff old.json new.json   # files saved with a UTF-8 BOM
Unexpected token '', "{"bomForm"... is not valid JSON
exit code: 1

Change

In the string-input path of parse(), strip a single leading BOM before parsing:

const obj: Record<string, unknown> =
  typeof input === 'string' ? JSON.parse(input.replace(/^/, '')) : input;
  • Only a BOM at the very start of the input is removed; BOMs appearing inside string values are preserved verbatim.
  • Object input is unaffected (no string to strip).
  • No new dependencies; behavior for BOM-free input is unchanged.

Tests

Added to src/__tests__/parser.test.ts:

  • A BOM-prefixed CycloneDX string parses successfully (format/components intact).
  • A BOM inside a string value is not stripped (guards against over-eager replacement).

Verification

  • npm test → 31 passing (2 new)
  • npm run lint → clean
  • npm run typecheck → clean
  • End-to-end: built the package and ran node dist/cli.js old.json new.json against two real BOM-prefixed (EF BB BF) CycloneDX files — previously crashed, now produces a normal diff report.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WeWeVvWTVLxzex3YDXuF7p


Generated by Claude Code

SBOM files exported by some generators and Windows text tooling carry a
leading UTF-8 byte order mark (U+FEFF). Such files are valid on disk, but
parse() passed them straight to JSON.parse, which throws a cryptic
"Unexpected token" error — making otherwise-valid SBOMs undiffable and the
CLI crash on the tool's core operation.

Strip a single leading BOM in the string-input path before parsing. Only a
BOM at the very start is removed; BOMs inside string values are preserved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WeWeVvWTVLxzex3YDXuF7p
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants