[postgis-tickets] r16723 - Fix undefined behaviour in ptarray_segmentize2d
Raul
raul at rmr.ninja
Fri Sep 7 04:19:23 PDT 2018
Author: algunenano
Date: 2018-09-07 04:19:22 -0700 (Fri, 07 Sep 2018)
New Revision: 16723
Modified:
trunk/NEWS
trunk/liblwgeom/cunit/cu_measures.c
trunk/liblwgeom/ptarray.c
Log:
Fix undefined behaviour in ptarray_segmentize2d
Closes #4173
References #4153
Closes https://github.com/postgis/postgis/pull/292
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2018-09-07 10:59:01 UTC (rev 16722)
+++ trunk/NEWS 2018-09-07 11:19:22 UTC (rev 16723)
@@ -8,6 +8,7 @@
- #4163, MVT: Fix resource leak when the first geometry is NULL (Raúl Marín)
- #4161, MVT: Drop geometries smaller than the resolution (Raúl Marín)
- #4172, Fix memory leak in lwgeom_offsetcurve (Raúl Marín)
+ - #4173, Fix undefined behaviour in ptarray_segmentize2d (Raúl Marín)
PostGIS 2.5.0rc1
2018/08/19
Modified: trunk/liblwgeom/cunit/cu_measures.c
===================================================================
--- trunk/liblwgeom/cunit/cu_measures.c 2018-09-07 10:59:01 UTC (rev 16722)
+++ trunk/liblwgeom/cunit/cu_measures.c 2018-09-07 11:19:22 UTC (rev 16723)
@@ -527,17 +527,23 @@
lwgeom_free(linein);
lwgeom_free(lineout);
+ /* test too many segments */
+ linein = lwgeom_from_wkt("LINESTRING(0 0,10 0)", LW_PARSER_CHECK_NONE);
+ lineout = lwgeom_segmentize2d(linein, 1e-100);
+ CU_ASSERT_EQUAL(lineout, NULL);
+ lwgeom_free(linein);
+
/* test interruption */
linein = lwgeom_from_wkt("LINESTRING(0 0,10 0)", LW_PARSER_CHECK_NONE);
lwgeom_request_interrupt();
- lineout = lwgeom_segmentize2d(linein, 1e-100);
+ lineout = lwgeom_segmentize2d(linein, INT32_MAX);
CU_ASSERT_EQUAL(lineout, NULL);
lwgeom_free(linein);
linein = lwgeom_from_wkt("MULTILINESTRING((0 0,10 0),(20 0, 30 0))", LW_PARSER_CHECK_NONE);
lwgeom_request_interrupt();
- lineout = lwgeom_segmentize2d(linein, 1e-100);
+ lineout = lwgeom_segmentize2d(linein, INT32_MAX);
CU_ASSERT_EQUAL(lineout, NULL);
lwgeom_free(linein);
@@ -545,7 +551,7 @@
"MULTIPOLYGON(((0 0,20 0,20 20,0 20,0 0),(2 2,2 4,4 4,4 2,2 2),(6 6,6 8,8 8,8 6,6 6)),((40 0,40 20,60 20,60 0,40 0),(42 2,42 4,44 4,44 2,42 2)))"
, LW_PARSER_CHECK_NONE);
lwgeom_request_interrupt();
- lineout = lwgeom_segmentize2d(linein, 1e-100);
+ lineout = lwgeom_segmentize2d(linein, INT32_MAX);
CU_ASSERT_EQUAL(lineout, NULL);
lwgeom_free(linein);
@@ -554,13 +560,15 @@
, LW_PARSER_CHECK_NONE);
CU_ASSERT_FATAL(linein != NULL);
lwgeom_request_interrupt();
- lineout = lwgeom_segmentize2d(linein, 1e-100);
+ lineout = lwgeom_segmentize2d(linein, INT32_MAX);
CU_ASSERT_EQUAL(lineout, NULL);
lwgeom_free(linein);
linein = lwgeom_from_wkt("LINESTRING(20 0, 30 0)", LW_PARSER_CHECK_NONE);
+ CU_ASSERT_FATAL(linein != NULL);
/* NOT INTERRUPTED */
lineout = lwgeom_segmentize2d(linein, 5);
+ CU_ASSERT_NOT_EQUAL_FATAL(lineout, NULL);
strout = lwgeom_to_ewkt(lineout);
ASSERT_STRING_EQUAL(strout, "LINESTRING(20 0,25 0,30 0)");
lwfree(strout);
Modified: trunk/liblwgeom/ptarray.c
===================================================================
--- trunk/liblwgeom/ptarray.c 2018-09-07 10:59:01 UTC (rev 16722)
+++ trunk/liblwgeom/ptarray.c 2018-09-07 11:19:22 UTC (rev 16723)
@@ -442,13 +442,24 @@
* breaks those "strict" rules.
*/
POINT4D *p1ptr=&p1, *p2ptr=&p2;
+ double segments;
getPoint4d_p(ipa, i, &p2);
segdist = distance2d_pt_pt((POINT2D *)p1ptr, (POINT2D *)p2ptr);
/* Split input segment into shorter even chunks */
- nseg = ceil(segdist / dist);
+ segments = ceil(segdist / dist);
+ /* Uses INT32_MAX instead of UINT32_MAX to be safe that it fits */
+ if (segments >= INT32_MAX)
+ {
+ lwnotice("%s:%d - %s: Too many segments required (%e)",
+ __FILE__, __LINE__,__func__, segments);
+ ptarray_free(opa);
+ return NULL;
+ }
+ nseg = segments;
+
for (j = 1; j < nseg; j++)
{
pbuf.x = p1.x + (p2.x - p1.x) * j / nseg;
More information about the postgis-tickets
mailing list