Skip to content

Releases: oschwald/maxminddb-rust

0.30.0

Choose a tag to compare

@oschwald oschwald released this 19 Jul 00:39
Immutable release. Only release title and notes can be modified.
fceaa66
  • Added deserialize_any_with_raw_strings() for Serde-based format adapters
    to validate MMDB strings while constructing another runtime's native string
    type, avoiding duplicate UTF-8 validation without unsafe Rust. Adapters
    remain responsible for strict UTF-8 validation.
  • Fixed network iteration on cyclic or over-deep corrupt search trees so it
    returns an error instead of looping indefinitely.
  • Fixed decode_path() error rendering for extreme negative indexes and
    reduced path traversal header parsing.
  • Removed decoder logging checks from hot deserialization paths.
  • Fixed verify() to validate shared data-section pointer targets once, reject
    pointer cycles, invalid scalar encodings, and impossible container sizes.

0.29.0

Choose a tag to compare

@oschwald oschwald released this 28 Jun 23:05
Immutable release. Only release title and notes can be modified.
5c656d4
  • Breaking: Metadata::build_time() now returns
    Result<SystemTime, MaxMindDbError> instead of panicking on
    unrepresentable timestamps, and databases whose build_epoch cannot be
    represented as SystemTime are rejected as invalid during open and verify.
  • Breaking: Reader::metadata is now private. Use Reader::metadata() to
    access validated metadata by shared reference.
  • Breaking: Opening a database now rejects unsupported major format versions,
    unsupported IP versions, and zero-node search trees. Minor format versions
    are still accepted for forward compatibility.
  • Fixed: within() and networks() now handle IPv6 databases without an
    IPv4 subtree without reading terminal data nodes as tree nodes or
    panicking while formatting low IPv6 networks.
  • Fixed: Skipping ignored or unknown fields now enforces data-section
    bounds and the maximum nesting depth instead of accepting truncated
    values or overflowing the stack on deeply nested corrupt data.
  • Internal: Added focused benchmarks for network iteration and serde
    unknown-field skipping, plus metadata build-time conversion, to guard
    performance-sensitive fixes.
  • Documentation: Fixed intra-doc links so docs build with warnings denied,
    and added a CI check to keep them passing.

0.28.1

Choose a tag to compare

@oschwald oschwald released this 26 Apr 19:58
Immutable release. Only release title and notes can be modified.
8e86128
  • Fixed: Databases with an impossible declared search tree size are now
    rejected during open/verify instead of causing runaway allocation
    during validation.
  • Fixed: within() now rejects IPv6 CIDRs on IPv4-only databases instead
    of yielding unrelated networks.
  • Fixed: Verification now rejects truncated scalar/string payloads instead
    of skipping past them and reporting the database as valid.
  • Fixed: LookupResult::network() now uses the reader's measured IPv4
    subtree depth instead of assuming it always begins at bit 96.

0.28.0

Choose a tag to compare

@oschwald oschwald released this 25 Apr 18:12
Immutable release. Only release title and notes can be modified.
429baa5
  • Performance improvement: Faster search-tree traversal by dispatching
    on the database's record size to monomorphized node readers, replacing
    per-step branching on the record size.
  • Performance improvement: Direct deserialization of scalars, sequences,
    maps, and structs through dedicated fast paths instead of routing
    through deserialize_any.
  • Performance improvement: IPv4 and IPv6 lookups dispatch to dedicated
    paths, avoiding per-call address-kind checks on the hot path.
  • Behavior change: Deserializing a database array into a tuple or
    tuple struct now returns a decoding error when the lengths do not
    match. Previously the mismatch was silently ignored.
  • Fixed: A corrupt data pointer that would underflow during resolution
    now returns an InvalidDatabase error instead of panicking.

0.27.3

Choose a tag to compare

@oschwald oschwald released this 16 Feb 14:29
Immutable release. Only release title and notes can be modified.
15b48e9
  • Removed the release_max_level_info feature from the log dependency, as
    libraries should not set a global release log-level cap. Pull request by
    monosans. GitHub #110.

0.27.2

Choose a tag to compare

@oschwald oschwald released this 14 Feb 22:09
Immutable release. Only release title and notes can be modified.
d2c9fab
  • Performance improvement: Faster lookups and record decoding in common paths,
    including control-byte header parsing and integer decoding.
  • Performance improvement: Faster string decoding for ASCII-only values by
    using a dedicated ASCII fast path.
  • Performance improvement: Reduced release-build overhead by compiling out
    debug/trace logging calls.
  • Fixed: Truncated or corrupt data in control-byte headers now returns a
    decoding error instead of panicking.

0.27.1

Choose a tag to compare

@oschwald oschwald released this 18 Dec 19:09
Immutable release. Only release title and notes can be modified.
c04068a
  • Performance improvement: Skipped UTF-8 validation for map keys during
    deserialization. This significantly speeds up full record decoding by
    treating keys as raw bytes when matching against struct fields.
  • Performance improvement: Optimized tree traversal by reducing bounds checks
    during node reading.

0.27.0

Choose a tag to compare

@oschwald oschwald released this 28 Nov 18:53
Immutable release. Only release title and notes can be modified.
02d6fc7

This release includes significant API changes. See UPGRADING.md
for migration guidance.

Breaking Changes

Lookup API

  • lookup() now returns LookupResult instead of Option<T>. The new API
    enables lazy decoding - data is only deserialized when explicitly requested.
  • lookup_prefix() has been removed. Use lookup(ip)?.network() instead.

Iteration API

  • within() now requires a second WithinOptions parameter. Use
    Default::default() for the previous behavior.
  • Within iterator now yields LookupResult instead of WithinItem<T>.

GeoIP2 Structs

  • The names fields now use a Names struct instead of BTreeMap<&str, &str>.
    Access names directly via language fields (e.g., names.english).
  • Nested struct fields (city, country, location, etc.) are now
    non-optional with Default, simplifying access patterns.
  • Removed is_anonymous_proxy and is_satellite_provider from Traits.
    These fields are no longer present in MaxMind databases.

Error Types

  • InvalidDatabase and Decoding variants now use structured fields instead
    of a single string. Pattern matching must be updated.
  • New InvalidInput variant for user input errors (e.g., IPv6 lookup in
    IPv4-only database).

Memory Mapping

  • Reader::open_mmap is now unsafe. The caller must ensure the database
    file is not modified or truncated while the Reader exists. This fixes a
    soundness issue. Reported by paolobarbolini. GitHub #86.

Added

  • LookupResult type with lazy decoding support:
    • has_data() - Check if data exists for this IP
    • network() - Get the network containing the IP
    • offset() - Get data offset for caching/deduplication
    • decode() - Deserialize full record
    • decode_path() - Selectively decode specific fields by path
  • PathElement enum and path! macro for navigating nested structures.
  • WithinOptions to control network iteration behavior:
    • include_aliased_networks() - Include IPv4 via IPv6 aliases
    • include_networks_without_data() - Include networks without data records
    • skip_empty_values() - Skip empty maps/arrays
  • networks() method for iterating over all networks in the database.
  • verify() method for comprehensive database validation.
  • Metadata::build_time() to convert build_epoch to SystemTime.
  • PartialEq and Eq implementations for Metadata and WithinOptions.

Changed

  • Error messages now include byte offsets when available.
  • decode_path() errors include path context showing where navigation failed.
  • Added recursion depth limit (512) matching libmaxminddb and Go reader.
  • Serde deserializer improvements: size hints, is_human_readable() returns
    false, deserialize_ignored_any, and deserialize_enum support.
  • MaxMindDbError is now #[non_exhaustive].

0.26.0

Choose a tag to compare

@oschwald oschwald released this 29 Mar 23:26
1023bab
  • BREAKING CHANGE: The lookup and lookup_prefix methods now return
    Ok(None) or Ok((None, prefix_len)) respectively when an IP address is
    valid but not found in the database (or has no associated data record),
    instead of returning an Err(MaxMindDbError::AddressNotFoundError).
    Code previously matching on AddressNotFoundError must be updated to
    handle the Ok(None) / Ok((None, prefix_len)) variants.
  • BREAKING CHANGE: The MaxMindDBError enum has been renamed
    MaxMindDbError and variants have been renamed and refactored. For
    example, IoError is now Io, InvalidDatabaseError is now
    InvalidDatabase, DecodingError is now Decoding,
    InvalidNetworkError is now InvalidNetwork. The MapError variant has
    been replaced by Mmap (under the mmap feature flag). Code explicitly
    matching on the old variant names must be updated.
  • BREAKING CHANGE: MaxMindDbError no longer implements PartialEq.
    This is because underlying error types like std::io::Error (now
    wrapped by the Io and Mmap variants) do not implement PartialEq.
    Code comparing errors directly using == or assert_eq! must be
    updated, typically by using matches! or by matching on the error
    kind and potentially its contents.
  • Refactored MaxMindDbError handling using the thiserror crate.
    Variants like Io, Mmap, and InvalidNetwork now directly wrap
    the underlying error types (std::io::Error, ipnetwork::IpNetworkError).
  • Errors wrapping underlying types (Io, Mmap, InvalidNetwork) now
    correctly implement std::error::Error::source(), allowing inspection
    of the original cause.
  • The Display implementation for MaxMindDbError has been refined to
    generally show only the specific error details, often including the
    message from the source error, rather than prefixing with the variant
    name.
  • lookup_prefix now returns the prefix length of the entry even when the
    value is not found.
  • Fixed an internal bounds checking error when resolving data pointers.
    The previous logic could cause a panic on a corrupt database.

0.25.0

Choose a tag to compare

@oschwald oschwald released this 16 Feb 19:50
5c5d717
  • Serde will now skip serialization of the GeoIP2 struct fields
    when Option is none. Pull request by Stefan Sundin. GitHub #79.
  • Serialize and Clone were added to the Metadata struct. Pull
    request by Stefan Sundin. GitHub #80.
  • Added feature to use simdutf8 as a faster alternative when
    unsafe-str-decode is too risky. Pull request by Jakub Onderka.
    GitHub #88.
  • Minor internal refactoring and performance improvements.