diff --git a/.github/workflows/precious.yml b/.github/workflows/precious.yml new file mode 100644 index 00000000..bfc4d6cb --- /dev/null +++ b/.github/workflows/precious.yml @@ -0,0 +1,24 @@ +name: precious + +on: + push: + pull_request: + +permissions: {} + +jobs: + precious: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Setup mise + uses: jdx/mise-action@6d1e696aa24c1aa1bcc1adea0212707c71ab78a8 # v3.6.1 + with: + cache: true + + - name: Run precious lint + run: precious lint --all diff --git a/.precious.toml b/.precious.toml new file mode 100644 index 00000000..33d74e02 --- /dev/null +++ b/.precious.toml @@ -0,0 +1,24 @@ +exclude = [ + ".git", + "maxmind-db/**", + "t/libtap/**", + "t/maxmind-db/**", +] + +[commands.clang-format] +type = "both" +cmd = ["clang-format", "-style=file"] +lint-flags = ["--dry-run", "-Werror"] +tidy-flags = ["-i"] +path-args = "file" +include = ["**/*.c", "**/*.h"] +ok-exit-codes = 0 + +[commands.prettier-markdown] +type = "both" +cmd = ["prettier", "--prose-wrap", "always", "--print-width", "80"] +lint-flags = ["--check"] +tidy-flags = ["--write"] +path-args = "file" +include = ["**/*.md"] +ok-exit-codes = 0 diff --git a/Changes.md b/Changes.md index 8f55ec5e..73bbe9fe 100644 --- a/Changes.md +++ b/Changes.md @@ -1,529 +1,486 @@ ## 1.13.0 -* `MMDB_get_entry_data_list()` now validates that the claimed array/map - size is plausible given the remaining bytes in the data section. A - crafted database could previously claim millions of array elements - while only having a few bytes of data, causing disproportionate memory - allocation (memory amplification DoS). -* On Windows, `GetFileSize()` was replaced with `GetFileSizeEx()` to - correctly handle files larger than 4GB. The previous code passed - `NULL` for the high DWORD, discarding the upper 32 bits of the file - size. -* Fixed integer overflow in `MMDB_read_node()` and `find_ipv4_start_node()` - pointer arithmetic. The `node_number * record_length` multiplication - was performed in `uint32_t`, which could overflow for very large - databases. Now cast to `uint64_t` before multiplying, matching the - pattern already used in `find_address_in_search_tree()`. -* Fixed printf format specifier mismatches in `mmdblookup`'s metadata - dump. `%i` was used for unsigned types and `%llu` for `uint64_t`, - which is technically undefined behavior. Now uses the portable - `PRIu32`, `PRIu16`, and `PRIu64` macros from ``. -* Fixed an integer overflow in the search tree bounds check in +- `MMDB_get_entry_data_list()` now validates that the claimed array/map size is + plausible given the remaining bytes in the data section. A crafted database + could previously claim millions of array elements while only having a few + bytes of data, causing disproportionate memory allocation (memory + amplification DoS). +- On Windows, `GetFileSize()` was replaced with `GetFileSizeEx()` to correctly + handle files larger than 4GB. The previous code passed `NULL` for the high + DWORD, discarding the upper 32 bits of the file size. +- Fixed integer overflow in `MMDB_read_node()` and `find_ipv4_start_node()` + pointer arithmetic. The `node_number * record_length` multiplication was + performed in `uint32_t`, which could overflow for very large databases. Now + cast to `uint64_t` before multiplying, matching the pattern already used in + `find_address_in_search_tree()`. +- Fixed printf format specifier mismatches in `mmdblookup`'s metadata dump. `%i` + was used for unsigned types and `%llu` for `uint64_t`, which is technically + undefined behavior. Now uses the portable `PRIu32`, `PRIu16`, and `PRIu64` + macros from ``. +- Fixed an integer overflow in the search tree bounds check in `find_address_in_search_tree()`. The addition of `node_count` and - `data_section_size` was performed in `uint32_t` arithmetic, which - could wrap on very large databases, causing valid lookups to be - incorrectly rejected as corrupt. -* Fixed a NULL pointer dereference in `mmdblookup` when displaying - metadata for a database with an out-of-range `build_epoch`. The - `gmtime()` return value is now checked before passing to `strftime()`. -* `MMDB_close()` now NULLs the `file_content`, `data_section`, and - `metadata_section` pointers and zeroes `file_size`, `data_section_size`, - and `metadata_section_size` after unmapping. Previously, calling - `MMDB_close()` twice on the same struct (or calling it after a failed - `MMDB_open()` that succeeded at mapping) would double-munmap the file - content, which is undefined behavior. -* Fixed a stack buffer overflow in `print_indentation()` when - `MMDB_dump_entry_data_list()` was called with a negative `indent` - value. The negative integer was cast to `size_t`, producing a massive - value passed to `memset()`. Negative indent values are now clamped - to 0. -* `MMDB_lookup_string()` now sets `*mmdb_error` to `MMDB_SUCCESS` when - `getaddrinfo` fails (non-zero `*gai_error`). Previously, `*mmdb_error` - was left uninitialized in this case, which could cause callers to read - an indeterminate value. -* Fixed an off-by-one in `mmdblookup` on Windows where `alloca` allocated - one byte too few for the program name buffer, causing `_splitpath` to - write one byte past the end when appending the null terminator. -* Added a recursion depth limit to `skip_map_or_array()`, matching the - existing `MAXIMUM_DATA_STRUCTURE_DEPTH` (512) limit already used by - `get_entry_data_list()`. A crafted MMDB file with deeply nested maps - or arrays could previously cause a stack overflow via unbounded - recursion in the `MMDB_aget_value` / `MMDB_get_value` code path. -* Fixed an off-by-one error in `MMDB_read_node()` that allowed reading one - node past the end of the search tree when called with - `node_number == node_count`. This caused the function to read from the - data section separator and return an invalid record with an underflowed - data offset. The check now correctly rejects `node_number >= node_count`. -* The handling of float and double types was rewritten to fix compiler errors + `data_section_size` was performed in `uint32_t` arithmetic, which could wrap + on very large databases, causing valid lookups to be incorrectly rejected as + corrupt. +- Fixed a NULL pointer dereference in `mmdblookup` when displaying metadata for + a database with an out-of-range `build_epoch`. The `gmtime()` return value is + now checked before passing to `strftime()`. +- `MMDB_close()` now NULLs the `file_content`, `data_section`, and + `metadata_section` pointers and zeroes `file_size`, `data_section_size`, and + `metadata_section_size` after unmapping. Previously, calling `MMDB_close()` + twice on the same struct (or calling it after a failed `MMDB_open()` that + succeeded at mapping) would double-munmap the file content, which is undefined + behavior. +- Fixed a stack buffer overflow in `print_indentation()` when + `MMDB_dump_entry_data_list()` was called with a negative `indent` value. The + negative integer was cast to `size_t`, producing a massive value passed to + `memset()`. Negative indent values are now clamped to 0. +- `MMDB_lookup_string()` now sets `*mmdb_error` to `MMDB_SUCCESS` when + `getaddrinfo` fails (non-zero `*gai_error`). Previously, `*mmdb_error` was + left uninitialized in this case, which could cause callers to read an + indeterminate value. +- Fixed an off-by-one in `mmdblookup` on Windows where `alloca` allocated one + byte too few for the program name buffer, causing `_splitpath` to write one + byte past the end when appending the null terminator. +- Added a recursion depth limit to `skip_map_or_array()`, matching the existing + `MAXIMUM_DATA_STRUCTURE_DEPTH` (512) limit already used by + `get_entry_data_list()`. A crafted MMDB file with deeply nested maps or arrays + could previously cause a stack overflow via unbounded recursion in the + `MMDB_aget_value` / `MMDB_get_value` code path. +- Fixed an off-by-one error in `MMDB_read_node()` that allowed reading one node + past the end of the search tree when called with `node_number == node_count`. + This caused the function to read from the data section separator and return an + invalid record with an underflowed data offset. The check now correctly + rejects `node_number >= node_count`. +- The handling of float and double types was rewritten to fix compiler errors and to eliminate the use of volatile. -* Improved endian preprocessor check if `MMDB_LITTLE_ENDIAN` is not set. +- Improved endian preprocessor check if `MMDB_LITTLE_ENDIAN` is not set. ## 1.12.2 - 2025-01-10 -* `MMDB_get_entry_data_list()` now always sets the passed `entry_data_list` - parameter to either `NULL` or valid memory. This makes it safe for - callers to use `MMDB_free_entry_data_list()` on it even in case of error. - In 1.12.0 `MMDB_get_entry_data_list()` was changed to not set this - parameter to valid memory in additional error cases. That change caused - segfaults for certain libraries that assumed it was safe to free memory - on error. Doing so was never safe, but worked in some cases. This change - makes such calls safe. Reported by Petr Pisar. GitHub - maxmind/MaxMind-DB-Reader-XS#39. +- `MMDB_get_entry_data_list()` now always sets the passed `entry_data_list` + parameter to either `NULL` or valid memory. This makes it safe for callers to + use `MMDB_free_entry_data_list()` on it even in case of error. In 1.12.0 + `MMDB_get_entry_data_list()` was changed to not set this parameter to valid + memory in additional error cases. That change caused segfaults for certain + libraries that assumed it was safe to free memory on error. Doing so was never + safe, but worked in some cases. This change makes such calls safe. Reported by + Petr Pisar. GitHub maxmind/MaxMind-DB-Reader-XS#39. ## 1.12.1 - 2025-01-08 -* Added missing `cmake_uninstall.cmake.in` to the source distribution. This - was missing from 1.12.0, causing CMake builds to fail. Reported by Marcel - Raad. GitHub #367. +- Added missing `cmake_uninstall.cmake.in` to the source distribution. This was + missing from 1.12.0, causing CMake builds to fail. Reported by Marcel Raad. + GitHub #367. ## 1.12.0 - 2025-01-07 -* Fixed memory leaks in `MMDB_open()`. These could happen with invalid - databases or in error situations such as failing to allocate memory. As - part of the fix, `MMDB_get_entry_data_list()` now frees memory it - allocates on additional errors. Previously it failed to clean up when - certain errors occurred. Pull request by pkillarjun. GitHub #356. -* There is now a build target to fuzz the library. Pull request by - pkillarjun. GitHub #357. -* Updated `cmake_minimum_required` to a version range to quiet deprecation +- Fixed memory leaks in `MMDB_open()`. These could happen with invalid databases + or in error situations such as failing to allocate memory. As part of the fix, + `MMDB_get_entry_data_list()` now frees memory it allocates on additional + errors. Previously it failed to clean up when certain errors occurred. Pull + request by pkillarjun. GitHub #356. +- There is now a build target to fuzz the library. Pull request by pkillarjun. + GitHub #357. +- Updated `cmake_minimum_required` to a version range to quiet deprecation warnings on new CMake versions. Reported by gmou3. GitHub #359. -* The script for generating man pages no longer uses `autodie`. This - eliminates the dependency on `IPC::System::Simple`. Reported by gmou3. - GitHub #359. -* An uninstall target is now included for CMake. Pull request by gmou3. - GitHub #362. +- The script for generating man pages no longer uses `autodie`. This eliminates + the dependency on `IPC::System::Simple`. Reported by gmou3. GitHub #359. +- An uninstall target is now included for CMake. Pull request by gmou3. GitHub + #362. ## 1.11.0 - 2024-08-21 -* When building with CMake, the man pages will now be generated and - installed. Requested by Thomas Klausner. GitHub #351. -* Removed unnecessary `$` directory from - `target_include_directories` in the CMake build configuration. This is - a private build directory. Pull request by Ankur Verma. GitHub #354. +- When building with CMake, the man pages will now be generated and installed. + Requested by Thomas Klausner. GitHub #351. +- Removed unnecessary `$` directory from + `target_include_directories` in the CMake build configuration. This is a + private build directory. Pull request by Ankur Verma. GitHub #354. ## 1.10.0 - 2024-06-10 -* When building with CMake, it is now possible to disable the building - of binaries (e.g., `mmdblookup`) with the `MAXMINDDB_BUILD_BINARIES` - option and the install target generation with the `MAXMINDDB_INSTALL` - option. Pull request by Seena Fallah. GitHub #342. -* CMake now makes greater use of GNUInstallDirs. Pull request by Maximilian +- When building with CMake, it is now possible to disable the building of + binaries (e.g., `mmdblookup`) with the `MAXMINDDB_BUILD_BINARIES` option and + the install target generation with the `MAXMINDDB_INSTALL` option. Pull + request by Seena Fallah. GitHub #342. +- CMake now makes greater use of GNUInstallDirs. Pull request by Maximilian Downey Twiss. GitHub #346. -* The reader can now look up records on a database with a search tree - that is greater than 4 gigabytes without sometimes returning erroneous - results due to an integer overflow. +- The reader can now look up records on a database with a search tree that is + greater than 4 gigabytes without sometimes returning erroneous results due to + an integer overflow. ## 1.9.1 - 2024-01-09 -* `SSIZE_MAX` is now defined conditionally on Windows. The 1.9.0 - release would cause a redefinition warning when compiled with MinGW. - Reported by Andreas Vögele. GitHub #338. +- `SSIZE_MAX` is now defined conditionally on Windows. The 1.9.0 release would + cause a redefinition warning when compiled with MinGW. Reported by Andreas + Vögele. GitHub #338. ## 1.9.0 - 2024-01-09 -* On very large databases, the calculation to determine the search tree - size could overflow. This was fixed and several additional guards - against overflows were added. Reported by Sami Salonen. GitHub #335. -* Removed `sa_family_t` typedef from the public header on Windows. Pull - request by Noah Treuhaft. GitHub #334. -* The CMake build was adjusted to allow running builds in parallel. - Pull request by Vladyslav Miachkov. GitHub #332. +- On very large databases, the calculation to determine the search tree size + could overflow. This was fixed and several additional guards against overflows + were added. Reported by Sami Salonen. GitHub #335. +- Removed `sa_family_t` typedef from the public header on Windows. Pull request + by Noah Treuhaft. GitHub #334. +- The CMake build was adjusted to allow running builds in parallel. Pull request + by Vladyslav Miachkov. GitHub #332. ## 1.8.0 - 2023-11-07 -* `PACKAGE_VERSION` is now a private compile definition when building - with CMake. Pull request by bsergean. GitHub #308. -* `PACKAGE_VERSION` is no longer defined in `maxminddb.h` on - Windows. -* The feature test macro `_POSIX_C_SOURCE` is no longer set by - `maxminddb.h`. As discussed in GitHub #318, this should be set by - applications rather than by libraries. -* `assert()` is no longer used outside test code. -* The deprecated Visual Studio 12 project files in the `projects/` - directory have been removed. CMake should be used when building on - Windows. +- `PACKAGE_VERSION` is now a private compile definition when building with + CMake. Pull request by bsergean. GitHub #308. +- `PACKAGE_VERSION` is no longer defined in `maxminddb.h` on Windows. +- The feature test macro `_POSIX_C_SOURCE` is no longer set by `maxminddb.h`. As + discussed in GitHub #318, this should be set by applications rather than by + libraries. +- `assert()` is no longer used outside test code. +- The deprecated Visual Studio 12 project files in the `projects/` directory + have been removed. CMake should be used when building on Windows. ## 1.7.1 - 2022-09-30 -* The external symbols test now only runs on Linux. It assumes a Linux +- The external symbols test now only runs on Linux. It assumes a Linux environment. Reported by Carlo Cabrera. GitHub #304. ## 1.7.0 - 2022-09-28 -* `FD_CLOEXEC` is now set on platforms that do not support `O_CLOEXEC`. - Reported by rittneje. GitHub #273. -* When building with Visual Studio, you may now build a static runtime with +- `FD_CLOEXEC` is now set on platforms that do not support `O_CLOEXEC`. Reported + by rittneje. GitHub #273. +- When building with Visual Studio, you may now build a static runtime with CMake by setting `MSVC_STATIC_RUNTIME` to `ON`. Pull request by Rafael Santiago. GitHub #269. -* The CMake build now works on iOS. Pull request by SpaceIm. GitHub #271. -* The CMake build now uses the correct library directory on Linux systems - using alternate directory structures. Pull request by Satadru Pramanik. - GitHub #284. -* File size check now correctly compares the size to `SSIZE_MAX`. Reported - by marakew. GitHub #301. +- The CMake build now works on iOS. Pull request by SpaceIm. GitHub #271. +- The CMake build now uses the correct library directory on Linux systems using + alternate directory structures. Pull request by Satadru Pramanik. GitHub #284. +- File size check now correctly compares the size to `SSIZE_MAX`. Reported by + marakew. GitHub #301. ## 1.6.0 - 2021-04-29 -* This release includes several improvements to the CMake build. In - particular: - * C99 support is now properly enabled, fixing builds on older `gcc` - versions. Pull request by Jan Včelák. GitHub #257. - * `CMAKE_SHARED_LIBRARY_PREFIX` and `CMAKE_STATIC_LIBRARY_PREFIX` are - no longer explicitly set and now use the default values for the platform. - Pull request by Jan Včelák. GitHub #258. - * `target_include_directories` now works as expected. Pull request by Jan +- This release includes several improvements to the CMake build. In particular: + - C99 support is now properly enabled, fixing builds on older `gcc` versions. + Pull request by Jan Včelák. GitHub #257. + - `CMAKE_SHARED_LIBRARY_PREFIX` and `CMAKE_STATIC_LIBRARY_PREFIX` are no + longer explicitly set and now use the default values for the platform. Pull + request by Jan Včelák. GitHub #258. + - `target_include_directories` now works as expected. Pull request by Jan Včelák. GitHub #259. - * DLLs are now installed on Windows when `libmaxminddb` is built as a - shared library. Pull request by Jan Včelák. GitHub #261. - * When built as a dynamic library on Windows, all symbols are now exported. + - DLLs are now installed on Windows when `libmaxminddb` is built as a shared + library. Pull request by Jan Včelák. GitHub #261. + - When built as a dynamic library on Windows, all symbols are now exported. Pull request by Jan Včelák. GitHub #262. - ## 1.5.2 - 2021-02-18 -* With `libmaxminddb` on Windows and `mmdblookup` generally, there were - instances where the return value of `calloc` was not checked, which could - lead to issues in low memory situations or when resource limits had been - set. Reported by cve-reporting. GitHub #252. - +- With `libmaxminddb` on Windows and `mmdblookup` generally, there were + instances where the return value of `calloc` was not checked, which could lead + to issues in low memory situations or when resource limits had been set. + Reported by cve-reporting. GitHub #252. ## 1.5.1 - 2021-02-18 -* The formatting of the manpages has been improved and the script that - generates them now supports `lowdown` in addition to `pandoc`. Pull request - by Faidon Liambotis. GitHub #248. - +- The formatting of the manpages has been improved and the script that generates + them now supports `lowdown` in addition to `pandoc`. Pull request by Faidon + Liambotis. GitHub #248. ## 1.5.0 - 2021-01-05 -* A CMake build script has been added for Windows builds. The Visual - Studio project files in `projects` are now considered deprecated and will - be removed in a future release. - +- A CMake build script has been added for Windows builds. The Visual Studio + project files in `projects` are now considered deprecated and will be removed + in a future release. ## 1.4.3 - 2020-08-06 -* On Windows, always call `CreateFileW` instead of `CreateFile`. - `CreateFile` could be mapped to `CreateFileA` and not work as expected. - Pull request by Sandu Liviu Catalin. GitHub #228. -* Fixed use of uninitialized memory in `dump_entry_data_list()` that could - cause a heap buffer overflow in `mmdblookup`. As part of this fix, most - uses of `malloc` were replaced with `calloc`. Reported by azhou. GitHub - #236. - +- On Windows, always call `CreateFileW` instead of `CreateFile`. `CreateFile` + could be mapped to `CreateFileA` and not work as expected. Pull request by + Sandu Liviu Catalin. GitHub #228. +- Fixed use of uninitialized memory in `dump_entry_data_list()` that could cause + a heap buffer overflow in `mmdblookup`. As part of this fix, most uses of + `malloc` were replaced with `calloc`. Reported by azhou. GitHub #236. ## 1.4.2 - 2019-11-02 -* The 1.4.0 release introduced a change that increased the size of `MMDB_s`, +- The 1.4.0 release introduced a change that increased the size of `MMDB_s`, unintentionally causing an ABI break. This release reverts the relevant commit. - ## 1.4.1 - 2019-11-01 -* The man page links for function calls were not generated correctly in - 1.4.0. This has been corrected. - +- The man page links for function calls were not generated correctly in 1.4.0. + This has been corrected. ## 1.4.0 - 2019-11-01 -* A negative array index may now be used with `MMDB_get_value`, - `MMDB_vget_value`, and `MMDB_aget_value`. This specifies the element - from the end of the array. For instance, `-1` would refer to the - last element of the array. PR by Kyle Box. GitHub #205. -* On Windows, the file name passed to `MMDB_open` is now expected to be - UTF-8 encoded. This allows Unicode characters to be used in file names. - As part of this change, `mmdblookup` on Windows now converts its - arguments to UTF-8. PR by Gerald Combs. GitHub #189 & #191. -* Fix a memory leak that occurred when freeing an `MMDB_s` where the - database had no languages defined in the metadata. If you are using an - official MaxMind database, this leak does not affect you. Pull request - by Kókai Péter. GitHub #180. -* Add `--disable-binaries` option to `configure`. Pull request by Fabrice +- A negative array index may now be used with `MMDB_get_value`, + `MMDB_vget_value`, and `MMDB_aget_value`. This specifies the element from the + end of the array. For instance, `-1` would refer to the last element of the + array. PR by Kyle Box. GitHub #205. +- On Windows, the file name passed to `MMDB_open` is now expected to be UTF-8 + encoded. This allows Unicode characters to be used in file names. As part of + this change, `mmdblookup` on Windows now converts its arguments to UTF-8. PR + by Gerald Combs. GitHub #189 & #191. +- Fix a memory leak that occurred when freeing an `MMDB_s` where the database + had no languages defined in the metadata. If you are using an official MaxMind + database, this leak does not affect you. Pull request by Kókai Péter. GitHub + #180. +- Add `--disable-binaries` option to `configure`. Pull request by Fabrice Fontaine. GitHub #166. -* Previous releases incorrectly included `*.Po` files in the `t` directory. - This has been corrected. Reported by Daniel Macks. GitHub #168. -* The internal use of the `MMDB_s` now has the `const` modifier. Public +- Previous releases incorrectly included `*.Po` files in the `t` directory. This + has been corrected. Reported by Daniel Macks. GitHub #168. +- The internal use of the `MMDB_s` now has the `const` modifier. Public functions that accepted an `MMDB_s` as an argument now also declare it as `const`. Pull request by Kurt Johnson. GitHub #199. -* `mmdblookup` now displays the prefix length for the record when using - the verbose flag. GitHub #172. - +- `mmdblookup` now displays the prefix length for the record when using the + verbose flag. GitHub #172. ## 1.3.2 - 2018-01-17 -* Allocate memory for `MMDB_entry_data_list_s` structs in separate chunks - rather than one large chunk. This simplifies accessing memory in +- Allocate memory for `MMDB_entry_data_list_s` structs in separate chunks rather + than one large chunk. This simplifies accessing memory in `MMDB_get_entry_data_list()` and increases performance. It builds on the changes in 1.3.0 and 1.3.1. -* We no longer export `data_pool_*` symbols. These are internal functions - but we were previously exporting them. Pull request by Faidon Liambotis. - GitHub #162. -* Build with POSIX.1-2008 by default if the system supports it. This allows - use of `open()` with `O_CLOEXEC`. We retain support for systems that - provide only POSIX.1-2001. -* Open the database with the `O_CLOEXEC` flag if the system provides it. - This avoids cases where we could leak fds when called in multi-threaded - programs that `fork()` and `exec()`. Original report and PR by Brandon L - Black. -* Added a test to ensure we export only intended symbols (e.g. MMDB_*). - +- We no longer export `data_pool_*` symbols. These are internal functions but we + were previously exporting them. Pull request by Faidon Liambotis. GitHub #162. +- Build with POSIX.1-2008 by default if the system supports it. This allows use + of `open()` with `O_CLOEXEC`. We retain support for systems that provide only + POSIX.1-2001. +- Open the database with the `O_CLOEXEC` flag if the system provides it. This + avoids cases where we could leak fds when called in multi-threaded programs + that `fork()` and `exec()`. Original report and PR by Brandon L Black. +- Added a test to ensure we export only intended symbols (e.g. MMDB\_\*). ## 1.3.1 - 2017-11-24 -* Fix build problems related to `rpl_malloc()`. Pull request by Rainer - Gerhards. GitHub #152. -* Fix a race to set and read data in a field on the `MMDB_s` struct +- Fix build problems related to `rpl_malloc()`. Pull request by Rainer Gerhards. + GitHub #152. +- Fix a race to set and read data in a field on the `MMDB_s` struct (`ipv4_start_node`). GitHub #153. -* Fix cases of invalid memory access when using - `MMDB_get_entry_data_list()`. This was introduced in 1.3.0 and occurred - when performing large lookups. GitHub #153. - +- Fix cases of invalid memory access when using `MMDB_get_entry_data_list()`. + This was introduced in 1.3.0 and occurred when performing large lookups. + GitHub #153. ## 1.3.0 - 2017-11-10 -* Perform fewer memory allocations in `MMDB_get_entry_data_list()`. This +- Perform fewer memory allocations in `MMDB_get_entry_data_list()`. This significantly improves its performance. GitHub #147. -* Fix `mmdblookup`'s build epoch reporting on some systems. Big endian - systems with a 32-bit `time_t` no longer show a database build date of - 1970-01-01 00:00:00. Pull request by Rainer Jung. GitHub #143. - +- Fix `mmdblookup`'s build epoch reporting on some systems. Big endian systems + with a 32-bit `time_t` no longer show a database build date of 1970-01-01 + 00:00:00. Pull request by Rainer Jung. GitHub #143. ## 1.2.1 - 2017-05-15 -* Use autoconf to check the system's endianness rather than trying to do this +- Use autoconf to check the system's endianness rather than trying to do this with compiler-defined macros like `__BYTE_ORDER__`. Apparently this didn't work properly on a Sparc system. GitHub #120. -* Several compiler warnings on Visual C++ were fixed. Pull request by Marcel +- Several compiler warnings on Visual C++ were fixed. Pull request by Marcel Raad. GitHub #130. -* Fix segmentation faults found in `MMDB_open()` using afl-fuzz. This - occurred on corrupt databases that had a data pointer large enough to - cause an integer overflow when doing bound checking. Reported by Ryan - Whitworth. GitHub #140. -* Add --disable-tests option to `configure`. Pull request by Fabrice - Fontaine. GitHub #136. - +- Fix segmentation faults found in `MMDB_open()` using afl-fuzz. This occurred + on corrupt databases that had a data pointer large enough to cause an integer + overflow when doing bound checking. Reported by Ryan Whitworth. GitHub #140. +- Add --disable-tests option to `configure`. Pull request by Fabrice Fontaine. + GitHub #136. ## 1.2.0 - 2016-03-23 -* Four additional fields were added to the end of the `MMDB_search_node_s` +- Four additional fields were added to the end of the `MMDB_search_node_s` struct returned by `MMDB_read_node`. These fields allow the user to iterate - through the search tree without making undocumented assumptions about how - this library works internally and without knowing the specific details of - the database format. GitHub #110. - + through the search tree without making undocumented assumptions about how this + library works internally and without knowing the specific details of the + database format. GitHub #110. ## 1.1.5 - 2016-03-20 -* Previously, reading a database with a pointer in the metadata would cause an +- Previously, reading a database with a pointer in the metadata would cause an `MMDB_INVALID_METADATA_ERROR` to be returned. This was due to an invalid offset being used when calculating the pointer. The `data_section` and - `metadata_section` fields now both point to the beginning of the data - section. Previously, `data_section` pointed to the beginning of the data - separator. This will not affect anyone using only documented fields from - `MMDB_s`. -* `MMDB_lookup_sockaddr` will set `mmdb_error` to + `metadata_section` fields now both point to the beginning of the data section. + Previously, `data_section` pointed to the beginning of the data separator. + This will not affect anyone using only documented fields from `MMDB_s`. +- `MMDB_lookup_sockaddr` will set `mmdb_error` to `MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR` if an IPv6 `sockaddr` is looked up - in an IPv4-only database. Previously only `MMDB_lookup_string` would set - this error code. -* When resolving an address, this library now relies on `getaddrinfo` to + in an IPv4-only database. Previously only `MMDB_lookup_string` would set this + error code. +- When resolving an address, this library now relies on `getaddrinfo` to determine the address family rather than trying to guess it itself. - ## 1.1.4 - 2016-01-06 -* Packaging fixes. The 1.1.3 tarball release contained a lot of extra junk in +- Packaging fixes. The 1.1.3 tarball release contained a lot of extra junk in the t/ directory. - ## 1.1.3 - 2016-01-05 -* Added several additional checks to make sure that we don't attempt to read +- Added several additional checks to make sure that we don't attempt to read past the end of the databases's data section. Implemented by Tobias Stoeckmann. GitHub #103. -* When searching for the database metadata, there was a bug that caused the - code to think it had found valid metadata when none existed. In addition, - this could lead to an attempt to read past the end of the database - entirely. Finally, if there are multiple metadata markers in the database, - we treat the final one as the start of the metadata, instead of the first. - Implemented by Tobias Stoeckmann. GitHub #102. -* Don't attempt to mmap a file that is too large to be mmapped on the - system. Implemented by Tobias Stoeckmann. GitHub #101. -* Added a missing out of memory check when reading a file's - metadata. Implemented by Tobias Stoeckmann. GitHub #101. -* Added several additional checks to make sure that we never attempt to - `malloc` more than `SIZE_MAX` memory, which would lead to integer - overflow. This could only happen with pathological databases. Implemented by - Tobias Stoeckmann. GitHub #101. - +- When searching for the database metadata, there was a bug that caused the code + to think it had found valid metadata when none existed. In addition, this + could lead to an attempt to read past the end of the database entirely. + Finally, if there are multiple metadata markers in the database, we treat the + final one as the start of the metadata, instead of the first. Implemented by + Tobias Stoeckmann. GitHub #102. +- Don't attempt to mmap a file that is too large to be mmapped on the system. + Implemented by Tobias Stoeckmann. GitHub #101. +- Added a missing out of memory check when reading a file's metadata. + Implemented by Tobias Stoeckmann. GitHub #101. +- Added several additional checks to make sure that we never attempt to `malloc` + more than `SIZE_MAX` memory, which would lead to integer overflow. This could + only happen with pathological databases. Implemented by Tobias Stoeckmann. + GitHub #101. ## 1.1.2 - 2015-11-16 -* IMPORTANT: This release includes a number of important security fixes. Among +- IMPORTANT: This release includes a number of important security fixes. Among these fixes is improved validation of the database metadata. Unfortunately, MaxMind GeoIP2 and GeoLite2 databases created earlier than January 28, 2014 had an invalid data type for the `record_size` in the metadata. Previously - these databases worked on little endian machines with libmaxminddb but did - not work on big endian machines. Due to increased safety checks when reading - the file, these databases will no longer work on any platform. If you are - using one of these databases, we recommend that you upgrade to the latest - GeoLite2 or GeoIP2 database -* Added pkg-config support. If your system supports it, then running `make - install` now installs a `libmaxminddb.pc` file for pkgconfig. Implemented by - Jan Vcelak. -* Several segmentation faults found with afl-fuzz were fixed. These were - caused by missing bounds checking and missing data type verification checks. -* `MMDB_get_entry_data_list` will now fail on data structures with a depth - greater than 512 and data structures that are cyclic. This should not - affect any known MaxMind DB in production. All databases produced by - MaxMind have a depth of less than five. - + these databases worked on little endian machines with libmaxminddb but did not + work on big endian machines. Due to increased safety checks when reading the + file, these databases will no longer work on any platform. If you are using + one of these databases, we recommend that you upgrade to the latest GeoLite2 + or GeoIP2 database +- Added pkg-config support. If your system supports it, then running + `make install` now installs a `libmaxminddb.pc` file for pkgconfig. + Implemented by Jan Vcelak. +- Several segmentation faults found with afl-fuzz were fixed. These were caused + by missing bounds checking and missing data type verification checks. +- `MMDB_get_entry_data_list` will now fail on data structures with a depth + greater than 512 and data structures that are cyclic. This should not affect + any known MaxMind DB in production. All databases produced by MaxMind have a + depth of less than five. ## 1.1.1 - 2015-07-22 -* Added `maxminddb-compat-util.h` as a source file to dist. - +- Added `maxminddb-compat-util.h` as a source file to dist. ## 1.1.0 - 2015-07-21 -* Previously, when there was an error in `MMDB_open()`, `errno` would - generally be overwritten during cleanup, preventing a useful value from - being returned to the caller. This was changed so that the `errno` value - from the function call that caused the error is restored before returning to - the caller. In particular, this is important for `MMDB_IO_ERROR` errors as - checking `errno` is often the only way to determine what actually failed. -* If `mmap()` fails due to running out of memory space, an +- Previously, when there was an error in `MMDB_open()`, `errno` would generally + be overwritten during cleanup, preventing a useful value from being returned + to the caller. This was changed so that the `errno` value from the function + call that caused the error is restored before returning to the caller. In + particular, this is important for `MMDB_IO_ERROR` errors as checking `errno` + is often the only way to determine what actually failed. +- If `mmap()` fails due to running out of memory space, an `MMDB_OUT_OF_MEMORY_ERROR` is now returned from `MMDB_open` rather than an `MMDB_IO_ERROR`. -* On Windows, the `CreateFileMappingA()` handle was not properly closed if +- On Windows, the `CreateFileMappingA()` handle was not properly closed if opening the database succeeded. Fixed by Bly Hostetler. GitHub #75 & #76. -* On Windows, we were not checking the return value of `CreateFileMappingA()` +- On Windows, we were not checking the return value of `CreateFileMappingA()` properly for errors. Fixed by Bly Hotetler. GitHub #78. -* Several warnings from Clang's scan-build were fixed. GitHub #86. -* All headers are now installed in `$(includedir)`. GitHub #89. -* We no longer install `maxminddb-compat-util.h`. This header was intended for +- Several warnings from Clang's scan-build were fixed. GitHub #86. +- All headers are now installed in `$(includedir)`. GitHub #89. +- We no longer install `maxminddb-compat-util.h`. This header was intended for internal use only. - ## 1.0.4 - 2015-01-02 -* If you used a non-integer string as an array index when doing a lookup with +- If you used a non-integer string as an array index when doing a lookup with `MMDB_get_value()`, `MMDB_vget_value()`, or `MMDB_aget_value()`, the first element of the array would be returned rather than an error. A `MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR` error will now be returned. GitHub #61. -* If a number larger than `LONG_MAX` was used in the same functions, - `LONG_MAX` would have been used in the lookup. Now a - `MMDB_INVALID_LOOKUP_PATH_ERROR` error will be returned. -* Visual Studio build files were added for unit tests and some compatibility +- If a number larger than `LONG_MAX` was used in the same functions, `LONG_MAX` + would have been used in the lookup. Now a `MMDB_INVALID_LOOKUP_PATH_ERROR` + error will be returned. +- Visual Studio build files were added for unit tests and some compatibility issues with the tests were fixed. -* Visual Studio project was updated to use property pages. Patch by Andre. +- Visual Studio project was updated to use property pages. Patch by Andre. GitHub #69. -* A test failure in `t/compile_c++_t.pl` on new installs was fixed. - +- A test failure in `t/compile_c++_t.pl` on new installs was fixed. ## 1.0.3 - 2014-12-02 -* A memory and file handle leak on Win32 was fixed when getting the database +- A memory and file handle leak on Win32 was fixed when getting the database size fails. Patch by Federico G. Schwindt. GitHub PR #49. -* Documentation fix. Federico G. Schwindt. GitHub PR #50. -* Added Visual Studio build files and fixed incorrect CreateFileMappingA - usage. Patch by Andre. GitHub #52. -* The includes for the Windows header files were made lowercase in order to +- Documentation fix. Federico G. Schwindt. GitHub PR #50. +- Added Visual Studio build files and fixed incorrect CreateFileMappingA usage. + Patch by Andre. GitHub #52. +- The includes for the Windows header files were made lowercase in order to match the actual file names on case-sensitive file systems. GitHub PR #57. -* Removed `realloc()` calls that caused warnings on Windows and generally +- Removed `realloc()` calls that caused warnings on Windows and generally cleaned up memory allocation in `MMDB_vget_value()`. See relevant discussion in GitHub #52. -* Added an `extern "C" { ... }` wrapper to maxminddb.h when compiling with a - C++ compiler. GitHub #55. - +- Added an `extern "C" { ... }` wrapper to maxminddb.h when compiling with a C++ + compiler. GitHub #55. ## 1.0.2 - 2014-09-22 -* Fixed a number of small issues found by Coverity. -* When freeing the MMDB struct in `MMDB_close()` we make sure to set the - pointers to NULL after freeing the memory they point to. This makes it safe - to call `MMDB_close` more than once on the same `MMDB_s` struct - pointer. Before this change, calling this function twice on the same pointer - could cause the code to free memory that belonged to something else in the - process. Patch by Shuxin Yang. GitHub PR #41. - +- Fixed a number of small issues found by Coverity. +- When freeing the MMDB struct in `MMDB_close()` we make sure to set the + pointers to NULL after freeing the memory they point to. This makes it safe to + call `MMDB_close` more than once on the same `MMDB_s` struct pointer. Before + this change, calling this function twice on the same pointer could cause the + code to free memory that belonged to something else in the process. Patch by + Shuxin Yang. GitHub PR #41. ## 1.0.1 - 2014-09-03 -* Added missing LICENSE and NOTICE files to distribution. No code changes. - +- Added missing LICENSE and NOTICE files to distribution. No code changes. ## 1.0.0 - 2014-09-02 -* Bumped version to 1.0.0. No code changes. - +- Bumped version to 1.0.0. No code changes. ## 0.5.6 - 2014-07-21 -* There was a leak in the `MMDB_open()` sub when it was called against a file - which did not contain any MMDB metadata. Reported by Federico - G. Schwindt. GitHub issue #36. -* Fixed an error that occurred when passing AI_V4MAPPED to `getaddrinfo()` on - FreeBSD. Apparently this macro is defined but doesn't work the way we - expected it to on that platform. -* Made sure to call `freeaddrinfo()` when a call to `getaddrinfo()` fails but +- There was a leak in the `MMDB_open()` sub when it was called against a file + which did not contain any MMDB metadata. Reported by Federico G. Schwindt. + GitHub issue #36. +- Fixed an error that occurred when passing AI_V4MAPPED to `getaddrinfo()` on + FreeBSD. Apparently this macro is defined but doesn't work the way we expected + it to on that platform. +- Made sure to call `freeaddrinfo()` when a call to `getaddrinfo()` fails but still allocated memory. -* Fixed a segfault in the tests that occurred on FreeBSD if we passed a NULL +- Fixed a segfault in the tests that occurred on FreeBSD if we passed a NULL value to `freeaddrinfo()`. -* Added a missing step to the README.md file for installing from our GitHub +- Added a missing step to the README.md file for installing from our GitHub repository. Patch by Yasith Fernando. -* Added instructions for installing via Homebrew. Patch by Yasith Fernando. - +- Added instructions for installing via Homebrew. Patch by Yasith Fernando. ## 0.5.5 - 2014-03-11 -* The previous tarball failed to compile because it was missing the +- The previous tarball failed to compile because it was missing the src/maxminddb-compat-util.h file. Reported by Günter Grodotzki. GitHub issue #18. - ## 0.5.4 - 2014-03-03 -* Added support for compiling in the MinGW environment. Patch by Michael +- Added support for compiling in the MinGW environment. Patch by Michael Eisendle. -* Added const declarations to many spots in the public API. None of these - should require changes to existing code. -* Various documentation improvements. -* Changed the license to the Apache 2.0 license. - +- Added const declarations to many spots in the public API. None of these should + require changes to existing code. +- Various documentation improvements. +- Changed the license to the Apache 2.0 license. ## 0.5.3 - 2013-12-23 -* The internal value_for_key_as_uint16 method was returning a uint32_t instead +- The internal value_for_key_as_uint16 method was returning a uint32_t instead of a uint16_t. Reported by Robert Wells. GitHub issue #11. -* The ip_version member of the MMDB_metadata_s struct was a uint8_t, even - though the docs and spec said it should be a uint16_t. Reported by Robert - Wells. GitHub issue #11. -* The mmdblookup_t.pl test now reports that it needs IPC::Run3 to run (which - it always did, but it didn't tell you this). Patch by Elan Ruusamäe. GitHub - issue #10. - +- The ip_version member of the MMDB_metadata_s struct was a uint8_t, even though + the docs and spec said it should be a uint16_t. Reported by Robert Wells. + GitHub issue #11. +- The mmdblookup_t.pl test now reports that it needs IPC::Run3 to run (which it + always did, but it didn't tell you this). Patch by Elan Ruusamäe. GitHub issue + #10. ## 0.5.2 - 2013-11-20 -* Running `make` from the tarball failed. This is now fixed. - +- Running `make` from the tarball failed. This is now fixed. ## 0.5.1 - 2013-11-20 -* Renamed MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA define to - MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR for consistency. Fixes github - issue #5. Reported by Albert Strasheim. -* Updated README.md to show git clone with --recursive flag so you get the +- Renamed MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA define to + MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR for consistency. Fixes github issue + #5. Reported by Albert Strasheim. +- Updated README.md to show git clone with --recursive flag so you get the needed submodules. Fixes github issue #4. Reported by Ryan Peck. -* Fixed some bugs with the MMDB_get_*value functions when navigating a data - structure that included pointers. Fixes github issue #3. Reported by - bagadon. -* Fixed compilation problems on OSX and OpenBSD. We have tested this on OSX - and OpenBSD 5.4. Fixes github issue #6. -* Removed some unneeded memory allocations and added const to many variable +- Fixed some bugs with the MMDB*get*\*value functions when navigating a data + structure that included pointers. Fixes github issue #3. Reported by bagadon. +- Fixed compilation problems on OSX and OpenBSD. We have tested this on OSX and + OpenBSD 5.4. Fixes github issue #6. +- Removed some unneeded memory allocations and added const to many variable declarations. Based on patches by Timo Teräs. Github issue #8. -* Added a test that uses threads to check for thread safety issue in the +- Added a test that uses threads to check for thread safety issue in the library. -* Distro tarball now includes man pages, tests, and test data +- Distro tarball now includes man pages, tests, and test data diff --git a/README.dev.md b/README.dev.md index 3f681715..235eda36 100644 --- a/README.dev.md +++ b/README.dev.md @@ -3,17 +3,17 @@ We release by uploading the tarball to GitHub and uploading Ubuntu PPAs. ## Creating the release tarball + You may want to refer to the section about prerequisites. -* Check whether there are any open issues to fix while you're doing this. -* Update `Changes.md` to include specify the new version, today's date, and - list relevant changes. Commit this. -* Create a new branch off of the latest `main` for the release. -* Run `./dev-bin/release.sh` to update various files in the distro, our - GitHub pages, and creates a GitHub release with the tarball. -* Check the release looks good on both GitHub and launchpad.net. -* Make a pull request against `main` with the changes from the release - script. +- Check whether there are any open issues to fix while you're doing this. +- Update `Changes.md` to specify the new version, today's date, and list + relevant changes. Commit this. +- Create a new branch off of the latest `main` for the release. +- Run `./dev-bin/release.sh` to update various files in the distro, our GitHub + pages, and creates a GitHub release with the tarball. +- Check the release looks good on both GitHub and launchpad.net. +- Make a pull request against `main` with the changes from the release script. ## PPA @@ -22,56 +22,53 @@ register a GPG key with that account. You also need to be added to the MaxMind team. Ask in the dev channel for someone to add you. See https://help.launchpad.net/Packaging/PPA for more details. -The PPA release script is at `dev-bin/ppa-release.sh`. Running it should -guide you though the release, although it may require some changes to run on +The PPA release script is at `dev-bin/ppa-release.sh`. Running it should guide +you though the release, although it may require some changes to run on configurations different than Greg's machine. -Check whether any new Ubuntu versions need to be listed in this script -before running it. +Check whether any new Ubuntu versions need to be listed in this script before +running it. You should run it from `main`. ## Homebrew (optional) -Releasing to Homebrew is no longer required as the formulas are easily -updated by the end-user using a built-in feature in the tool. These -directions remain in case there is a more significant change to the -build process that may require a non-trivial update to the formula or -in the case where we want the Homebrew version updated promptly for -some reason. +Releasing to Homebrew is no longer required as the formulas are easily updated +by the end-user using a built-in feature in the tool. These directions remain in +case there is a more significant change to the build process that may require a +non-trivial update to the formula or in the case where we want the Homebrew +version updated promptly for some reason. -* Go to https://github.com/Homebrew/homebrew-core/edit/master/Formula/libmaxminddb.rb -* Edit the file to update the url and sha256. You can get the sha256 for the +- Go to + https://github.com/Homebrew/homebrew-core/edit/master/Formula/libmaxminddb.rb +- Edit the file to update the url and sha256. You can get the sha256 for the tarball with the `sha256sum` command line utility. -* Make a commit with the summary `libmaxminddb ` -* Submit a PR with the changes you just made. +- Make a commit with the summary `libmaxminddb ` +- Submit a PR with the changes you just made. # Prerequisites for releasing -* Required packages (Ubuntu Artful): vim git-core dput build-essential - autoconf automake libtool git-buildpackage libfile-slurp-perl pandoc - dirmngr libfile-slurp-tiny-perl libdatetime-perl debhelper dh-autoreconf +- Required packages (Ubuntu Artful): vim git-core dput build-essential autoconf + automake libtool git-buildpackage libfile-slurp-perl pandoc dirmngr + libfile-slurp-tiny-perl libdatetime-perl debhelper dh-autoreconf libipc-run3-perl libtest-output-perl devscripts -* Install [gh](https://github.com/cli/cli/releases). -* GitHub ssh key (e.g. in `~/.ssh/id_rsa`) -* Git config (e.g. `~/.gitconfig`) -* Import your GPG secret key (or create one if you don't have a suitable - one) - * `gpg --import /path/to/key` - * `gpg --edit-key KEYID` and trust it ultimately - * Ensure it shows with `gpg --list-secret-keys` -* You need to be invited to the launchpad.net MaxMind organization on your +- Install [gh](https://github.com/cli/cli/releases). +- GitHub ssh key (e.g. in `~/.ssh/id_rsa`) +- Git config (e.g. `~/.gitconfig`) +- Import your GPG secret key (or create one if you don't have a suitable one) + - `gpg --import /path/to/key` + - `gpg --edit-key KEYID` and trust it ultimately + - Ensure it shows with `gpg --list-secret-keys` +- You need to be invited to the launchpad.net MaxMind organization on your launchpad.net account. -* You need your GPG key listed on your launchpad.net account - * You can add it in the web interface. It wants the output of +- You need your GPG key listed on your launchpad.net account + - You can add it in the web interface. It wants the output of `gpg --fingerprint`. - * Part of the instructions involve having your key published on the - Ubuntu keyserver: - `gpg --keyserver keyserver.ubuntu.com --send-keys KEYID` - * You'll get an email with an encrypted payload that you need to decrypt - and follow the link to confirm it. -* Ensure `dch` knows your name and email. Refer to its man page for how to - tell it this. One way is to set the `DEBFULLNAME` and `DEBEMAIL` - environment variables. These should match your GPG key's name and email - exactly. This is what gets used in the Debian changelog as well as - defines what GPG key to use. + - Part of the instructions involve having your key published on the Ubuntu + keyserver: `gpg --keyserver keyserver.ubuntu.com --send-keys KEYID` + - You'll get an email with an encrypted payload that you need to decrypt and + follow the link to confirm it. +- Ensure `dch` knows your name and email. Refer to its man page for how to tell + it this. One way is to set the `DEBFULLNAME` and `DEBEMAIL` environment + variables. These should match your GPG key's name and email exactly. This is + what gets used in the Debian changelog as well as defines what GPG key to use. diff --git a/README.fuzzing.md b/README.fuzzing.md index c0a4948d..621061c0 100644 --- a/README.fuzzing.md +++ b/README.fuzzing.md @@ -9,10 +9,10 @@ These tests are only meant to be run on GNU/Linux. Note that in `CFLAGS` and `CXXFLAGS`, any type of sanitizers can be added. - [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html), - [ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html), - [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html), - [UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html), - [LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html). + [ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html), + [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html), + [UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html), + [LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html). ```shell $ export CC=clang @@ -38,4 +38,5 @@ $ find ../t/maxmind-db/test-data/ -type f -size -4k -exec cp {} ./fuzz_mmdb_seed $ ./t/fuzz_mmdb fuzz_mmdb_seed/ fuzz_mmdb_seed_corpus/ ``` -Here is more information about [LibFuzzer](https://llvm.org/docs/LibFuzzer.html). +Here is more information about +[LibFuzzer](https://llvm.org/docs/LibFuzzer.html). diff --git a/README.md b/README.md index 3256b75c..46a08013 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ designed to facilitate fast lookups of IP addresses while allowing for great flexibility in the type of data associated with an address. The MaxMind DB format is an open format. The spec is available at -https://maxmind.github.io/MaxMind-DB/. This spec is licensed under the -Creative Commons Attribution-ShareAlike 3.0 Unported License. +https://maxmind.github.io/MaxMind-DB/. This spec is licensed under the Creative +Commons Attribution-ShareAlike 3.0 Unported License. See https://dev.maxmind.com/ for more details about MaxMind's GeoIP2 products. @@ -23,9 +23,9 @@ This library is licensed under the Apache License, Version 2. tarballs on the [Releases](https://github.com/maxmind/libmaxminddb/releases) page (e.g. `libmaxminddb-*.tar.gz`). -This code is known to work with GCC 4.4+ and clang 3.2+. It should also work -on other compilers that supports C99, POSIX.1-2001, and the `-fms-extensions -flag` (or equivalent). The latter is needed to allow an anonymous union in a +This code is known to work with GCC 4.4+ and clang 3.2+. It should also work on +other compilers that support C99, POSIX.1-2001, and the `-fms-extensions flag` +(or equivalent). The latter is needed to allow an anonymous union in a structure. To install this code, run the following commands: @@ -56,16 +56,16 @@ ldconfig ## From a GitHub "Source Code" Archive / Git Repo Clone (Achtung!) -**NOTE:** These instructions are for installation from the GitHub "Source -Code" archives also available on the +**NOTE:** These instructions are for installation from the GitHub "Source Code" +archives also available on the [Releases](https://github.com/maxmind/libmaxminddb/releases) page (e.g. -`X.Y.Z.zip` or `X.Y.Z.tar.gz`), as well as installation directly from a clone -of the [Git repo](https://github.com/maxmind/libmaxminddb). Installation from -these sources are possible but will present challenges to users not -comfortable with manual dependency resolution. +`X.Y.Z.zip` or `X.Y.Z.tar.gz`), as well as installation directly from a clone of +the [Git repo](https://github.com/maxmind/libmaxminddb). Installation from these +sources is possible but will present challenges to users not comfortable with +manual dependency resolution. -You will need `automake`, `autoconf`, and `libtool` installed -in addition to `make` and a compiler. +You will need `automake`, `autoconf`, and `libtool` installed in addition to +`make` and a compiler. You can clone this repository and build it by running: @@ -74,8 +74,8 @@ git clone --recursive https://github.com/maxmind/libmaxminddb ``` After cloning, run `./bootstrap` from the `libmaxminddb` directory and then -follow the instructions for installing from a named release tarball as -described above. +follow the instructions for installing from a named release tarball as described +above. ## Using CMake @@ -91,8 +91,8 @@ ctest -V . cmake --build . --target install ``` -When building with Visual Studio, you may build a multithreaded (MT/MTd) -runtime library, using the `MSVC_STATIC_RUNTIME` setting: +When building with Visual Studio, you may build a multithreaded (MT/MTd) runtime +library, using the `MSVC_STATIC_RUNTIME` setting: ```bash cmake -DMSVC_STATIC_RUNTIME=ON -DBUILD_SHARED_LIBS=OFF .. @@ -106,8 +106,8 @@ cmake --build . --target uninstall ## On Ubuntu via PPA -MaxMind provides a PPA for recent version of Ubuntu. To add the PPA to your -APT sources, run: +MaxMind provides a PPA for recent version of Ubuntu. To add the PPA to your APT +sources, run: ```bash sudo add-apt-repository ppa:maxmind/ppa @@ -136,8 +136,8 @@ sudo port install libmaxminddb # Requirements -libmaxminddb requires a minimum of POSIX.1-2001 support. If not specified -at compilation time, it defaults to requesting POSIX.1-2008 support. +libmaxminddb requires a minimum of POSIX.1-2001 support. If not specified at +compilation time, it defaults to requesting POSIX.1-2008 support. # Bug Reports @@ -152,14 +152,13 @@ Use `make safedist` to check the resulting tarball. Copyright 2013-2025 MaxMind, Inc. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at https://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. diff --git a/dev-bin/clang-format-all.sh b/dev-bin/clang-format-all.sh deleted file mode 100755 index 85c595d5..00000000 --- a/dev-bin/clang-format-all.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -format="clang-format -i -style=file" - -for dir in bin include src t; do - c_files=`find $dir -maxdepth 1 -name '*.c'` - if [ "$c_files" != "" ]; then - $format $dir/*.c; - fi - - h_files=`find $dir -maxdepth 1 -name '*.h'` - if [ "$h_files" != "" ]; then - $format $dir/*.h; - fi -done diff --git a/doc/libmaxminddb.md b/doc/libmaxminddb.md index 5684f8e8..511008be 100644 --- a/doc/libmaxminddb.md +++ b/doc/libmaxminddb.md @@ -14,12 +14,12 @@ int MMDB_open( void MMDB_close(MMDB_s *const mmdb); MMDB_lookup_result_s MMDB_lookup_string( - MMDB_s *const mmdb, + const MMDB_s *const mmdb, const char *const ipstr, int *const gai_error, int *const mmdb_error); MMDB_lookup_result_s MMDB_lookup_sockaddr( - MMDB_s *const mmdb, + const MMDB_s *const mmdb, const struct sockaddr *const sockaddr, int *const mmdb_error); @@ -43,7 +43,7 @@ int MMDB_get_entry_data_list( void MMDB_free_entry_data_list( MMDB_entry_data_list_s *const entry_data_list); int MMDB_get_metadata_as_entry_data_list( - MMDB_s *const mmdb, + const MMDB_s *const mmdb, MMDB_entry_data_list_s **const entry_data_list); int MMDB_dump_entry_data_list( FILE *const stream, @@ -51,7 +51,7 @@ int MMDB_dump_entry_data_list( int indent); int MMDB_read_node( - MMDB_s *const mmdb, + const MMDB_s *const mmdb, uint32_t node_number, MMDB_search_node_s *const node); @@ -92,12 +92,12 @@ typedef struct MMDB_entry_data_list_s { # DESCRIPTION -The libmaxminddb library provides functions for working MaxMind DB files. See -https://maxmind.github.io/MaxMind-DB/ for the MaxMind DB format -specification. The database and results are all represented by different -data structures. Databases are opened by calling `MMDB_open()`. You can -look up IP addresses as a string with `MMDB_lookup_string()` or as a -pointer to a `sockaddr` structure with `MMDB_lookup_sockaddr()`. +The libmaxminddb library provides functions for working with MaxMind DB files. +See https://maxmind.github.io/MaxMind-DB/ for the MaxMind DB format +specification. The database and results are all represented by different data +structures. Databases are opened by calling `MMDB_open()`. You can look up IP +addresses as a string with `MMDB_lookup_string()` or as a pointer to a +`sockaddr` structure with `MMDB_lookup_sockaddr()`. If the lookup finds the IP address in the database, it returns a `MMDB_lookup_result_s` structure. If that structure indicates that the database @@ -107,7 +107,7 @@ See the function documentation below for more details. When you are done with the database handle you should call `MMDB_close()`. -All publicly visible functions, structures, and macros begin with "MMDB_". +All publicly visible functions, structures, and macros begin with "MMDB\_". # DATA STRUCTURES @@ -132,11 +132,11 @@ typedef struct MMDB_s { } MMDB_s; ``` -* `uint32_t flags` - the flags this database was opened with. See the +- `uint32_t flags` - the flags this database was opened with. See the `MMDB_open()` documentation for more details. -* `const char *filename` - the name of the file which was opened, as passed to +- `const char *filename` - the name of the file which was opened, as passed to `MMDB_open()`. -* `MMDB_metadata_s metadata` - the metadata for the database. +- `MMDB_metadata_s metadata` - the metadata for the database. ## `MMDB_metadata_s` and `MMDB_description_s` @@ -176,8 +176,8 @@ The `ip_version` member should always be `4` or `6`. The `binary_format_major_version` should always be `2`. There is no requirement that the database metadata include languages or -descriptions, so the `count` for these parts of the metadata can be zero. All -of the other `MMDB_metadata_s` fields should be populated. +descriptions, so the `count` for these parts of the metadata can be zero. All of +the other `MMDB_metadata_s` fields should be populated. ## `MMDB_lookup_result_s` @@ -191,9 +191,8 @@ typedef struct MMDB_lookup_result_s { } MMDB_lookup_result_s; ``` -If the `found_entry` member is false then the other members of this structure -do not contain meaningful values. Always check that `found_entry` is true -first. +If the `found_entry` member is false then the other members of this structure do +not contain meaningful values. Always check that `found_entry` is true first. The `entry` member is used to look up the data associated with the IP address. @@ -203,11 +202,11 @@ and the returned `netmask` is 16, then the address is part of the `1.1.0.0/16` subnet. If the database is an IPv6 database, the returned netmask is always an IPv6 -prefix length (from 0-128), even if that database *also* contains IPv4 -networks. If you look up an IPv4 address and would like to turn the netmask -into an IPv4 netmask value, you can simply subtract `96` from the value. +prefix length (from 0-128), even if that database _also_ contains IPv4 networks. +If you look up an IPv4 address and would like to turn the netmask into an IPv4 +netmask value, you can simply subtract `96` from the value. -## `MMDB_result_s` +## `MMDB_entry_s` You don't really need to dig around in this structure. You'll get this from a `MMDB_lookup_result_s` structure and pass it to various functions. @@ -247,71 +246,75 @@ other values in the structure are meaningful. The union at the beginning of the structure defines the actual data. To determine which union member is populated you should look at the `type` member. -The `pointer` member of the union should never be populated in any data -returned by the API. Pointers should always be resolved internally. +The `pointer` member of the union should never be populated in any data returned +by the API. Pointers should always be resolved internally. The `data_size` member is only relevant for `utf8_string` and `bytes` data. -`utf8_string` is not null terminated and `data_size` _must_ be used to -determine its length. +`utf8_string` is not null terminated and `data_size` _must_ be used to determine +its length. -The `type` member can be compared to one of the `MMDB_DATA_TYPE_*` macros. +The `type` member can be compared to one of the `MMDB_DATA_TYPE_*` macros. When +`type` is `MMDB_DATA_TYPE_MAP` or `MMDB_DATA_TYPE_ARRAY`, the entry represents a +collection. To access individual items within the collection, use +`MMDB_get_value()` with the appropriate lookup path from the original entry. To +iterate over all items, use `MMDB_get_entry_data_list()`. ### 128-bit Integers The handling of `uint128` data depends on how your platform supports 128-bit -integers, if it does so at all. With GCC 4.4 and 4.5 we can write `unsigned -int __attribute__ ((__mode__ (TI)))`. With newer versions of GCC (4.6+) and -clang (3.2+) we can simply write "unsigned __int128". +integers, if it does so at all. With GCC 4.4 and 4.5 we can write +`unsigned int __attribute__ ((__mode__ (TI)))`. With newer versions of GCC +(4.6+) and clang (3.2+) we can simply write "unsigned \_\_int128". In order to work around these differences, this library defines an `mmdb_uint128_t` type. This type is defined in the `maxminddb.h` header so you can use it in your own code. -With older compilers, we can't use an integer so we instead use a 16 byte -array of `uint8_t` values. This is the raw data from the database. +With older compilers, we can't use an integer so we instead use a 16 byte array +of `uint8_t` values. This is the raw data from the database. -This library provides a public macro `MMDB_UINT128_IS_BYTE_ARRAY` macro. If -this is true (1), then `uint128` values are returned as a byte array, if it is -false then they are returned as a `mmdb_uint128_t` integer. +This library provides a public macro `MMDB_UINT128_IS_BYTE_ARRAY` macro. If this +is true (1), then `uint128` values are returned as a byte array, if it is false +then they are returned as a `mmdb_uint128_t` integer. ### Data Type Macros This library provides a macro for every data type defined by the MaxMind DB spec. -* `MMDB_DATA_TYPE_UTF8_STRING` -* `MMDB_DATA_TYPE_DOUBLE` -* `MMDB_DATA_TYPE_BYTES` -* `MMDB_DATA_TYPE_UINT16` -* `MMDB_DATA_TYPE_UINT32` -* `MMDB_DATA_TYPE_MAP` -* `MMDB_DATA_TYPE_INT32` -* `MMDB_DATA_TYPE_UINT64` -* `MMDB_DATA_TYPE_UINT128` -* `MMDB_DATA_TYPE_ARRAY` -* `MMDB_DATA_TYPE_BOOLEAN` -* `MMDB_DATA_TYPE_FLOAT` +- `MMDB_DATA_TYPE_UTF8_STRING` +- `MMDB_DATA_TYPE_DOUBLE` +- `MMDB_DATA_TYPE_BYTES` +- `MMDB_DATA_TYPE_UINT16` +- `MMDB_DATA_TYPE_UINT32` +- `MMDB_DATA_TYPE_MAP` +- `MMDB_DATA_TYPE_INT32` +- `MMDB_DATA_TYPE_UINT64` +- `MMDB_DATA_TYPE_UINT128` +- `MMDB_DATA_TYPE_ARRAY` +- `MMDB_DATA_TYPE_BOOLEAN` +- `MMDB_DATA_TYPE_FLOAT` There are also a few types that are for internal use only: -* `MMDB_DATA_TYPE_EXTENDED` -* `MMDB_DATA_TYPE_POINTER` -* `MMDB_DATA_TYPE_CONTAINER` -* `MMDB_DATA_TYPE_END_MARKER` +- `MMDB_DATA_TYPE_EXTENDED` +- `MMDB_DATA_TYPE_POINTER` +- `MMDB_DATA_TYPE_CONTAINER` +- `MMDB_DATA_TYPE_END_MARKER` -If you see one of these in returned data then something has gone very wrong. -The database is damaged or was generated incorrectly or there is a bug in the +If you see one of these in returned data then something has gone very wrong. The +database is damaged or was generated incorrectly or there is a bug in the libmaxminddb code. ### Pointer Values and `MMDB_close()` The `utf8_string`, `bytes`, and (maybe) the `uint128` members of this structure -are all pointers directly into the database's data section. This can either be -a `calloc`'d or `mmap`'d block of memory. In either case, these pointers will +are all pointers directly into the database's data section. This can either be a +`calloc`'d or `mmap`'d block of memory. In either case, these pointers will become invalid after `MMDB_close()` is called. -If you need to refer to this data after that time you should copy the data -with an appropriate function (`strdup`, `memcpy`, etc.). +If you need to refer to this data after that time you should copy the data with +an appropriate function (`strdup`, `memcpy`, etc.). ## `MMDB_entry_data_list_s` @@ -324,14 +327,14 @@ typedef struct MMDB_entry_data_list_s { } MMDB_entry_data_list_s; ``` -This structure lets you look at entire map or array data entry by iterating -over the linked list. +This structure lets you look at entire map or array data entry by iterating over +the linked list. ## `MMDB_search_node_s` This structure encapsulates the two records in a search node. This is really -only useful if you want to write code that iterates over the entire search -tree as opposed to looking up a specific IP address. +only useful if you want to write code that iterates over the entire search tree +as opposed to looking up a specific IP address. ```c typedef struct MMDB_search_node_s { @@ -346,14 +349,14 @@ typedef struct MMDB_search_node_s { The two record types will take one of the following values: -* `MMDB_RECORD_TYPE_SEARCH_NODE` - The record points to the next search node. -* `MMDB_RECORD_TYPE_EMPTY` - The record is a placeholder that indicates there - is no data for the IP address. The search should end here. -* `MMDB_RECORD_TYPE_DATA` - The record is for data in the data section of the +- `MMDB_RECORD_TYPE_SEARCH_NODE` - The record points to the next search node. +- `MMDB_RECORD_TYPE_EMPTY` - The record is a placeholder that indicates there is + no data for the IP address. The search should end here. +- `MMDB_RECORD_TYPE_DATA` - The record is for data in the data section of the database. Use the entry for the record when looking up the data for the record. -* `MMDB_RECORD_TYPE_INVALID` - The record is invalid. Either an invalid node - was looked up or the database is corrupt. +- `MMDB_RECORD_TYPE_INVALID` - The record is invalid. Either an invalid node was + looked up or the database is corrupt. The `MMDB_entry_s` for the record is only valid if the type is `MMDB_RECORD_TYPE_DATA`. Attempts to use an entry for other record types will @@ -364,33 +367,32 @@ result in an error or invalid data. This library returns (or populates) status codes for many functions. These status codes are: -* `MMDB_SUCCESS` - everything worked -* `MMDB_FILE_OPEN_ERROR` - there was an error trying to open the MaxMind DB +- `MMDB_SUCCESS` - everything worked +- `MMDB_FILE_OPEN_ERROR` - there was an error trying to open the MaxMind DB file. -* `MMDB_IO_ERROR` - an IO operation failed. Check `errno` for more details. -* `MMDB_CORRUPT_SEARCH_TREE_ERROR` - looking up an IP address in the search - tree gave us an impossible result. The database is damaged or was generated +- `MMDB_IO_ERROR` - an IO operation failed. Check `errno` for more details. +- `MMDB_CORRUPT_SEARCH_TREE_ERROR` - looking up an IP address in the search tree + gave us an impossible result. The database is damaged or was generated incorrectly or there is a bug in the libmaxminddb code. -* `MMDB_INVALID_METADATA_ERROR` - something in the database is wrong. This +- `MMDB_INVALID_METADATA_ERROR` - something in the database is wrong. This includes missing metadata keys as well as impossible values (like an `ip_version` of 7). -* `MMDB_UNKNOWN_DATABASE_FORMAT_ERROR` - The database metadata indicates that - it's major version is not 2. This library can only handle major version 2. -* `MMDB_OUT_OF_MEMORY_ERROR` - a memory allocation call (`malloc`, etc.) - failed. -* `MMDB_INVALID_DATA_ERROR` - an entry in the data section contains invalid +- `MMDB_UNKNOWN_DATABASE_FORMAT_ERROR` - The database metadata indicates that + its major version is not 2. This library can only handle major version 2. +- `MMDB_OUT_OF_MEMORY_ERROR` - a memory allocation call (`malloc`, etc.) failed. +- `MMDB_INVALID_DATA_ERROR` - an entry in the data section contains invalid data. For example, a `uint16` field is claiming to be more than 2 bytes long. The database is probably damaged or was generated incorrectly. -* `MMDB_INVALID_LOOKUP_PATH_ERROR` - The lookup path passed to - `MMDB_get_value`, `MMDB_vget_value`, or `MMDB_aget_value` contains an array - offset that is larger than LONG_MAX or smaller than LONG_MIN. -* `MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR` - The lookup path passed to +- `MMDB_INVALID_LOOKUP_PATH_ERROR` - The lookup path passed to `MMDB_get_value`, + `MMDB_vget_value`, or `MMDB_aget_value` contains an array offset that is + larger than LONG_MAX or smaller than LONG_MIN. +- `MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR` - The lookup path passed to `MMDB_get_value`,`MMDB_vget_value`, or `MMDB_aget_value` does not match the - data structure for the entry. There are number of reasons this can - happen. The lookup path could include a key not in a map. The lookup path - could include an array index larger than an array or smaller than the - minimum offset from the end of an array. It can also happen when the path - expects to find a map or array where none exist. + data structure for the entry. There are number of reasons this can happen. The + lookup path could include a key not in a map. The lookup path could include an + array index larger than an array or smaller than the minimum offset from the + end of an array. It can also happen when the path expects to find a map or + array where none exist. All status codes should be treated as `int` values. @@ -416,8 +418,8 @@ int MMDB_open( MMDB_s *const mmdb); ``` -This function opens a handle to a MaxMind DB file. Its return value is a -status code as defined above. Always check this call's return value. +This function opens a handle to a MaxMind DB file. Its return value is a status +code as defined above. Always check this call's return value. ```c MMDB_s mmdb; @@ -431,14 +433,14 @@ MMDB_close(&mmdb); `filename` must be encoded as UTF-8 on Windows. The `MMDB_s` structure you pass in can be on the stack or allocated from the -heap. However, if the open is successful it will contain heap-allocated data, -so you need to close it with `MMDB_close()`. If the status returned is not +heap. However, if the open is successful it will contain heap-allocated data, so +you need to close it with `MMDB_close()`. If the status returned is not `MMDB_SUCCESS` then this library makes sure that all allocated memory is freed before returning. The flags currently provided are: -* `MMDB_MODE_MMAP` - open the database with `mmap()`. +- `MMDB_MODE_MMAP` - open the database with `mmap()`. Passing in other values for `flags` may yield unpredictable results. In the future we may add additional flags that you can bitwise-or together with the @@ -455,24 +457,24 @@ void MMDB_close(MMDB_s *const mmdb); ``` This frees any allocated or mmap'd memory that is held from the `MMDB_s` -structure. *It does not free the memory allocated for the structure itself!* -If you allocated the structure from the heap then you are responsible for -freeing it. +structure. _It does not free the memory allocated for the structure itself!_ If +you allocated the structure from the heap then you are responsible for freeing +it. ## `MMDB_lookup_string()` ```c MMDB_lookup_result_s MMDB_lookup_string( - MMDB_s *const mmdb, + const MMDB_s *const mmdb, const char *const ipstr, int *const gai_error, int *const mmdb_error); ``` This function looks up an IP address that is passed in as a null-terminated -string. Internally it calls `getaddrinfo()` to resolve the address into a -binary form. It then calls `MMDB_lookup_sockaddr()` to look the address up in -the database. If you have already resolved an address you can call +string. Internally it calls `getaddrinfo()` to resolve the address into a binary +form. It then calls `MMDB_lookup_sockaddr()` to look the address up in the +database. If you have already resolved an address you can call `MMDB_lookup_sockaddr()` directly, rather than resolving the address twice. ```c @@ -485,20 +487,20 @@ if (MMDB_SUCCESS != mmdb_error) { ... } if (result.found_entry) { ... } ``` -This function always returns an `MMDB_lookup_result_s` structure, but you -should also check the `gai_error` and `mmdb_error` parameters. If either of -these indicates an error then the returned structure is meaningless. +This function always returns an `MMDB_lookup_result_s` structure, but you should +also check the `gai_error` and `mmdb_error` parameters. If either of these +indicates an error then the returned structure is meaningless. -When `*gai_error` is non-zero (i.e., `getaddrinfo()` failed), `*mmdb_error` -is set to `MMDB_SUCCESS` because no database error occurred. You should always +When `*gai_error` is non-zero (i.e., `getaddrinfo()` failed), `*mmdb_error` is +set to `MMDB_SUCCESS` because no database error occurred. You should always check `*gai_error` first. If no error occurred you still need to make sure that the `found_entry` member -in the returned result is true. If it's not, this means that the IP address -does not have an entry in the database. +in the returned result is true. If it's not, this means that the IP address does +not have an entry in the database. -This function will work with IPv4 addresses even when the database contains -data for both IPv4 and IPv6 addresses. The IPv4 address will be looked up as +This function will work with IPv4 addresses even when the database contains data +for both IPv4 and IPv6 addresses. The IPv4 address will be looked up as '::xxx.xxx.xxx.xxx' rather than being remapped to the `::ffff:xxx.xxx.xxx.xxx` block allocated for IPv4-mapped IPv6 addresses. @@ -510,7 +512,7 @@ If you pass an IPv6 address to a database with only IPv4 data then the ```c MMDB_lookup_result_s MMDB_lookup_sockaddr( - MMDB_s *const mmdb, + const MMDB_s *const mmdb, const struct sockaddr *const sockaddr, int *const mmdb_error); ``` @@ -518,8 +520,8 @@ MMDB_lookup_result_s MMDB_lookup_sockaddr( This function looks up an IP address that has already been resolved by `getaddrinfo()`. -Other than not calling `getaddrinfo()` itself, this function is identical to -the `MMDB_lookup_string()` function. +Other than not calling `getaddrinfo()` itself, this function is identical to the +`MMDB_lookup_string()` function. ```c int mmdb_error; @@ -549,17 +551,17 @@ int MMDB_aget_value( const char *const *const path); ``` -The three functions allow three slightly different calling styles, but they -all do the same thing. +The three functions allow three slightly different calling styles, but they all +do the same thing. -The first parameter is an `MMDB_entry_s` value. In most cases this will come -from the `MMDB_lookup_result_s` value returned by `MMDB_lookup_string()` or -`MMDB_lookup_sockaddr()`. +The first parameter is a pointer to an `MMDB_entry_s` struct. In most cases this +will be a pointer to the `entry` field of the `MMDB_lookup_result_s` value +returned by `MMDB_lookup_string()` or `MMDB_lookup_sockaddr()`. The second parameter is a reference to an `MMDB_entry_data_s` structure. This will be populated with the data that is being looked up, if any is found. If -nothing is found, then the `has_data` member of this structure will be false. -If `has_data` is true then you can look at the `data_type` member. +nothing is found, then the `has_data` member of this structure will be false. If +`has_data` is true then you can look at the `type` member. The final parameter is a lookup path. The path consists of a set of strings representing either map keys (e.g, "city") or array indexes (e.g., "0", "1", @@ -594,26 +596,30 @@ if (MMDB_SUCCESS != status) { ... } if (entry_data.has_data) { ... } ``` -If we wanted to find the first city the lookup path would be `"cities", -"0"`. If you don't provide a lookup path at all, you'll get the entry which -corresponds to the top level map. The lookup path must always end with `NULL`, -regardless of which function you call. +If we wanted to find the first city the lookup path would be `"cities", "0"`. If +you don't provide a lookup path at all, you'll get the entry which corresponds +to the top level map. The lookup path must always end with `NULL`, regardless of +which function you call. The `MMDB_get_value` function takes a variable number of arguments. All of the -arguments after the `MMDB_entry_data_s *` structure pointer are the lookup -path. The last argument must be `NULL`. +arguments after the `MMDB_entry_data_s *` structure pointer are the lookup path. +The last argument must be `NULL`. -The `MMDB_vget_value` function accepts a `va_list` as the lookup path. The -last element retrieved by `va_arg()` must be `NULL`. +The `MMDB_vget_value` function accepts a `va_list` as the lookup path. The last +element retrieved by `va_arg()` must be `NULL`. -Finally, the `MMDB_aget_value` accepts an array of strings as the lookup -path. The last member of this array must be `NULL`. +Finally, the `MMDB_aget_value` accepts an array of strings as the lookup path. +The last member of this array must be `NULL`. -If you want to get all of the entry data at once you can call -`MMDB_get_entry_data_list()` instead. +To look up multiple keys within the same map, use the full lookup path for each +key. For example, to get both the `en` and `de` values from the `names` map, +make separate calls with `"names", "en", NULL` and `"names", "de", NULL`. If you +need all of the data from a complex structure rather than specific values, +`MMDB_get_entry_data_list()` is more efficient than making many individual +calls. -For each of the three functions, the return value is a status code as -defined above. +For each of the three functions, the return value is a status code as defined +above. ## `MMDB_get_entry_data_list()` @@ -623,8 +629,12 @@ int MMDB_get_entry_data_list( MMDB_entry_data_list_s **const entry_data_list); ``` -This function allows you to get all of the data for a complex data structure -at once, rather than looking up each piece using repeated calls to +The `start` parameter is a pointer to an `MMDB_entry_s` struct. In most cases +this will be a pointer to the `entry` field of the `MMDB_lookup_result_s` value +returned by `MMDB_lookup_string()` or `MMDB_lookup_sockaddr()`. + +This function allows you to get all of the data for a complex data structure at +once, rather than looking up each piece using repeated calls to `MMDB_get_value()`. ```c @@ -698,7 +708,7 @@ function to free the `MMDB_entry_data_list_s` structure. ```c int MMDB_get_metadata_as_entry_data_list( - MMDB_s *const mmdb, + const MMDB_s *const mmdb, MMDB_entry_data_list_s **const entry_data_list); ``` @@ -733,16 +743,16 @@ indent level for the generated output. It is incremented for nested data structures (maps, array, etc.). The `stream` must be a file handle (`stdout`, etc). If your platform provides -something like the GNU `open_memstream()` you can use that to capture the -output as a string. +something like the GNU `open_memstream()` you can use that to capture the output +as a string. The output is formatted in a JSON-ish fashion, but values are marked with their data type (except for maps and arrays which are shown with "{}" and "[]" respectively). -The specific output format may change in future releases, so you should not -rely on the specific formatting produced by this function. It is intended to be -used to show data to users in a readable way and for debugging purposes. +The specific output format may change in future releases, so you should not rely +on the specific formatting produced by this function. It is intended to be used +to show data to users in a readable way and for debugging purposes. The return value of the function is a status code as defined above. @@ -750,24 +760,23 @@ The return value of the function is a status code as defined above. ```c int MMDB_read_node( - MMDB_s *const mmdb, + const MMDB_s *const mmdb, uint32_t node_number, MMDB_search_node_s *const node); ``` -This reads a specific node in the search tree. The third argument is a -reference to an `MMDB_search_node_s` structure that will be populated by this -function. +This reads a specific node in the search tree. The third argument is a reference +to an `MMDB_search_node_s` structure that will be populated by this function. The return value is a status code. If you pass a `node_number` that is greater -than the number of nodes in the database, this function will return +than or equal to the number of nodes in the database, this function will return `MMDB_INVALID_NODE_NUMBER_ERROR`, otherwise it will return `MMDB_SUCCESS`. The first node in the search tree is always node 0. If you wanted to iterate -over the whole search tree, you would start by reading node 0 and then -following the the records that make up this node, based on the type of each -record. If the type is `MMDB_RECORD_TYPE_SEARCH_NODE` then the record contains -an integer for the next node to look up. +over the whole search tree, you would start by reading node 0 and then following +the records that make up this node, based on the type of each record. If the +type is `MMDB_RECORD_TYPE_SEARCH_NODE` then the record contains an integer for +the next node to look up. ## `MMDB_lib_version()` @@ -857,13 +866,13 @@ int main(int argc, char **argv) # REQUIREMENTS -libmaxminddb requires a minimum of POSIX.1-2001 support. If not specified -at compilation time, it defaults to requesting POSIX.1-2008 support. +libmaxminddb requires a minimum of POSIX.1-2001 support. If not specified at +compilation time, it defaults to requesting POSIX.1-2008 support. # THREAD SAFETY -This library is thread safe when compiled and linked with a thread-safe -`malloc` and `free` implementation. +This library is thread safe when compiled and linked with a thread-safe `malloc` +and `free` implementation. # INSTALLATION AND SOURCE @@ -882,24 +891,23 @@ greatly preferred over patches. # AUTHORS -This library was written by Boris Zentner (bzentner@maxmind.com) and Dave -Rolsky (drolsky@maxmind.com). +This library was written by Boris Zentner (bzentner@maxmind.com) and Dave Rolsky +(drolsky@maxmind.com). # COPYRIGHT AND LICENSE Copyright 2013-2025 MaxMind, Inc. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at https://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. # SEE ALSO diff --git a/doc/mmdblookup.md b/doc/mmdblookup.md index f48446be..81c0ee00 100644 --- a/doc/mmdblookup.md +++ b/doc/mmdblookup.md @@ -8,14 +8,14 @@ mmdblookup --file [FILE PATH] --ip [IP ADDRESS] [DATA PATH] # DESCRIPTION -`mmdblookup` looks up an IP address in the specified MaxMind DB file. The -record for the IP address is displayed with `{}` to denote maps and `[]` to -denote arrays. The values are followed by type annotations. This output is -_not_ JSON and is not intended to be used as such. If you need JSON, please -see [`mmdbinspect`](https://github.com/maxmind/mmdbinspect). +`mmdblookup` looks up an IP address in the specified MaxMind DB file. The record +for the IP address is displayed with `{}` to denote maps and `[]` to denote +arrays. The values are followed by type annotations. This output is _not_ JSON +and is not intended to be used as such. If you need JSON, please see +[`mmdbinspect`](https://github.com/maxmind/mmdbinspect). -If an IP's data entry resolves to a map or array, you can provide a lookup -path to only show part of that data. +If an IP's data entry resolves to a map or array, you can provide a lookup path +to only show part of that data. For example, given a JSON structure like this: @@ -29,8 +29,8 @@ For example, given a JSON structure like this: } ``` -You could look up just the English name by calling mmdblookup with a lookup -path of: +You could look up just the English name by calling mmdblookup with a lookup path +of: ```bash mmdblookup --file ... --ip ... names en @@ -53,24 +53,24 @@ This application accepts the following options: -f, --file -: The path to the MMDB file. Required. +: The path to the MMDB file. Required. -i, --ip -: The IP address to look up. Required. +: The IP address to look up. Required. -v, --verbose -: Turns on verbose output. Specifically, this causes this - application to output the database metadata. +: Turns on verbose output. Specifically, this causes this application to output +the database metadata. --version -: Print the program's version number and exit. +: Print the program's version number and exit. -h, -?, --help -: Show usage information. +: Show usage information. # BUG REPORTS AND PULL REQUESTS @@ -81,24 +81,23 @@ greatly preferred over patches. # AUTHORS -This utility was written by Boris Zentner (bzentner@maxmind.com) and Dave -Rolsky (drolsky@maxmind.com). +This utility was written by Boris Zentner (bzentner@maxmind.com) and Dave Rolsky +(drolsky@maxmind.com). # COPYRIGHT AND LICENSE Copyright 2013-2025 MaxMind, Inc. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at https://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. # SEE ALSO diff --git a/mise.lock b/mise.lock new file mode 100644 index 00000000..2fa928ac --- /dev/null +++ b/mise.lock @@ -0,0 +1,283 @@ +[conda-packages.linux-arm64."linux-aarch64/_openmp_mutex-4.5-3_kmp_llvm"] +url = "https://api.anaconda.org/download/conda-forge/_openmp_mutex/4.5/linux-aarch64/_openmp_mutex-4.5-3_kmp_llvm.conda" +checksum = "sha256:5ec4d1d1dca8cc57e48132ec795e1df96082a7a69037f07add30d73d388df6ff" + +[conda-packages.linux-arm64."linux-aarch64/clang-format-21-21.1.8-default_he95a3c9_0"] +url = "https://api.anaconda.org/download/conda-forge/clang-format-21/21.1.8/linux-aarch64/clang-format-21-21.1.8-default_he95a3c9_0.conda" +checksum = "sha256:7c6a8aaedba28f3c769f8288bab62b07b843c0ca0c98241275db07e396915f0a" + +[conda-packages.linux-arm64."linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_0"] +url = "https://api.anaconda.org/download/conda-forge/libclang-cpp21.1/21.1.8/linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_0.conda" +checksum = "sha256:969c7267ea4bfc4e2bed5470fe0f22d76f7a85f9ccbefb7f8272adb938d97d00" + +[conda-packages.linux-arm64."linux-aarch64/libgcc-15.2.0-he277a41_5"] +url = "https://api.anaconda.org/download/conda-forge/libgcc/15.2.0/linux-aarch64/libgcc-15.2.0-he277a41_5.conda" +checksum = "sha256:827fb84fdd38bb16ee0d45d81b95203c6abaf4dc3c02f1ed77017969038ceba6" + +[conda-packages.linux-arm64."linux-aarch64/libiconv-1.18-hc99b53d_0"] +url = "https://api.anaconda.org/download/conda-forge/libiconv/1.18/linux-aarch64/libiconv-1.18-hc99b53d_0.conda" +checksum = "sha256:c1d8421dbdf98d1ff4631130278ac95c9fe204630ca536c8eefd2be3912c89c0" + +[conda-packages.linux-arm64."linux-aarch64/libllvm21-21.1.8-hfd2ba90_0"] +url = "https://api.anaconda.org/download/conda-forge/libllvm21/21.1.8/linux-aarch64/libllvm21-21.1.8-hfd2ba90_0.conda" +checksum = "sha256:5af18365698a9093a81490de16c97a0af5318e20086b74998718f1e5d7566e74" + +[conda-packages.linux-arm64."linux-aarch64/liblzma-5.8.2-he30d5cf_0"] +url = "https://api.anaconda.org/download/conda-forge/liblzma/5.8.2/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda" +checksum = "sha256:843c46e20519651a3e357a8928352b16c5b94f4cd3d5481acc48be2e93e8f6a3" + +[conda-packages.linux-arm64."linux-aarch64/libstdcxx-15.2.0-h3f4de04_5"] +url = "https://api.anaconda.org/download/conda-forge/libstdcxx/15.2.0/linux-aarch64/libstdcxx-15.2.0-h3f4de04_5.conda" +checksum = "sha256:3f33a34cc50d6a44972f18465e9cb5cb1b4d77cc6f55ac847b8fda871f3ed2a7" + +[conda-packages.linux-arm64."linux-aarch64/libxml2-16-2.15.1-h064b767_0"] +url = "https://api.anaconda.org/download/conda-forge/libxml2-16/2.15.1/linux-aarch64/libxml2-16-2.15.1-h064b767_0.conda" +checksum = "sha256:0bd3eed5acc8aff346d8d7fb52b16652f75ed2543e36636e48a263c418b9204d" + +[conda-packages.linux-arm64."linux-aarch64/libxml2-2.15.1-h49afab2_0"] +url = "https://api.anaconda.org/download/conda-forge/libxml2/2.15.1/linux-aarch64/libxml2-2.15.1-h49afab2_0.conda" +checksum = "sha256:546238fa1ece20ba6b318957bf949fc135f31d66457a85369591e0e84033b47f" + +[conda-packages.linux-arm64."linux-aarch64/libzlib-1.3.1-h31becfc_0"] +url = "https://api.anaconda.org/download/conda-forge/libzlib/1.3.1/linux-aarch64/libzlib-1.3.1-h31becfc_0.conda" +checksum = "sha256:96f87f3ff22727997a9614d50f1b9ca76798e2df70002966c04690d49a207995" + +[conda-packages.linux-arm64."linux-aarch64/llvm-openmp-22.1.0.rc2-h89bea51_0"] +url = "https://api.anaconda.org/download/conda-forge/llvm-openmp/22.1.0.rc2/linux-aarch64/llvm-openmp-22.1.0.rc2-h89bea51_0.conda" +checksum = "sha256:848fe110c9c48b2de3851ea45aeb0228ed3efece55651c6e5e7fc6e5cd0eaa18" + +[conda-packages.linux-arm64."linux-aarch64/zstd-1.5.7-hbcf94c1_0"] +url = "https://api.anaconda.org/download/conda-forge/zstd/1.5.7/linux-aarch64/zstd-1.5.7-hbcf94c1_0.conda" +checksum = "sha256:ea29fd955df64170ff3adcfba833bc3c9784e5539459f4d8e6418f7eed235687" + +[conda-packages.linux-x64."linux-64/_openmp_mutex-4.5-3_kmp_llvm"] +url = "https://api.anaconda.org/download/conda-forge/_openmp_mutex/4.5/linux-64/_openmp_mutex-4.5-3_kmp_llvm.conda" +checksum = "sha256:cec7343e76c9da6a42c7e7cba53391daa6b46155054ef61a5ef522ea27c5a058" + +[conda-packages.linux-x64."linux-64/clang-format-21-21.1.8-default_h99862b1_0"] +url = "https://api.anaconda.org/download/conda-forge/clang-format-21/21.1.8/linux-64/clang-format-21-21.1.8-default_h99862b1_0.conda" +checksum = "sha256:d64fa483750cd5a87b0b2f7e7af7b549d64aa28a1aefad28d7958d8b3f1e9c0f" + +[conda-packages.linux-x64."linux-64/icu-75.1-he02047a_0"] +url = "https://api.anaconda.org/download/conda-forge/icu/75.1/linux-64/icu-75.1-he02047a_0.conda" +checksum = "sha256:71e750d509f5fa3421087ba88ef9a7b9be11c53174af3aa4d06aff4c18b38e8e" + +[conda-packages.linux-x64."linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_0"] +url = "https://api.anaconda.org/download/conda-forge/libclang-cpp21.1/21.1.8/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_0.conda" +checksum = "sha256:e1db2f22479bff125d2e1b4241a91f3d039f240ace78285ffd6a32c9b3ceba13" + +[conda-packages.linux-x64."linux-64/libgcc-15.2.0-h767d61c_5"] +url = "https://api.anaconda.org/download/conda-forge/libgcc/15.2.0/linux-64/libgcc-15.2.0-h767d61c_5.conda" +checksum = "sha256:cf6c34d2c024f1a28ad48f9a352ffbed5dfd0767be0fae50c4ccaa96f2538116" + +[conda-packages.linux-x64."linux-64/libiconv-1.18-h4ce23a2_0"] +url = "https://api.anaconda.org/download/conda-forge/libiconv/1.18/linux-64/libiconv-1.18-h4ce23a2_0.conda" +checksum = "sha256:659a83c0c184a30336ca512d670a7db56bfb5e289caa9ee641e6f78fd2326463" + +[conda-packages.linux-x64."linux-64/libllvm21-21.1.8-hf7376ad_0"] +url = "https://api.anaconda.org/download/conda-forge/libllvm21/21.1.8/linux-64/libllvm21-21.1.8-hf7376ad_0.conda" +checksum = "sha256:91bb4f5be1601b40b4995911d785e29387970f0b3c80f33f7f9028f95335399f" + +[conda-packages.linux-x64."linux-64/liblzma-5.8.2-hb03c661_0"] +url = "https://api.anaconda.org/download/conda-forge/liblzma/5.8.2/linux-64/liblzma-5.8.2-hb03c661_0.conda" +checksum = "sha256:755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb" + +[conda-packages.linux-x64."linux-64/libstdcxx-15.2.0-h8f9b012_5"] +url = "https://api.anaconda.org/download/conda-forge/libstdcxx/15.2.0/linux-64/libstdcxx-15.2.0-h8f9b012_5.conda" +checksum = "sha256:803eb5a488314b5e127f014001279795ad0e9a2a096f4a0c84d20bc543109104" + +[conda-packages.linux-x64."linux-64/libxml2-16-2.15.1-ha9997c6_0"] +url = "https://api.anaconda.org/download/conda-forge/libxml2-16/2.15.1/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda" +checksum = "sha256:71436e72a286ef8b57d6f4287626ff91991eb03c7bdbe835280521791efd1434" + +[conda-packages.linux-x64."linux-64/libxml2-2.15.1-h26afc86_0"] +url = "https://api.anaconda.org/download/conda-forge/libxml2/2.15.1/linux-64/libxml2-2.15.1-h26afc86_0.conda" +checksum = "sha256:ec0735ae56c3549149eebd7dc22c0bed91fd50c02eaa77ff418613ddda190aa8" + +[conda-packages.linux-x64."linux-64/libzlib-1.3.1-hd590300_0"] +url = "https://api.anaconda.org/download/conda-forge/libzlib/1.3.1/linux-64/libzlib-1.3.1-hd590300_0.conda" +checksum = "sha256:9df76697b6fe2228711283c0dda589354d5df633726db2fca7f7841dd5e50c82" + +[conda-packages.linux-x64."linux-64/llvm-openmp-22.1.0.rc2-h905f809_0"] +url = "https://api.anaconda.org/download/conda-forge/llvm-openmp/22.1.0.rc2/linux-64/llvm-openmp-22.1.0.rc2-h905f809_0.conda" +checksum = "sha256:53445bf1496578efa084f48e776812b5a76c96ab1c9130a51d8f53fa25abff12" + +[conda-packages.linux-x64."linux-64/zstd-1.5.7-hb8e6e7a_0"] +url = "https://api.anaconda.org/download/conda-forge/zstd/1.5.7/linux-64/zstd-1.5.7-hb8e6e7a_0.conda" +checksum = "sha256:b8f7b4c7264e84fcedce3929239f5c55e86ae90948c9fdee666f93a70ca58e66" + +[conda-packages.macos-arm64."osx-arm64/clang-format-21-21.1.8-default_hf3020a7_0"] +url = "https://api.anaconda.org/download/conda-forge/clang-format-21/21.1.8/osx-arm64/clang-format-21-21.1.8-default_hf3020a7_0.conda" +checksum = "sha256:21bc990ecd254c3f80f92f57dc25c3a2f9df596fef4296a02f5cda0dc3400aa8" + +[conda-packages.macos-arm64."osx-arm64/icu-75.1-hfee45f7_0"] +url = "https://api.anaconda.org/download/conda-forge/icu/75.1/osx-arm64/icu-75.1-hfee45f7_0.conda" +checksum = "sha256:9ba12c93406f3df5ab0a43db8a4b4ef67a5871dfd401010fbe29b218b2cbe620" + +[conda-packages.macos-arm64."osx-arm64/libclang-cpp21.1-21.1.8-default_hf3020a7_0"] +url = "https://api.anaconda.org/download/conda-forge/libclang-cpp21.1/21.1.8/osx-arm64/libclang-cpp21.1-21.1.8-default_hf3020a7_0.conda" +checksum = "sha256:4a539299d774c62d999d3dac171f9955dcdef10b77713d961bea07e4637faf79" + +[conda-packages.macos-arm64."osx-arm64/libcxx-22.1.0.rc2-h919050e_0"] +url = "https://api.anaconda.org/download/conda-forge/libcxx/22.1.0.rc2/osx-arm64/libcxx-22.1.0.rc2-h919050e_0.conda" +checksum = "sha256:b7d3f1ede1b9ef0fab4d7cc8ecc2e7ac7862e9c98cfd6ab82ffe29e5b736ac17" + +[conda-packages.macos-arm64."osx-arm64/libiconv-1.18-hfe07756_0"] +url = "https://api.anaconda.org/download/conda-forge/libiconv/1.18/osx-arm64/libiconv-1.18-hfe07756_0.conda" +checksum = "sha256:a7e7b90bcf2680e447aa9a17ccbebb07089d4b63d5ab53eb1cd8ddeafb4701c3" + +[conda-packages.macos-arm64."osx-arm64/libllvm21-21.1.8-h8e0c9ce_0"] +url = "https://api.anaconda.org/download/conda-forge/libllvm21/21.1.8/osx-arm64/libllvm21-21.1.8-h8e0c9ce_0.conda" +checksum = "sha256:3f4512155aca799a25937f9ee794490794fb33f8f90a5e6532d8be869e7d79a0" + +[conda-packages.macos-arm64."osx-arm64/liblzma-5.8.2-h8088a28_0"] +url = "https://api.anaconda.org/download/conda-forge/liblzma/5.8.2/osx-arm64/liblzma-5.8.2-h8088a28_0.conda" +checksum = "sha256:7bfc7ffb2d6a9629357a70d4eadeadb6f88fa26ebc28f606b1c1e5e5ed99dc7e" + +[conda-packages.macos-arm64."osx-arm64/libxml2-16-2.15.1-h0ff4647_0"] +url = "https://api.anaconda.org/download/conda-forge/libxml2-16/2.15.1/osx-arm64/libxml2-16-2.15.1-h0ff4647_0.conda" +checksum = "sha256:ebe2dd9da94280ad43da936efa7127d329b559f510670772debc87602b49b06d" + +[conda-packages.macos-arm64."osx-arm64/libxml2-2.15.1-h9329255_0"] +url = "https://api.anaconda.org/download/conda-forge/libxml2/2.15.1/osx-arm64/libxml2-2.15.1-h9329255_0.conda" +checksum = "sha256:c409e384ddf5976a42959265100d6b2c652017d250171eb10bae47ef8166193f" + +[conda-packages.macos-arm64."osx-arm64/libzlib-1.3.1-h0d3ecfb_0"] +url = "https://api.anaconda.org/download/conda-forge/libzlib/1.3.1/osx-arm64/libzlib-1.3.1-h0d3ecfb_0.conda" +checksum = "sha256:9c59bd3f3e3e1900620e3a85c04d3a3699cb93c714333d06cb8afdd7addaae9d" + +[conda-packages.macos-arm64."osx-arm64/zstd-1.5.7-h6491c7d_0"] +url = "https://api.anaconda.org/download/conda-forge/zstd/1.5.7/osx-arm64/zstd-1.5.7-h6491c7d_0.conda" +checksum = "sha256:ee7bbee860b437a214fbdfb4fdf9e48982dc984ad3b0bf2d6480d94c0a8fc8c4" + +[conda-packages.macos-x64."osx-64/clang-format-21-21.1.8-default_hd70426c_0"] +url = "https://api.anaconda.org/download/conda-forge/clang-format-21/21.1.8/osx-64/clang-format-21-21.1.8-default_hd70426c_0.conda" +checksum = "sha256:3e524439f57e848532b75380040fb65c69bcdc8ea606d0c67b3dbddc4351c795" + +[conda-packages.macos-x64."osx-64/icu-75.1-h120a0e1_0"] +url = "https://api.anaconda.org/download/conda-forge/icu/75.1/osx-64/icu-75.1-h120a0e1_0.conda" +checksum = "sha256:2e64307532f482a0929412976c8450c719d558ba20c0962832132fd0d07ba7a7" + +[conda-packages.macos-x64."osx-64/libclang-cpp21.1-21.1.8-default_hd70426c_0"] +url = "https://api.anaconda.org/download/conda-forge/libclang-cpp21.1/21.1.8/osx-64/libclang-cpp21.1-21.1.8-default_hd70426c_0.conda" +checksum = "sha256:feeee046ad79a31c404263221d03804884753fe096a064d3eb12bf6fa2846be0" + +[conda-packages.macos-x64."osx-64/libcxx-22.1.0.rc2-hb6afd73_0"] +url = "https://api.anaconda.org/download/conda-forge/libcxx/22.1.0.rc2/osx-64/libcxx-22.1.0.rc2-hb6afd73_0.conda" +checksum = "sha256:fc211a8a1af379d9a2a839a6932c196eec102632bd1ebc4273fe053b3b0c105e" + +[conda-packages.macos-x64."osx-64/libiconv-1.18-h4b5e92a_0"] +url = "https://api.anaconda.org/download/conda-forge/libiconv/1.18/osx-64/libiconv-1.18-h4b5e92a_0.conda" +checksum = "sha256:63ed6a73653794d19ccd1271c462305ecab446b38b36884b6be96befe3f8876f" + +[conda-packages.macos-x64."osx-64/libllvm21-21.1.8-h56e7563_0"] +url = "https://api.anaconda.org/download/conda-forge/libllvm21/21.1.8/osx-64/libllvm21-21.1.8-h56e7563_0.conda" +checksum = "sha256:b98962b93624f52399aa748cc66dea7d6aae0a20db6decadc979db151928d214" + +[conda-packages.macos-x64."osx-64/liblzma-5.8.2-h11316ed_0"] +url = "https://api.anaconda.org/download/conda-forge/liblzma/5.8.2/osx-64/liblzma-5.8.2-h11316ed_0.conda" +checksum = "sha256:7ab3c98abd3b5d5ec72faa8d9f5d4b50dcee4970ed05339bc381861199dabb41" + +[conda-packages.macos-x64."osx-64/libxml2-16-2.15.1-ha1d9b0f_0"] +url = "https://api.anaconda.org/download/conda-forge/libxml2-16/2.15.1/osx-64/libxml2-16-2.15.1-ha1d9b0f_0.conda" +checksum = "sha256:e23c5ac1da7b9b65bd18bf32b68717cd9da0387941178cb4d8cc5513eb69a0a9" + +[conda-packages.macos-x64."osx-64/libxml2-2.15.1-h7b7ecba_0"] +url = "https://api.anaconda.org/download/conda-forge/libxml2/2.15.1/osx-64/libxml2-2.15.1-h7b7ecba_0.conda" +checksum = "sha256:ddf87bf05955d7870a41ca6f0e9fbd7b896b5a26ec1a98cd990883ac0b4f99bb" + +[conda-packages.macos-x64."osx-64/libzlib-1.3.1-hd75f5a5_0"] +url = "https://api.anaconda.org/download/conda-forge/libzlib/1.3.1/osx-64/libzlib-1.3.1-hd75f5a5_0.conda" +checksum = "sha256:49fd2bde256952ab6a8265f3b2978ae624db1f096e3340253699e2534426244a" + +[conda-packages.macos-x64."osx-64/zstd-1.5.7-h8210216_0"] +url = "https://api.anaconda.org/download/conda-forge/zstd/1.5.7/osx-64/zstd-1.5.7-h8210216_0.conda" +checksum = "sha256:644095227a3dd4559a07ce3f33d660d7e21f5e6b2a4227ce835fa156a4528a92" + +[[tools."conda:clang-format"]] +version = "21.1.8" +backend = "conda:clang-format" +"platforms.linux-arm64" = { checksum = "sha256:f36140c5cfa875bf9981a0fd978c54706227d15c93bedb6fa43c131b7e764b46", conda_deps = [ + "linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_0", + "linux-aarch64/libgcc-15.2.0-he277a41_5", + "linux-aarch64/libzlib-1.3.1-h31becfc_0", + "linux-aarch64/libstdcxx-15.2.0-h3f4de04_5", + "linux-aarch64/zstd-1.5.7-hbcf94c1_0", + "linux-aarch64/liblzma-5.8.2-he30d5cf_0", + "linux-aarch64/_openmp_mutex-4.5-3_kmp_llvm", + "linux-aarch64/libxml2-16-2.15.1-h064b767_0", + "linux-aarch64/libiconv-1.18-hc99b53d_0", + "linux-aarch64/llvm-openmp-22.1.0.rc2-h89bea51_0", + "linux-aarch64/libllvm21-21.1.8-hfd2ba90_0", + "linux-aarch64/libxml2-2.15.1-h49afab2_0", + "linux-aarch64/clang-format-21-21.1.8-default_he95a3c9_0", +], url = "https://api.anaconda.org/download/conda-forge/clang-format/21.1.8/linux-aarch64/clang-format-21.1.8-default_he95a3c9_0.conda"} +"platforms.linux-x64" = { checksum = "sha256:7dde9b7439f38d239a827f71136f6a172d324fef183fb3ad334efb1701f62f2e", conda_deps = [ + "linux-64/zstd-1.5.7-hb8e6e7a_0", + "linux-64/clang-format-21-21.1.8-default_h99862b1_0", + "linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_0", + "linux-64/libstdcxx-15.2.0-h8f9b012_5", + "linux-64/llvm-openmp-22.1.0.rc2-h905f809_0", + "linux-64/libiconv-1.18-h4ce23a2_0", + "linux-64/icu-75.1-he02047a_0", + "linux-64/liblzma-5.8.2-hb03c661_0", + "linux-64/libxml2-2.15.1-h26afc86_0", + "linux-64/libgcc-15.2.0-h767d61c_5", + "linux-64/libllvm21-21.1.8-hf7376ad_0", + "linux-64/_openmp_mutex-4.5-3_kmp_llvm", + "linux-64/libzlib-1.3.1-hd590300_0", + "linux-64/libxml2-16-2.15.1-ha9997c6_0", +], url = "https://api.anaconda.org/download/conda-forge/clang-format/21.1.8/linux-64/clang-format-21.1.8-default_h99862b1_0.conda"} +"platforms.macos-arm64" = { checksum = "sha256:f968186fa56331fc1bbe6a5ced9eba08bb50c57e780e3daea863773e8b59d32f", conda_deps = [ + "osx-arm64/libxml2-2.15.1-h9329255_0", + "osx-arm64/liblzma-5.8.2-h8088a28_0", + "osx-arm64/libcxx-22.1.0.rc2-h919050e_0", + "osx-arm64/icu-75.1-hfee45f7_0", + "osx-arm64/libxml2-16-2.15.1-h0ff4647_0", + "osx-arm64/libllvm21-21.1.8-h8e0c9ce_0", + "osx-arm64/zstd-1.5.7-h6491c7d_0", + "osx-arm64/libzlib-1.3.1-h0d3ecfb_0", + "osx-arm64/clang-format-21-21.1.8-default_hf3020a7_0", + "osx-arm64/libclang-cpp21.1-21.1.8-default_hf3020a7_0", + "osx-arm64/libiconv-1.18-hfe07756_0", +], url = "https://api.anaconda.org/download/conda-forge/clang-format/21.1.8/osx-arm64/clang-format-21.1.8-default_hf3020a7_0.conda"} +"platforms.macos-x64" = { checksum = "sha256:477805cf0016cfa9738936f76d85970daefee72a1a9f2276df1a34581073b135", conda_deps = [ + "osx-64/libzlib-1.3.1-hd75f5a5_0", + "osx-64/clang-format-21-21.1.8-default_hd70426c_0", + "osx-64/libclang-cpp21.1-21.1.8-default_hd70426c_0", + "osx-64/icu-75.1-h120a0e1_0", + "osx-64/zstd-1.5.7-h8210216_0", + "osx-64/libiconv-1.18-h4b5e92a_0", + "osx-64/libxml2-16-2.15.1-ha1d9b0f_0", + "osx-64/liblzma-5.8.2-h11316ed_0", + "osx-64/libllvm21-21.1.8-h56e7563_0", + "osx-64/libcxx-22.1.0.rc2-hb6afd73_0", + "osx-64/libxml2-2.15.1-h7b7ecba_0", +], url = "https://api.anaconda.org/download/conda-forge/clang-format/21.1.8/osx-64/clang-format-21.1.8-default_hd70426c_0.conda"} +"platforms.windows-x64" = { checksum = "sha256:dd8855c6b01dd986d55b67cef7b9532749493aeebbbb70fdc3f2b6cd348981e0", url = "https://api.anaconda.org/download/conda-forge/clang-format/21.1.8/win-64/clang-format-21.1.8-default_hac490eb_0.conda"} + +[[tools."github:houseabsolute/precious"]] +version = "0.10.2" +backend = "github:houseabsolute/precious" +"platforms.linux-arm64" = { checksum = "sha256:8fbaead9f9626170549c3121e67d1bc81193b3bb086e29576f548aefa839fcc4", url = "https://github.com/houseabsolute/precious/releases/download/v0.10.2/precious-Linux-musl-arm64.tar.gz", url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/345520042"} +"platforms.linux-x64" = { checksum = "sha256:3d717d906db338f63017766b07982dc9055773e1b3bec6d3f432d1f0ad9676bb", url = "https://github.com/houseabsolute/precious/releases/download/v0.10.2/precious-Linux-musl-x86_64.tar.gz", url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/345519861"} +"platforms.macos-arm64" = { checksum = "sha256:04157c64459bb6ab029295b21b112077040ad2575b34508d84b19a839551cddb", url = "https://github.com/houseabsolute/precious/releases/download/v0.10.2/precious-macOS-arm64.tar.gz", url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/345519985"} +"platforms.macos-x64" = { checksum = "sha256:9932defd246d0771530357463bdb55582557fd7381853cb4dc2074e36ad0cc84", url = "https://github.com/houseabsolute/precious/releases/download/v0.10.2/precious-macOS-x86_64.tar.gz", url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/345519772"} +"platforms.windows-x64" = { checksum = "sha256:9d683d1730e302c646ccb90a23d313e7a548c8b23b5abf7d24e19ff6befe763d", url = "https://github.com/houseabsolute/precious/releases/download/v0.10.2/precious-Windows-msvc-x86_64.zip", url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/345520544"} + +[[tools.node]] +version = "25.6.1" +backend = "core:node" +"platforms.linux-arm64" = { checksum = "sha256:90fea701897ecb424aafa2824539476598437ad9f21e649732a85cc2d955d845", url = "https://nodejs.org/dist/v25.6.1/node-v25.6.1-linux-arm64.tar.gz"} +"platforms.linux-x64" = { checksum = "sha256:3809fdbfd54829bad363b9db8e96ca3600509e2ff20ede74181cfc1ca8451ce3", url = "https://nodejs.org/dist/v25.6.1/node-v25.6.1-linux-x64.tar.gz"} +"platforms.macos-arm64" = { checksum = "sha256:a80cb252d170a4730f78f5950cf19a46106f156e5886e5c1cc8c5602aea60243", url = "https://nodejs.org/dist/v25.6.1/node-v25.6.1-darwin-arm64.tar.gz"} +"platforms.macos-x64" = { checksum = "sha256:3b68f847d9d8861c7c8bfef32c540d14f6ca18bfcbf5f6495a595b9529063a9b", url = "https://nodejs.org/dist/v25.6.1/node-v25.6.1-darwin-x64.tar.gz"} +"platforms.windows-x64" = { checksum = "sha256:0ae2300cdf44c399b5b351edbefb3534d1342a6fabd64302ca8c8e2fb86b0445", url = "https://nodejs.org/dist/v25.6.1/node-v25.6.1-win-x64.zip"} + +[[tools."npm:prettier"]] +version = "3.8.1" +backend = "npm:prettier" + +[[tools."pipx:clang-format"]] +version = "21.1.8" +backend = "pipx:clang-format" diff --git a/mise.toml b/mise.toml new file mode 100644 index 00000000..83e93536 --- /dev/null +++ b/mise.toml @@ -0,0 +1,14 @@ +[settings] +lockfile = true +locked = true + +disable_backends = [ + "asdf", + "vfox", +] + +[tools] +node = "latest" +"pipx:clang-format" = "21.1.8" +"github:houseabsolute/precious" = "latest" +"npm:prettier" = "latest" diff --git a/src/data-pool.c b/src/data-pool.c index fb91928b..3bc63286 100644 --- a/src/data-pool.c +++ b/src/data-pool.c @@ -1,5 +1,5 @@ #ifndef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 200809L + #define _POSIX_C_SOURCE 200809L #endif #include "data-pool.h" @@ -146,8 +146,8 @@ MMDB_entry_data_list_s *data_pool_to_list(MMDB_data_pool_s *const pool) { #ifdef TEST_DATA_POOL -#include -#include + #include + #include static void test_can_multiply(void); diff --git a/t/bad_databases_t.c b/t/bad_databases_t.c index 2324f1ec..9ae7d632 100644 --- a/t/bad_databases_t.c +++ b/t/bad_databases_t.c @@ -51,9 +51,7 @@ int test_read(const char *path, MMDB_free_entry_data_list(entry_data_list); if (status != MMDB_SUCCESS) { - ok(1, - "received error from MMDB_get_entry_data_list for %s", - path); + ok(1, "received error from MMDB_get_entry_data_list for %s", path); MMDB_close(mmdb); free(mmdb); return 0; @@ -63,7 +61,9 @@ int test_read(const char *path, // Some bad-data files (e.g. uint64-max-epoch) are valid databases with // extreme metadata values. They don't produce errors in libmaxminddb // but are useful for testing other reader implementations. - ok(1, "no error reading %s (database may have extreme but valid data)", path); + ok(1, + "no error reading %s (database may have extreme but valid data)", + path); MMDB_close(mmdb); free(mmdb); diff --git a/t/bad_search_tree_t.c b/t/bad_search_tree_t.c index 06e8cb85..2ec8dd31 100644 --- a/t/bad_search_tree_t.c +++ b/t/bad_search_tree_t.c @@ -17,8 +17,7 @@ void test_read_node_bounds(void) { MMDB_search_node_s node; /* node_count - 1 is the last valid node */ - int status = - MMDB_read_node(mmdb, mmdb->metadata.node_count - 1, &node); + int status = MMDB_read_node(mmdb, mmdb->metadata.node_count - 1, &node); cmp_ok(status, "==", MMDB_SUCCESS, diff --git a/t/double_close_t.c b/t/double_close_t.c index 942b4abf..606fe84f 100644 --- a/t/double_close_t.c +++ b/t/double_close_t.c @@ -27,9 +27,11 @@ void test_double_close(void) { 0, "description.count is 0 after close"); cmp_ok(mmdb.file_size, "==", 0, "file_size is 0 after close"); - cmp_ok(mmdb.data_section_size, "==", 0, - "data_section_size is 0 after close"); - cmp_ok(mmdb.metadata_section_size, "==", 0, + cmp_ok( + mmdb.data_section_size, "==", 0, "data_section_size is 0 after close"); + cmp_ok(mmdb.metadata_section_size, + "==", + 0, "metadata_section_size is 0 after close"); /* Second close should be a safe no-op (file_content was NULLed) */ diff --git a/t/max_depth_t.c b/t/max_depth_t.c index f703b8d0..7511f3e7 100644 --- a/t/max_depth_t.c +++ b/t/max_depth_t.c @@ -74,8 +74,7 @@ void test_valid_nesting_allowed(void) { } void test_deep_array_nesting_rejected(void) { - char *db_file = - bad_database_path("libmaxminddb-deep-array-nesting.mmdb"); + char *db_file = bad_database_path("libmaxminddb-deep-array-nesting.mmdb"); MMDB_s mmdb; int status = MMDB_open(db_file, MMDB_MODE_MMAP, &mmdb);