Add test databases for empty map/array last in metadata#222
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces specialized test databases to validate the handling of empty data structures within the metadata section of MaxMind DB files. The primary goal is to ensure that the Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request adds two new test databases to reproduce a bug related to empty maps or arrays at the end of the metadata section. The changes are correct and achieve the goal. I've provided a couple of suggestions in pkg/writer/rawmmdb.go to refactor the newly added functions to reduce significant code duplication and improve maintainability. Otherwise, the changes look good.
These databases reproduce the off-by-one bug in libmaxminddb's get_entry_data_list() validation. When a 0-length map or array is the last field in metadata, offset_to_next equals data_section_size exactly, which the >= check incorrectly rejects. ENG-4322 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request adds two new test databases to address an off-by-one bug in get_entry_data_list() related to 0-length maps or arrays at the end of the metadata section. The changes include modifications to mise.toml, pkg/writer/baddata.go, and pkg/writer/rawmmdb.go, along with the addition of mise.lock. The review focuses on the correctness and maintainability of the added code, particularly the new database generation logic and metadata handling.
| if !ok { | ||
| panic("unknown metadata key: " + key) | ||
| } |
There was a problem hiding this comment.
Instead of panicking, return an error to allow the caller to handle the situation more gracefully.
valueWriter, ok := valueWriters[key]
if !ok {
return 0, fmt.Errorf("unknown metadata key: %s", key)
}
pos += writeMetaKey(buf[pos:], key)
bytesWritten := valueWriter(buf[pos:])
pos += bytesWritten
return pos, nilThere was a problem hiding this comment.
Given the scope of this project and that it is a programmer error, panicking seems fine.
Also, the other suggestions don't really seem appropriate for in-memory writers for test databases.
| {"libmaxminddb-empty-map-last-in-metadata.mmdb", buildEmptyMapLastInMetadataDB()}, | ||
| {"libmaxminddb-empty-array-last-in-metadata.mmdb", buildEmptyArrayLastInMetadataDB()}, |
There was a problem hiding this comment.
|
|
||
| pos += writeMetaKey(buf[pos:], "database_type") | ||
| pos += writeString(buf[pos:], "Test") | ||
| func buildSimpleDB(metadataWriter func([]byte, uint32, uint64) int) []byte { |
|
|
||
| pos += writeMetaKey(buf[pos:], "database_type") | ||
| pos += writeString(buf[pos:], "Test") | ||
| func buildSimpleDB(metadataWriter func([]byte, uint32, uint64) int) []byte { |
| func buildSimpleDB(metadataWriter func([]byte, uint32, uint64) int) []byte { | ||
| const nodeCount = 1 | ||
| const recordValue = nodeCount + 16 | ||
| const buildEpoch = 1_000_000_000 | ||
|
|
||
| pos += writeMetaKey(buf[pos:], "description") | ||
| pos += writeMap(buf[pos:], 0) | ||
| buf := make([]byte, 1024) | ||
| pos := 0 | ||
|
|
||
| pos += writeMetaKey(buf[pos:], "ip_version") | ||
| pos += writeUint16(buf[pos:], 4) | ||
| pos += writeSearchTree(buf[pos:], recordValue) | ||
|
|
||
| pos += writeMetaKey(buf[pos:], "languages") | ||
| pos += writeEmptyArray(buf[pos:]) | ||
| // 16-byte null separator | ||
| pos += dataSeparatorSize | ||
|
|
||
| pos += writeMetaKey(buf[pos:], "node_count") | ||
| pos += writeUint32(buf[pos:], nodeCount) | ||
| // Data: a simple map with one string entry | ||
| pos += writeMap(buf[pos:], 1) | ||
| pos += writeString(buf[pos:], "ip") | ||
| pos += writeString(buf[pos:], "test") | ||
|
|
||
| pos += writeMetaKey(buf[pos:], "record_size") | ||
| pos += writeUint16(buf[pos:], 24) | ||
| pos += metadataWriter(buf[pos:], nodeCount, buildEpoch) | ||
|
|
||
| return pos | ||
| return buf[:pos] |
|
|
||
| pos += writeMetaKey(buf[pos:], "database_type") | ||
| pos += writeString(buf[pos:], "Test") | ||
| func buildSimpleDB(metadataWriter func([]byte, uint32, uint64) int) []byte { |
|
LGTM. Tests are failing though. Claude said this about the failure: |
Summary
libmaxminddb-empty-map-last-in-metadata.mmdbandlibmaxminddb-empty-array-last-in-metadata.mmdbget_entry_data_list()where a 0-length map or array at the end of the metadata section is incorrectly rejectedContext
ENG-4322. Reported via vimt/MaxMind-DB-Writer-python#16.
🤖 Generated with Claude Code