[SCM] PostGIS branch master updated. 3.7.0beta2-10-g2b8bb15d7
git at osgeo.org
git at osgeo.org
Mon Aug 10 02:01:41 PDT 2026
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".
The branch, master has been updated
via 2b8bb15d7a3a872ce9f0f6f4e680f9edd8b7415a (commit)
via c7287d8a085581c37be947859c4b0cc285a83cd2 (commit)
from 8b55c63cfa65a37dd0cabdf51782d589b62f8773 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 2b8bb15d7a3a872ce9f0f6f4e680f9edd8b7415a
Merge: 8b55c63cf c7287d8a0
Author: Darafei Praliaskouski <komzpa at gmail.com>
Date: Mon Aug 10 02:01:37 2026 -0700
Merge pull request 'liblwgeom: reject overlong encoded polylines' (!715) from Komzpa/postgis:fix/encoded-polyline-shift-544518840 into master
Encoded polyline coordinate varints were accumulated into a signed `int`, so malformed inputs could shift a high 5-bit group into the signed bit range under UBSAN. Decode the varint into a bounded unsigned accumulator instead, and reject truncated, invalid, or overlong coordinate varints before shifting them.
Reviewed-on: https://gitea.osgeo.org/postgis/postgis/pulls/715
commit c7287d8a085581c37be947859c4b0cc285a83cd2
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Mon Aug 10 12:55:53 2026 +0400
fix(liblwgeom): reject overlong encoded polylines
diff --git a/NEWS b/NEWS
index 024608787..258077332 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ These are only changes since 3.7.0beta2.
* Bug Fixes *
+ - OSSFuzz 6152109301760000, reject overlong encoded polyline coordinate
+ varints (Darafei Praliaskouski)
diff --git a/liblwgeom/cunit/cu_in_encoded_polyline.c b/liblwgeom/cunit/cu_in_encoded_polyline.c
index 9cd4a7e1f..7fcb7841a 100644
--- a/liblwgeom/cunit/cu_in_encoded_polyline.c
+++ b/liblwgeom/cunit/cu_in_encoded_polyline.c
@@ -69,6 +69,13 @@ static void in_encoded_polyline_test_truncated_input(void)
CU_ASSERT_PTR_NULL(lwgeom_from_encoded_polyline("`", 5));
}
+static void
+in_encoded_polyline_test_overlong_varint(void)
+{
+ /* OSSFuzz 6152109301760000: 17 << 30 must be rejected before shifting. */
+ CU_ASSERT_PTR_NULL(lwgeom_from_encoded_polyline("~~~~~~P", 5));
+}
+
/*
** Used by test harness to register the tests in this file.
*/
@@ -80,4 +87,5 @@ void in_encoded_polyline_suite_setup(void)
PG_ADD_TEST(suite, in_encoded_polyline_test_precision);
PG_ADD_TEST(suite, in_encoded_polyline_test_close_points);
PG_ADD_TEST(suite, in_encoded_polyline_test_truncated_input);
+ PG_ADD_TEST(suite, in_encoded_polyline_test_overlong_varint);
}
diff --git a/liblwgeom/lwin_encoded_polyline.c b/liblwgeom/lwin_encoded_polyline.c
index d1af103ea..ef35d8c0f 100644
--- a/liblwgeom/lwin_encoded_polyline.c
+++ b/liblwgeom/lwin_encoded_polyline.c
@@ -32,6 +32,50 @@
#include "lwgeom_log.h"
#include "../postgis_config.h"
+static int
+encoded_polyline_read_varint(const char *encodedpolyline, int length, int *idx, uint32_t *value)
+{
+ uint32_t res = 0;
+ unsigned int shift = 0;
+
+ while (1)
+ {
+ int byte;
+ if (*idx >= length)
+ {
+ lwerror("lwgeom_from_encoded_polyline: input is truncated");
+ return LW_FALSE;
+ }
+
+ byte = (unsigned char)encodedpolyline[(*idx)++] - 63;
+ if (byte < 0)
+ {
+ lwerror("lwgeom_from_encoded_polyline: input contains an invalid byte");
+ return LW_FALSE;
+ }
+ if (shift > 30 || (shift == 30 && ((byte & 0x1C) || (byte >= 0x20))))
+ {
+ lwerror("lwgeom_from_encoded_polyline: coordinate value is too large");
+ return LW_FALSE;
+ }
+
+ res |= (uint32_t)(byte & 0x1F) << shift;
+ if (byte < 0x20)
+ break;
+
+ shift += 5;
+ }
+
+ *value = res;
+ return LW_TRUE;
+}
+
+static int32_t
+encoded_polyline_zigzag_decode(uint32_t value)
+{
+ return (int32_t)((value >> 1) ^ (uint32_t)(-(int32_t)(value & 1)));
+}
+
LWGEOM*
lwgeom_from_encoded_polyline(const char *encodedpolyline, int precision)
{
@@ -48,36 +92,22 @@ lwgeom_from_encoded_polyline(const char *encodedpolyline, int precision)
while (idx < length) {
POINT4D pt;
- char byte = 0;
+ uint32_t res = 0;
- int res = 0;
- char shift = 0;
- do {
- if (idx >= length) {
- lwerror("lwgeom_from_encoded_polyline: input is truncated");
- ptarray_free(pa);
- return NULL;
- }
- byte = encodedpolyline[idx++] - 63;
- res |= (byte & 0x1F) << shift;
- shift += 5;
- } while (byte >= 0x20);
- int32_t deltaLat = ((res & 1) ? ~(res >> 1) : (res >> 1));
+ if (!encoded_polyline_read_varint(encodedpolyline, length, &idx, &res))
+ {
+ ptarray_free(pa);
+ return NULL;
+ }
+ int32_t deltaLat = encoded_polyline_zigzag_decode(res);
latitude += deltaLat;
- shift = 0;
- res = 0;
- do {
- if (idx >= length) {
- lwerror("lwgeom_from_encoded_polyline: input is truncated");
- ptarray_free(pa);
- return NULL;
- }
- byte = encodedpolyline[idx++] - 63;
- res |= (byte & 0x1F) << shift;
- shift += 5;
- } while (byte >= 0x20);
- int32_t deltaLon = ((res & 1) ? ~(res >> 1) : (res >> 1));
+ if (!encoded_polyline_read_varint(encodedpolyline, length, &idx, &res))
+ {
+ ptarray_free(pa);
+ return NULL;
+ }
+ int32_t deltaLon = encoded_polyline_zigzag_decode(res);
longitude += deltaLon;
pt.x = longitude/scale;
-----------------------------------------------------------------------
Summary of changes:
NEWS | 2 +
liblwgeom/cunit/cu_in_encoded_polyline.c | 8 +++
liblwgeom/lwin_encoded_polyline.c | 86 +++++++++++++++++++++-----------
3 files changed, 68 insertions(+), 28 deletions(-)
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list