Skip to content

fix: well-formed Write after Parse, trimmed ids, overflow-safe subject numbers, regexps compiled once - #2

Open
go-while wants to merge 1 commit into
javi11:mainfrom
go-while:review-fixes
Open

go-while wants to merge 1 commit into
javi11:mainfrom
go-while:review-fixes

Conversation

@go-while

Copy link
Copy Markdown

Found these while switching NZBreX from Tensai75/nzbparser to this fork. One commit; each fix has a test in review_test.go (five of the six fail on main).

Fixes

  • Write after Parse produced malformed XML. Segment IDs were read as raw inner XML, unescaped with html.UnescapeString, then written back raw, so an ID like part1&x@host came out as part1&x@host inside the element. IDs and meta values are now read as XML character data (xml:",chardata"), which decodes the standard entities the same way, and Write escapes them. The existing TestSegmentIDUnescaping still passes unchanged. MakeUnique now compares the decoded IDs.
  • Whitespace of pretty-printed NZBs. <segment …>\n id@host\n</segment> gave an ID with the newlines and spaces. IDs, groups and meta values are trimmed.
  • Overflowing subject numbers. (1/99999999999999999999) made strconv.Atoi return the largest int, which ScanNzbFile summed into TotalSegments; a caller sizing a slice by it panics. Such numbers now count as missing, so the real segments decide.
  • Basefilename was never set since the subject parser moved into this package.
  • Write round trips. The comment gained two spaces per Parse → Write cycle (" hi " → " hi "), and meta came out in map order. The comment is trimmed on parse; meta is written sorted by type, so the output is the same every time.
  • Stable sort. sort.Sort doesn't keep the order of equal elements; files without a number in the subject all have number 1. Now sort.Stable for files and segments.
  • ParseSubject compiled ~11 regexps per call. They're package-level now: ~81 µs → ~28 µs and 249 → 22 allocations per subject (BenchmarkParseSubject).
  • Parse wraps the XML error with %w.

Not changed: several meta entries of the same type (e.g. two category) still collapse into one in the Meta map; fixing that would change the API.

Checks: go test -race ./..., go vet, staticcheck (v0.8.2) are clean. go tool golangci-lint run (v2.1.6 from go.mod) can't load packages built by newer toolchains (Go 1.27 here: "export data version 5 is greater than maximum supported version 2"), the same on main, so I couldn't run it.

🤖 Generated with Claude Code

…ers, compile regexps once

- Segment ids and meta values are read as XML character data and trimmed,
  instead of raw inner XML plus html.UnescapeString. Write marshalled the
  unescaped ids raw, so a parsed NZB with "&" in an id was written as
  malformed XML; pretty-printed NZBs kept newlines around ids. Dedupe
  (MakeUnique) now compares decoded ids. Groups are trimmed too.
- A subject number too big for an int counts as missing (0): strconv.Atoi
  returned the largest int, which ScanNzbFile summed into TotalSegments.
- Basefilename is set again (it was never assigned since the subject
  parser moved in).
- The comment is trimmed on Parse, so Write's padding no longer grows it on
  every round trip; Write emits meta in a fixed (sorted) order.
- Files and segments are sorted with sort.Stable: files without a number
  in the subject keep the NZB's order.
- ParseSubject's regexps are compiled once: ~81 -> ~28 us and
  249 -> 22 allocations per subject.
- Parse wraps the XML error (%w).

Tests for each of these (five fail on main).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
go-while added a commit to go-while/NZBreX that referenced this pull request Oct 18, 2026
- github.com/go-while/go-yenc-simd is on GitHub: required at 50d56c3
  (pseudo-version), the replace to ../go-yenc-simd is gone
- github.com/javi11/nzbparser is replaced by the pushed review-fixes
  branch of github.com/go-while/nzbparser (7c20501, open as
  javi11/nzbparser#2) instead of ../nzbparser

A fresh clone builds without sibling checkouts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant