Skip to content

Fix reader error handling, strengthen tests, rewrite README - #23

Merged
dimchansky merged 4 commits into
masterfrom
fix/reader-errors
Oct 21, 2026
Merged

dimchansky merged 4 commits into
masterfrom
fix/reader-errors

Conversation

@dimchansky

Copy link
Copy Markdown
Owner

Prepares the next release: two reader-error fixes, stronger tests, a rewritten README and a non-mutating make check. Exported API, String() names and performance are unchanged.

Fixes (both present since v1.1.1)

  • Error lost after empty reads. A read that returned an error was counted as an empty read, so a source that returned io.EOF or a real error after 99 (0, nil) reads got io.ErrNoProgress instead. Only (0, nil) now counts.
  • Timing-dependent UTF-16 detection. FE FF 00 41 returned together with a non-EOF error was Unknown (BOM kept), but the same bytes with the error on the next Read were UTF16BigEndian. With 4 bytes read, UTF-32 is already ruled out, so UTF-16 is now detected in both cases. The historical 2–3-byte FE FF/FF FE + non-EOF error case still yields Unknown.

A differential run of old vs new detection over ~5.7M read schedules found differences only in these two cases.

Tests

  • Regression tests for both fixes (they fail without the fix).
  • Exact Encoding.String() names; Skip on a *Reader returns the same reader; 1–4 byte destination buffers.
  • FuzzSkip against an independent BOM table (EOF-terminated streams, whole and one-byte reads).
  • Benchmarks. benchstat before/after (Go 1.27.1, Apple M1 Max, count=10): no change in time, 68 B/op and 2 allocs/op both.

Docs and tooling

  • README rewritten: purpose and boundaries, Go 1.19+, one complete example, BOM table, Behavior section, pkg.go.dev badge.
  • Go doc comments fixed (Encoding is a defined type; Read does not search for a BOM on each call).
  • Examples print readable output; ExampleSkip_utf16 shows the payload is not transcoded. The QF1010 lint exclusion is no longer needed.
  • make check only checks; make task runs fix, fmt, then check sequentially.

Verified locally on Go 1.27.1 and 1.19.13: vet, race + shuffle tests, golangci-lint v2.15.0, 30 s fuzz, README example compiled and run.

- readBOM counted a read that returned an error as an empty read, so a
  source that returned io.EOF or a real error after 99 empty reads got
  io.ErrNoProgress instead. Only (0, nil) now counts as no progress.
- detectUtf gave up on UTF-16 whenever probing ended with a non-EOF
  error, even with all 4 probe bytes read. FE FF 00 41 returned together
  with an error was Unknown, but the same bytes followed by the error on
  the next Read were UTF16BigEndian. With 4 bytes read, UTF-32 has
  already been ruled out, so UTF-16 is now detected in both cases.

Both bugs date back to v1.1.1. A 2-3 byte FE FF / FF FE prefix followed
by a non-EOF error intentionally still yields Unknown, as before.
- Encoding.String: check exact names, including out-of-range values.
- Skip on a *Reader returns the same reader.
- Reads with 1-4 byte destination buffers.
- FuzzSkip: BOM detection and payload preservation against an
  independent BOM table, with whole and one-byte source reads.
- Benchmarks for small inputs with and without BOM and a 64KB copy.
- README: purpose and boundaries, minimum Go version, one complete
  example, BOM table, Behavior section, pkg.go.dev badge.
- Encoding is a defined type, not a type alias; Read does not search
  for a BOM on every call; Reader is created by Skip/SkipOnly and does
  not close the source.
- Examples print readable output; new ExampleSkip_utf16 shows that the
  payload is not transcoded.
- The QF1010 lint exclusion is no longer needed.
check runs vet, lint and race tests without touching files. task runs
fix and fmt first, then check, so make -j cannot race edits against
checks. Targets cover ./... and are all .PHONY.
@dimchansky
dimchansky enabled auto-merge October 21, 2026 17:10
@dimchansky
dimchansky merged commit f384a2e into master Oct 21, 2026
5 checks passed
@dimchansky
dimchansky deleted the fix/reader-errors branch October 21, 2026 17:19
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