[Git][debian-gis-team/mapnik][upstream] New upstream version 4.2.2+ds

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Mon Mar 30 18:48:20 BST 2026



Bas Couwenberg pushed to branch upstream at Debian GIS Project / mapnik


Commits:
4d81f31b by Bas Couwenberg at 2026-03-30T19:34:57+02:00
New upstream version 4.2.2+ds
- - - - -


14 changed files:

- .github/actions/run_tests/action.yml
- .github/workflows/build_and_test.yml
- .github/workflows/release_linux.yml
- CHANGELOG.md
- include/mapnik/datasource_cache.hpp
- include/mapnik/util/name_to_int.hpp
- include/mapnik/version.hpp
- plugins/input/pgraster/pgraster_datasource.cpp
- src/build.py
- src/datasource_cache.cpp
- src/load_map.cpp
- src/svg/svg_parser.cpp
- src/value.cpp
- test/unit/core/expressions_test.cpp


Changes:

=====================================
.github/actions/run_tests/action.yml
=====================================
@@ -50,7 +50,7 @@ runs:
         tar -vzcf visual-test-results.tar.gz visual-test-result
 
     - name: Upload visual test results
-      uses: actions/upload-artifact at v4
+      uses: actions/upload-artifact at v6
       if: runner.os != 'macOS'
       with:
         name: ${{ inputs.cmake-preset }}-visual-tests-${{ github.sha }}
@@ -77,12 +77,12 @@ runs:
 
     - name: Upload coverage to Codecov (Linux & macOS)
       if: runner.os != 'Windows'
-      uses: codecov/codecov-action at v4
+      uses: codecov/codecov-action at v6
       with:
         files: build/coverage.info
 
     - name: Upload coverage to Codecov (Windows)
       if: runner.os == 'Windows'
-      uses: codecov/codecov-action at v4
+      uses: codecov/codecov-action at v6
       with:
         files: ctest.cov,build/out/mapnik-test-visual.cov


=====================================
.github/workflows/build_and_test.yml
=====================================
@@ -15,7 +15,7 @@ env:
   USERNAME: mapnik
   VCPKG_EXE: ${{ github.workspace }}/vcpkg/vcpkg
   FEED_URL: https://nuget.pkg.github.com/mapnik/index.json
-  VCPKG_RELEASE: 2025.09.17
+  VCPKG_RELEASE: 2026.03.18
   VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/mapnik/index.json,readwrite"
 
 jobs:
@@ -23,7 +23,7 @@ jobs:
     name: Check Source Code
     runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout at v4
+      - uses: actions/checkout at v5
       - uses: actions/setup-python at v5
         with:
           python-version: "3.10"
@@ -63,12 +63,12 @@ jobs:
           fi
 
       - name: Checkout Mapnik
-        uses: actions/checkout at v4
+        uses: actions/checkout at v5
         with:
           submodules: recursive
 
       - name: Checkout vcpkg
-        uses: actions/checkout at v4
+        uses: actions/checkout at v5
         with:
           path: vcpkg
           ref: ${{ env.VCPKG_RELEASE }}


=====================================
.github/workflows/release_linux.yml
=====================================
@@ -16,7 +16,7 @@ jobs:
     steps:
 
       - name: checkout mapnik
-        uses: actions/checkout at v4
+        uses: actions/checkout at v5
         with:
           submodules: "recursive"
 
@@ -53,7 +53,7 @@ jobs:
         run: cmake --build --preset ${{ env.PRESET }} --target package
 
       - name: Upload mapnik debian package
-        uses: actions/upload-artifact at v4
+        uses: actions/upload-artifact at v6
         with:
           name: ${{ env.PRESET }}-deb
           path: build/mapnik-*.deb


=====================================
CHANGELOG.md
=====================================
@@ -6,6 +6,22 @@ Developers: Please commit along with changes.
 
 For a complete change history, see the git log.
 
+## Mapnik 4.2.2
+
+Released March 30th, 2026
+
+(Packaged from [23567fcef](https://github.com/mapnik/mapnik/commit/23567fcef))
+
+- SCons build - remove boost_system
+- Fix "modulo by zero" exceptions  by returning `mapnik::value_null` when rhs is zero (cosistent with `div` implementation)
+  (including specialisations using `std::fmod` which return NAN if rhs is zero https://en.cppreference.com/w/cpp/numeric/math/fmod) (ref #4545)
+- Return vector<string> from plugin_directories method
+- pgraster.input - fix stderr messages
+- Fix warning - identifier '_case' preceded by whitespace in a literal operator declaration is deprecated
+- Update vcpkg to 2026.03.18
+- Update github actions (node24) https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
+
+
 ## Mapnik 4.2.1
 
 Released January 28th, 2026


=====================================
include/mapnik/datasource_cache.hpp
=====================================
@@ -50,7 +50,7 @@ class MAPNIK_DECL datasource_cache : public singleton<datasource_cache, CreateSt
   public:
     bool plugin_registered(std::string const& plugin_name) const;
     std::vector<std::string> plugin_names() const;
-    std::string plugin_directories();
+    std::vector<std::string> plugin_directories() const;
     bool register_datasources(std::string const& path, bool recurse = false);
     bool register_datasource(std::string const& path);
     std::shared_ptr<datasource> create(parameters const& params);


=====================================
include/mapnik/util/name_to_int.hpp
=====================================
@@ -28,7 +28,7 @@ constexpr unsigned name_to_int(char const* str, unsigned off = 0)
     return !str[off] ? 5381 : (name_to_int(str, off + 1) * 33) ^ static_cast<unsigned>(str[off]);
 }
 
-constexpr unsigned operator"" _case(char const* str, std::size_t)
+constexpr unsigned operator""_case(char const* str, std::size_t)
 {
     return name_to_int(str);
 }


=====================================
include/mapnik/version.hpp
=====================================
@@ -27,7 +27,7 @@
 
 #define MAPNIK_MAJOR_VERSION 4
 #define MAPNIK_MINOR_VERSION 2
-#define MAPNIK_PATCH_VERSION 1
+#define MAPNIK_PATCH_VERSION 2
 
 #define MAPNIK_VERSION MAPNIK_VERSION_ENCODE(MAPNIK_MAJOR_VERSION, MAPNIK_MINOR_VERSION, MAPNIK_PATCH_VERSION)
 


=====================================
plugins/input/pgraster/pgraster_datasource.cpp
=====================================
@@ -113,7 +113,7 @@ pgraster_datasource::pgraster_datasource(parameters const& params)
         if (max_async_connections_ > pool_max_size_)
         {
             std::ostringstream err;
-            err << "PostGIS Plugin: Error: 'max_async_connections (" << max_async_connections_
+            err << "PGRaster Plugin: Error: 'max_async_connections (" << max_async_connections_
                 << ") must be <= max_size(" << pool_max_size_ << ")";
             throw mapnik::datasource_exception(err.str());
         }
@@ -400,7 +400,7 @@ pgraster_datasource::pgraster_datasource(parameters const& params)
                         // throw for cases like a numeric primary key, which is invalid
                         // as it should be floating point (int numerics are useless)
                         std::ostringstream err;
-                        err << "PostGIS Plugin: Error: '" << rs_key->getValue(0) << "' on table '" << parsed_table_
+                        err << "PGRaster Plugin: Error: '" << rs_key->getValue(0) << "' on table '" << parsed_table_
                             << "' is not a valid integer primary key field\n";
                         throw mapnik::datasource_exception(err.str());
                     }
@@ -408,7 +408,7 @@ pgraster_datasource::pgraster_datasource(parameters const& params)
                 else if (result_rows > 1)
                 {
                     std::ostringstream err;
-                    err << "PostGIS Plugin: Error: '" << "multi column primary key detected but is not supported";
+                    err << "PGRaster Plugin: Error: '" << "multi column primary key detected but is not supported";
                     throw mapnik::datasource_exception(err.str());
                 }
             }
@@ -419,7 +419,7 @@ pgraster_datasource::pgraster_datasource(parameters const& params)
         // but still not known at this point, then throw
         if (*autodetect_key_field && key_field_.empty())
         {
-            throw mapnik::datasource_exception("PostGIS Plugin: Error: primary key required"
+            throw mapnik::datasource_exception("PGRaster Plugin: Error: primary key required"
                                                " but could not be detected for table '" +
                                                parsed_table_ +
                                                "', please supply 'key_field'"
@@ -810,7 +810,7 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q, proces
         if (geometryColumn_.empty())
         {
             std::ostringstream s_error;
-            s_error << "PostGIS: geometry name lookup failed for table '";
+            s_error << "PGRaster: geometry name lookup failed for table '";
 
             if (!parsed_schema_.empty())
             {
@@ -975,7 +975,7 @@ featureset_ptr pgraster_datasource::features_at_point(coord2d const& pt, double
             if (geometryColumn_.empty())
             {
                 std::ostringstream s_error;
-                s_error << "PostGIS: geometry name lookup failed for table '";
+                s_error << "PGRaster: geometry name lookup failed for table '";
 
                 if (!parsed_schema_.empty())
                 {
@@ -1074,7 +1074,7 @@ box2d<double> pgraster_datasource::envelope() const
             if (col.empty())
             {
                 std::ostringstream s_error;
-                s_error << "PostGIS: unable to query the layer extent of table '";
+                s_error << "PGRaster: unable to query the layer extent of table '";
 
                 if (!sch.empty())
                 {
@@ -1093,7 +1093,7 @@ box2d<double> pgraster_datasource::envelope() const
                 if (tab.empty())
                 {
                     std::ostringstream s_error;
-                    s_error << "PostGIS: unable to query the layer extent as "
+                    s_error << "PGRaster: unable to query the layer extent as "
                             << "we couldn't determine the raster table name.\n"
                             << "Please provide either an 'extent' parameter to skip this query, "
                             << "a 'raster_table' parameter, or do not set 'estimate_extent'";


=====================================
src/build.py
=====================================
@@ -55,7 +55,6 @@ enabled_imaging_libraries = []
 
 
 filesystem = 'boost_filesystem%s' % env['BOOST_APPEND']
-system = 'boost_system%s' % env['BOOST_APPEND']
 regex = 'boost_regex%s' % env['BOOST_APPEND']
 
 
@@ -65,7 +64,6 @@ lib_env['LIBS'] = [regex]
 
 if int(env['CXX_STD']) < 17 or env['USE_BOOST_FILESYSTEM']:
     lib_env['LIBS'].append(filesystem)
-    lib_env['LIBS'].append(system)
 
 if env['COVERAGE']:
     lib_env.Append(LINKFLAGS='--coverage')


=====================================
src/datasource_cache.cpp
=====================================
@@ -93,7 +93,8 @@ datasource_ptr datasource_cache::create(parameters const& params)
             }
             else
             {
-                s += " (searched for datasource plugins in '" + plugin_directories() + "')";
+                s +=
+                  " (searched for datasource plugins in '" + boost::algorithm::join(plugin_directories_, ", ") + "')";
             }
             throw config_error(s);
         }
@@ -119,12 +120,12 @@ datasource_ptr datasource_cache::create(parameters const& params)
     return create_datasource->create(params);
 }
 
-std::string datasource_cache::plugin_directories()
+std::vector<std::string> datasource_cache::plugin_directories() const
 {
 #ifdef MAPNIK_THREADSAFE
     std::lock_guard<std::recursive_mutex> lock(instance_mutex_);
 #endif
-    return boost::algorithm::join(plugin_directories_, ", ");
+    return std::vector<std::string>(plugin_directories_.begin(), plugin_directories_.end());
 }
 
 bool datasource_cache::plugin_registered(std::string const& plugin_name) const


=====================================
src/load_map.cpp
=====================================
@@ -84,7 +84,7 @@ using boost::tokenizer;
 namespace mapnik {
 using std::optional;
 using util::name_to_int;
-using util::operator"" _case;
+using util::operator""_case;
 
 class map_parser : util::noncopyable
 {


=====================================
src/svg/svg_parser.cpp
=====================================
@@ -58,7 +58,7 @@ namespace mapnik {
 namespace svg {
 
 using util::name_to_int;
-using util::operator"" _case;
+using util::operator""_case;
 } // namespace svg
 } // namespace mapnik
 


=====================================
src/value.cpp
=====================================
@@ -386,6 +386,8 @@ struct mod
     template<typename T>
     value_type operator()(T lhs, T rhs) const
     {
+        if (rhs == 0)
+            return value_type();
         return lhs % rhs;
     }
 
@@ -395,15 +397,24 @@ struct mod
 
     value_type operator()(value_double lhs, value_integer rhs) const
     {
+        if (rhs == 0)
+            return value_type();
         return std::fmod(lhs, static_cast<value_double>(rhs));
     }
 
     value_type operator()(value_integer lhs, value_double rhs) const
     {
+        if (rhs == 0)
+            return value_type();
         return std::fmod(static_cast<value_double>(lhs), rhs);
     }
 
-    value_type operator()(value_double lhs, value_double rhs) const { return std::fmod(lhs, rhs); }
+    value_type operator()(value_double lhs, value_double rhs) const
+    {
+        if (rhs == 0)
+            return value_type();
+        return std::fmod(lhs, rhs);
+    }
 };
 
 template<typename V>


=====================================
test/unit/core/expressions_test.cpp
=====================================
@@ -11,6 +11,7 @@
 
 #include <functional>
 #include <map>
+#include <cmath>
 
 namespace {
 
@@ -108,7 +109,15 @@ TEST_CASE("expressions")
     TRY_CHECK(parse_and_dump("pi") == "3.14159");
     TRY_CHECK(parse_and_dump("deg_to_rad") == "0.0174533");
     TRY_CHECK(parse_and_dump("rad_to_deg") == "57.2958");
-
+    // div by zero
+    TRY_CHECK(eval("(1 / 0) = null") == true);
+    TRY_CHECK(eval("(pi / 0) = null") == true);
+    TRY_CHECK(eval("(1 / 0.0) = null") == true);
+    // modulus
+    TRY_CHECK(eval("3 % 2") == 1);
+    TRY_CHECK(eval("int((pi % 3) * 100000)") == 14159);
+    TRY_CHECK(eval("(1 % 0) = null") == true);
+    TRY_CHECK(eval("(pi % 0) = null") == true);
     // ascii attribute name
     TRY_CHECK(eval(" [foo]='bar' ") == true);
 



View it on GitLab: https://salsa.debian.org/debian-gis-team/mapnik/-/commit/4d81f31b1e3b5c1b65eeaa9550eb4105a617dd22

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/mapnik/-/commit/4d81f31b1e3b5c1b65eeaa9550eb4105a617dd22
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20260330/4272c7c8/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list