Skip to content

fix(fetcher): nil-safe charset lookup#1276

Open
SAY-5 wants to merge 2 commits into
floatpane:masterfrom
SAY-5:fix/fetcher-encoding-nil-fallback
Open

fix(fetcher): nil-safe charset lookup#1276
SAY-5 wants to merge 2 commits into
floatpane:masterfrom
SAY-5:fix/fetcher-encoding-nil-fallback

Conversation

@SAY-5
Copy link
Copy Markdown
Contributor

@SAY-5 SAY-5 commented May 11, 2026

Fixes #896.

What?

decodeReaderWithCharset and decodeHeader's CharsetReader in fetcher/fetcher.go could nil-deref because ianaindex.IANA.Encoding is allowed to return (nil, nil) for charset names it recognizes but has no implementation for. The previous code chained .NewDecoder() on that nil encoding.

Refactor: introduce lookupCharsetEncoding that always returns a non-nil encoding.Encoding by trying the requested charset, then ianaindex's "utf-8", then encoding/unicode.UTF8 as final guarantee. Use it from decodeReaderWithCharset. Guard the decodeHeader path explicitly so the nil-after-success case surfaces as a clean error.

Why?

Without the guard, a real message with an unusual charset header can panic the fetcher. The fix is minimal, has no behavior change for the common path (a valid charset still resolves the same way), and is covered by two new tests:

  • TestDecodeReaderWithCharsetSurvivesUnknownCharset (issue regression)
  • TestLookupCharsetEncodingAlwaysReturnsNonNil (table-driven contract)

go test ./fetcher/... passes locally; go vet ./fetcher/... clean; gofmt clean.

decodeReaderWithCharset called ianaindex.IANA.Encoding(charset) and on
failure fell back to ianaindex.IANA.Encoding("utf-8") while discarding
the second error. The library can return (nil, nil) for charset names
it recognizes but has no implementation for, so encoding could be nil
when we chained .NewDecoder(), panicking.

Extract a lookupCharsetEncoding helper that tries the requested charset,
falls back to utf-8 via ianaindex, and ultimately falls back to
encoding/unicode.UTF8 so it always returns a non-nil encoding.

decodeHeader's CharsetReader had the same nil-after-success edge case;
guard it explicitly with a clear error message.

Regression tests cover an unknown charset and the helper's contract.

Signed-off-by: say <say.apm35@gmail.com>
@SAY-5 SAY-5 requested a review from a team as a code owner May 11, 2026 23:20
Copy link
Copy Markdown
Member

@floatpanebot floatpanebot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @SAY-5! Please fix the following issues with your PR:

  • Title: Is too long (64 characters). The PR title must be strictly under 40 characters.
  • Body: Missing the ## What? or ## Why? headings required by the PR template.

@floatpanebot floatpanebot added size/M Diff: 51–200 lines area/fetcher IMAP fetch / IDLE / search bug Something isn't working labels May 11, 2026
Copy link
Copy Markdown
Member

@floatpanebot floatpanebot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @SAY-5! Please fix the following issues with your PR:

  • Title: Is too long (64 characters). The PR title must be strictly under 40 characters.

@floatpanebot floatpanebot added the chore Maintenance, refactor, cleanup label May 11, 2026
@SAY-5 SAY-5 changed the title fix(fetcher): avoid nil-deref when ianaindex returns no encoding fix(fetcher): nil-safe charset lookup May 11, 2026
@floatpanebot floatpanebot dismissed stale reviews from themself May 11, 2026 23:23

Formatting issues have been resolved. Thank you!

@floatpanebot floatpanebot added the size/S Diff: 11–50 lines label May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/fetcher IMAP fetch / IDLE / search bug Something isn't working chore Maintenance, refactor, cleanup size/M Diff: 51–200 lines size/S Diff: 11–50 lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: IANA encoding lookup error ignored for charset fallback

2 participants