diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1cebbbd..ca3a058 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,7 @@
CHANGELOG
=========
-1.14.0
+1.14.0 (2026-09-10)
-------------------
* Bounded the resources that the pure PHP decoder spends on a single lookup. A
diff --git a/README.md b/README.md
index b610552..6e7ef47 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ You should now have the file `composer.phar` in your project directory.
Run in your project root:
```
-php composer.phar require maxmind-db/reader:^1.13.1
+php composer.phar require maxmind-db/reader:^1.14.0
```
You should now have the files `composer.json` and `composer.lock` as well as
@@ -230,6 +230,6 @@ The MaxMind DB Reader PHP API uses [Semantic Versioning](https://semver.org/).
## Copyright and License ##
-This software is Copyright (c) 2014-2025 by MaxMind, Inc.
+This software is Copyright (c) 2014-2026 by MaxMind, Inc.
This is free software, licensed under the Apache License, Version 2.0.
diff --git a/composer.json b/composer.json
index f0a9fad..4ce807d 100644
--- a/composer.json
+++ b/composer.json
@@ -22,7 +22,7 @@
"maxmind-db/reader-ext": "C extension for significantly faster IP lookups (install via PIE: pie install maxmind-db/reader-ext)"
},
"conflict": {
- "ext-maxminddb": "<1.11.1 || >=2.0.0"
+ "ext-maxminddb": "<1.14.0 || >=2.0.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "3.*",
diff --git a/dev-bin/release.sh b/dev-bin/release.sh
index 8287f4e..7f8b12d 100755
--- a/dev-bin/release.sh
+++ b/dev-bin/release.sh
@@ -44,6 +44,10 @@ if ! gh workflow view release.yml --repo maxmind/MaxMind-DB-Reader-php-ext &>/de
fi
check_command perl
+if ! perl -MHTML::Entities -e 1; then
+ echo "Error: Cannot load HTML::Entities. Install the Perl HTML::Parser distribution before releasing."
+ exit 1
+fi
check_command php
check_command phpize
check_command pecl
@@ -164,7 +168,8 @@ export RELEASE_VERSION="$version" RELEASE_DATE="$date" RELEASE_NOTES="$notes"
subst composer.json 's/(?<="ext-maxminddb": "<)[^ ,|"]+/$ENV{RELEASE_VERSION}/'
subst package.xml 's/(?<=<(?:api)>)\d+\.\d+\.\d+(?=<)/$ENV{RELEASE_VERSION}/'
subst package.xml 's/(?<=<(?:release)>)\d+\.\d+\.\d+(?=<)/$ENV{RELEASE_VERSION}/'
- subst package.xml 's{(?<=).*(?=)}{$ENV{RELEASE_NOTES}}sm' -0777
+ # Limit escaping to XML text characters to avoid HTML-only named entities.
+ subst package.xml 's{(?<=).*(?=)}{encode_entities($ENV{RELEASE_NOTES}, "<>&")}sme' -0777 -MHTML::Entities
subst package.xml 's/(?<=)\d{4}-\d{2}-\d{2}(?=<)/$ENV{RELEASE_DATE}/'
}
@@ -179,6 +184,8 @@ php -n -dextension=ext/modules/maxminddb.so "$(mise which composer.phar)" update
php -n -dextension=ext/modules/maxminddb.so ./vendor/bin/phpunit
php -n ./vendor/bin/phpunit
+pecl package
+
echo $'\nDiff:'
git diff
@@ -189,8 +196,6 @@ fi
echo $'\nRelease notes:'
echo "$notes"
-pecl package
-
package="maxminddb-$version.tgz"
read -r -p "Push to origin? (y/n) " should_push
diff --git a/ext/php_maxminddb.h b/ext/php_maxminddb.h
index 30e2461..fae51a8 100644
--- a/ext/php_maxminddb.h
+++ b/ext/php_maxminddb.h
@@ -15,7 +15,7 @@
#ifndef PHP_MAXMINDDB_H
#define PHP_MAXMINDDB_H 1
-#define PHP_MAXMINDDB_VERSION "1.13.1"
+#define PHP_MAXMINDDB_VERSION "1.14.0"
#define PHP_MAXMINDDB_EXTNAME "maxminddb"
extern zend_module_entry maxminddb_module_entry;
diff --git a/package.xml b/package.xml
index 15db600..5f66c4f 100644
--- a/package.xml
+++ b/package.xml
@@ -14,17 +14,57 @@
goschwald@maxmind.com
yes
- 2025-11-21
+ 2026-09-10
- 1.13.1
- 1.13.1
+ 1.14.0
+ 1.14.0
stable
stable
Apache License 2.0
- * First PIE release. No other changes.
+ * Bounded the resources that the pure PHP decoder spends on a single lookup. A
+ crafted database could nest data-section pointers to shared targets so that
+ decoding one record cost exponential time and memory, or point many times at
+ one large value so that the decoder copied far more data than the file holds.
+ The decoder now follows the Reader Resource Limits section of the MaxMind DB
+ specification. Each lookup is limited to 65,536 values, 512 levels of
+ nesting, and 2 MiB of string and bytes payload.
+ * Exceeding a limit throws an `InvalidDatabaseException`.
+ * Opening a database whose metadata exceeds a limit throws the same
+ exception.
+ * A scalar that declares more than 16 bytes, the width of the widest
+ fixed-width type, is rejected as invalid data.
+* The bundled libmaxminddb used by `--with-maxminddb-bundled` builds of the
+ extension now applies the same decoder limits. The extension throws an
+ `InvalidDatabaseException` when a lookup exceeds them.
+* The pure PHP reader is about 40% faster on City lookups. It no longer seeks
+ before a read that continues where the last one ended, and it checks read
+ lengths with `strlen()` instead of `ftell()`.
+* The Windows build configuration now accepts either `libmaxminddb.lib` or
+ `maxminddb.lib` when building the extension. The `lib` prefix was removed
+ in libmaxminddb 1.6.0, but the libmaxminddb that PHP publishes for Windows
+ builds is still 1.5.0, which uses the prefixed name. Pull request by
+ Jean-Baptiste Nahan. GitHub #231.
+* Replaced `XtOffsetOf()` with `offsetof()`. The `XtOffsetOf()` alias has
+ been removed in PHP 8.6. Pull request by Remi Collet. GitHub #252.
+* The extension can now be built from a bundled copy of libmaxminddb, on
+ both Unix-like systems and Windows, by passing `--with-maxminddb-bundled`
+ to `configure` (or to `configure.bat` on Windows). This produces an
+ extension that does not depend on a system libmaxminddb, which is a
+ prerequisite for distributing precompiled builds; on Windows it also
+ replaces the 1.5.0 import library that PHP publishes for Windows builds.
+ The default is unchanged: without the flag, the extension links against a
+ system libmaxminddb as before. GitHub #265.
+* The `conflict` constraint on `ext-maxminddb` in `composer.json` is again
+ updated when a release is cut. The substitution that maintains it stopped
+ matching in April 2024, when the constraint's separator changed from a comma
+ to `||`, so the constraint has read `<1.11.1` through four releases. Users of
+ the C extension should note the effect of reviving it: `ext-maxminddb` is a
+ Composer platform package, so this release conflicts with an older compiled
+ extension and `composer update` will require upgrading the two together.
+ GitHub #266.