From cc23dcf3387c776b16f81312aacac1c239fb9b24 Mon Sep 17 00:00:00 2001 From: Taotao Date: Tue, 3 Mar 2026 21:56:29 +0800 Subject: [PATCH] fix: compatibility with libmaxminddb v1.13.x stricter validation libmaxminddb v1.13.0 added validation in get_entry_data_list() that checks `offset >= data_section_size` for MAP/ARRAY types. When the metadata section ends with an empty map (e.g. empty `description`), offset_to_next equals metadata_section_size, triggering this check and causing MMDB_open to fail with MMDB_INVALID_DATA_ERROR. Fix: reorder metadata fields so `build_epoch` (a scalar UINT64 not subject to the MAP/ARRAY validation) is the last entry, ensuring `description` and `languages` are never at the tail of the metadata. Fixes #16 Made-with: Cursor --- mmdb_writer.py | 2 +- tests/test_api.py | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mmdb_writer.py b/mmdb_writer.py index c486e0a..1730e80 100644 --- a/mmdb_writer.py +++ b/mmdb_writer.py @@ -686,6 +686,6 @@ def _build_meta(self): "languages": self.languages, "binary_format_major_version": self.binary_format_major_version, "binary_format_minor_version": self.binary_format_minor_version, - "build_epoch": int(time.time()), "description": self.description, + "build_epoch": int(time.time()), } diff --git a/tests/test_api.py b/tests/test_api.py index 1f40ab3..d78b321 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -68,6 +68,33 @@ def test_insert_subnet(self): self.assertEqual(record2, m.get("1.10.10.1"), mode) m.close() + def test_empty_description(self): + """Regression test for https://github.com/vimt/MaxMind-DB-Writer-python/issues/16 + libmaxminddb v1.13.x added stricter validation that rejects files where an + empty map/array is the last element in the metadata section. + """ + writer = MMDBWriter() + writer.insert_network( + IPSet(["1.1.0.0/24", "1.1.1.0/24"]), + {"country": "COUNTRY", "isp": "ISP"}, + ) + writer.to_db_file(self.filename) + for mode in (maxminddb.MODE_MMAP_EXT, maxminddb.MODE_MMAP, maxminddb.MODE_FILE): + m = maxminddb.open_database(self.filename, mode=mode) + self.assertEqual({"country": "COUNTRY", "isp": "ISP"}, m.get("1.1.0.0"), mode) + self.assertEqual({"country": "COUNTRY", "isp": "ISP"}, m.get("1.1.1.0"), mode) + m.close() + + def test_empty_languages(self): + """Ensure empty languages array doesn't cause issues with strict validation.""" + writer = MMDBWriter(languages=[]) + writer.insert_network(IPSet(["10.0.0.0/8"]), {"value": "test"}) + writer.to_db_file(self.filename) + for mode in (maxminddb.MODE_MMAP_EXT, maxminddb.MODE_MMAP, maxminddb.MODE_FILE): + m = maxminddb.open_database(self.filename, mode=mode) + self.assertEqual({"value": "test"}, m.get("10.0.0.1"), mode) + m.close() + def test_int_type(self): value_range_map = {} value_range_map.update(