Skip to content

Misc cleanup#203

Merged
oschwald merged 18 commits intomainfrom
greg/cleanups
Feb 10, 2026
Merged

Misc cleanup#203
oschwald merged 18 commits intomainfrom
greg/cleanups

Conversation

@oschwald
Copy link
Owner

@oschwald oschwald commented Feb 8, 2026

  • Simplify resolveDataPointer error path
  • Consolidate reflection error context wrapping
  • Return errors for invalid maxminddb struct tags
  • Remove unused decoder errorContext scaffolding
  • Remove unused Decoder options state field
  • Simplify maxminddb struct tag validation flow
  • Clean up test-only debug paths
  • Guard verifier separator reads with bounds checks
  • Fix mmdbdata.NewDecoder error-context documentation
  • Inline NewDecoder return construction
  • Preserve prefix construction errors in NetworksWithin
  • Trim unused PathBuilder mutation methods
  • Clarify and verify option hook behavior

Summary by CodeRabbit

  • Bug Fixes

    • Invalid (non-UTF‑8) struct tags now produce an error instead of being ignored.
    • Prevented out-of-bounds errors when reading malformed database files.
    • Improved handling of pointer-related decoding errors to avoid unclear failures.
  • Improvements

    • Error messages now consistently include contextual offset/path information.
    • Changelog updated to reflect stricter tag validation behavior.

@coderabbitai
Copy link

coderabbitai bot commented Feb 8, 2026

Walkthrough

Refactors decoder error handling to use PathBuilder-based wrapping and Prepend* APIs, adds UTF-8 validation for struct tags that causes decode to error, introduces ReaderOption for reader configuration, and tightens bounds checks in verifier and pointer decoding constants.

Changes

Cohort / File(s) Summary
Changelog & docs
CHANGELOG.md, mmdbdata/type.go
Adds 2.2.0 changelog entry about tag validation; simplifies NewDecoder doc comment to mention offset context only.
Decoder core & tests
internal/decoder/decoder.go, internal/decoder/decoder_test.go, internal/decoder/error_context.go, internal/decoder/error_context_test.go, internal/decoder/reflection.go, internal/decoder/tag_validation_test.go, internal/decoder/data_decoder.go
Removes stored decoder options; introduces Decoder.wrapError / wrapErrorAtOffset and consolidated wrapErrorWithPath; replaces errorContext usage with PathBuilder-based wrapping and Prepend* APIs; adds UTF-8 struct-tag validation propagated via fields.validationErr; introduces pointerBase2/3 constants; updates and extends related tests.
PathBuilder / mmdberrors
internal/mmdberrors/context.go
Removes mutable PathBuilder methods (PushMap, PushSlice, Pop, Reset); retains PrependMap/PrependSlice, Build, ParseAndExtend and BuildPath semantics.
Reader & tests
reader.go, reader_test.go
Adds public ReaderOption type and options plumbing to Open/OpenBytes; test ensures options callback is applied even when OpenBytes errors.
Verifier & tests
verifier.go, verifier_test.go
Adds explicit end-bound computation/validation for data section separator and corresponding unit test for out-of-bounds handling.
Traversal error wrapping
traverse.go
Changes error formatting to wrap underlying error with %w when prefixing fails.
Misc / small updates
reader.go (resolveDataPointer flow)
Reorders pointer bound checks in resolveDataPointer for clearer error paths; behavior for valid inputs preserved.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I nibble bytes and hop on paths so neat,
I prepend steps where errors meet,
I check each tag for UTF-8 light,
Tighten bounds and point pointers right,
A little rabbit, keeping decode sweet. 🌿

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 34.62% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title "Misc cleanup" is vague and generic, using non-descriptive terminology that fails to convey meaningful information about the substantive changes in the changeset. Replace with a more descriptive title that captures the primary change, such as "Refactor error handling and remove unused decoder state" or "Add validation for maxminddb struct tags and consolidate error context wrapping".
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch greg/cleanups

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@internal/decoder/reflection.go`:
- Around line 950-959: The current check uses utf8.ValidString on the entire
rawTag which can misattribute invalid UTF-8 from unrelated struct tags to the
maxminddb tag; modify the logic so you either remove the rawTag utf8 check
entirely (since validateTag(field, tag) already verifies the extracted value)
or, if you want an explicit pre-check, extract the maxminddb tag first via
field.Tag.Get("maxminddb") and run utf8.ValidString only on that extracted tag
string before calling validateTag; update the conditional that sets
validationErr (current use of rawTag and validationErr) to reference the
extracted tag value or remove it and rely on validateTag.

In `@verifier_test.go`:
- Around line 75-79: Inside the require.NotPanics callback in the test that
calls v.verifyDataSectionSeparator(), replace the inner require.Error call with
assert.Error (and keep assert.ErrorContains) so no require (which calls
t.FailNow/Goexit) runs inside the NotPanics closure; update the assertion on the
error returned from v.verifyDataSectionSeparator() to use assert.Error(t, err)
and keep assert.ErrorContains(t, err, "unexpected end of database") to avoid
interfering with testify's recover handling.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@internal/decoder/reflection.go`:
- Around line 1054-1073: Add a brief clarifying comment near the call site of
validateRawMaxMindDBTagValue (around the validateTag usage) explaining that
validateRawMaxMindDBTagValue manually parses the raw struct tag to catch invalid
UTF-8 cases that reflect.StructTag.Get may miss, and that this raw parsing is a
defensive, layered validation used alongside validateTag (which handles the
common/normalized case); mention both function names
(validateRawMaxMindDBTagValue and validateTag) so future readers understand the
ordering and purpose of the two checks.

Comment on lines +1054 to +1073
func validateRawMaxMindDBTagValue(field reflect.StructField, rawTag string) error {
const key = `maxminddb:"`

start := strings.Index(rawTag, key)
if start == -1 {
return nil
}

start += len(key)
end := strings.IndexByte(rawTag[start:], '"')
if end == -1 {
return nil
}

if !utf8.ValidString(rawTag[start : start+end]) {
return invalidMaxMindDBTagError(field.Name)
}

return nil
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

validateRawMaxMindDBTagValue manually parses the raw tag — consider documenting why this is needed alongside validateTag.

This function addresses the edge case where reflect.StructTag.Get() may not correctly extract a tag value containing invalid UTF-8. The manual parsing provides defense-in-depth, but the relationship between this function and validateTag (lines 850–860) isn't immediately obvious to a reader.

A brief comment on lines 951–956 explaining the layered validation (raw parse for robustness + Tag.Get for the common case) would improve maintainability.

🤖 Prompt for AI Agents
In `@internal/decoder/reflection.go` around lines 1054 - 1073, Add a brief
clarifying comment near the call site of validateRawMaxMindDBTagValue (around
the validateTag usage) explaining that validateRawMaxMindDBTagValue manually
parses the raw struct tag to catch invalid UTF-8 cases that
reflect.StructTag.Get may miss, and that this raw parsing is a defensive,
layered validation used alongside validateTag (which handles the
common/normalized case); mention both function names
(validateRawMaxMindDBTagValue and validateTag) so future readers understand the
ordering and purpose of the two checks.

@oschwald oschwald merged commit 517adc2 into main Feb 10, 2026
18 checks passed
@oschwald oschwald deleted the greg/cleanups branch February 10, 2026 03:56
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