[SCM] PostGIS branch stable-3.4 updated. 3.4.5-24-g399e2f18c
git at osgeo.org
git at osgeo.org
Mon Apr 13 15:04:30 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, stable-3.4 has been updated
via 399e2f18c249ea272ffefd974c110a4c69a213c4 (commit)
via 2078e0c88c93b392e9efaf46dad4cac80a287ed7 (commit)
via 4400c58d090f82de491e13a9cf5fe6c90336079d (commit)
via 4808f465b86df6b9b69d569cef36acefc43be710 (commit)
via 53f3e6fe28a25a3dc08672bcc91d0549542fcf59 (commit)
via 02597250d8753f072363872d35b558fd43911d24 (commit)
via 10f8aa4840b2fa57f8d24abc92dd1b3f36d92daa (commit)
via 1a9074a7bbbea7ea5f24af593034485cdd499a26 (commit)
from 77143e9908ff70d7d8085a2559de21fc85a9950c (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 399e2f18c249ea272ffefd974c110a4c69a213c4
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date: Fri Apr 10 16:33:36 2026 -0700
Remove potential null dereference in ptarray_calc_areas()
diff --git a/liblwgeom/effectivearea.c b/liblwgeom/effectivearea.c
index 3c038c5f5..c22bde282 100644
--- a/liblwgeom/effectivearea.c
+++ b/liblwgeom/effectivearea.c
@@ -358,6 +358,9 @@ void ptarray_calc_areas(EFFECTIVE_AREAS *ea, int avoid_collaps, int set_area, do
const double *P2;
const double *P3;
+ if (npoints < 2)
+ lwerror("%s: not enough points provided", __func__);
+
P1 = (double*)getPoint_internal(ea->inpts, 0);
P2 = (double*)getPoint_internal(ea->inpts, 1);
commit 2078e0c88c93b392e9efaf46dad4cac80a287ed7
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date: Fri Apr 10 16:33:16 2026 -0700
Remove potential null dereference in lwcircstring_linearize()
diff --git a/liblwgeom/lwstroke.c b/liblwgeom/lwstroke.c
index ff025ffde..06ef95c78 100644
--- a/liblwgeom/lwstroke.c
+++ b/liblwgeom/lwstroke.c
@@ -565,8 +565,11 @@ lwcircstring_linearize(const LWCIRCSTRING *icurve, double tol,
return NULL;
}
}
- getPoint4d_p(icurve->points, icurve->points->npoints-1, &p1);
- ptarray_append_point(ptarray, &p1, LW_FALSE);
+ if (icurve->points->npoints > 0)
+ {
+ getPoint4d_p(icurve->points, icurve->points->npoints-1, &p1);
+ ptarray_append_point(ptarray, &p1, LW_FALSE);
+ }
oline = lwline_construct(icurve->srid, NULL, ptarray);
return oline;
commit 4400c58d090f82de491e13a9cf5fe6c90336079d
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date: Fri Apr 10 15:55:18 2026 -0700
Remove potential null dereference in pt_in_ring_3d()
diff --git a/liblwgeom/measures3d.c b/liblwgeom/measures3d.c
index 49889bf31..ab9b2387e 100644
--- a/liblwgeom/measures3d.c
+++ b/liblwgeom/measures3d.c
@@ -1580,6 +1580,9 @@ pt_in_ring_3d(const POINT3DZ *p, const POINTARRAY *ring, PLANE3D *plane)
POINT3DZ first, last;
+ if ( !ring || ring->npoints == 0 )
+ lwerror("%s called on empty pointarray", __func__);
+
getPoint3dz_p(ring, 0, &first);
getPoint3dz_p(ring, ring->npoints - 1, &last);
if (memcmp(&first, &last, sizeof(POINT3DZ)))
commit 4808f465b86df6b9b69d569cef36acefc43be710
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date: Fri Apr 10 15:36:05 2026 -0700
Remove potential null dereference from ptarray_contains_point_partial()
diff --git a/liblwgeom/ptarray.c b/liblwgeom/ptarray.c
index 12114bbf2..1e62b50b8 100644
--- a/liblwgeom/ptarray.c
+++ b/liblwgeom/ptarray.c
@@ -1042,11 +1042,14 @@ ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt)
const POINT2D *seg1, *seg2;
int wn = 0;
+ if ( !pa || !pa->npoints )
+ lwerror("%s called on empty pointarray", __func__);
+
seg1 = getPoint2d_cp(pa, 0);
seg2 = getPoint2d_cp(pa, pa->npoints-1);
if (!p2d_same(seg1, seg2))
- lwerror("ptarray_contains_point called on unclosed ring");
+ lwerror("%s called on unclosed ring", __func__);
for (uint32_t i = 1; i < pa->npoints; i++)
{
commit 53f3e6fe28a25a3dc08672bcc91d0549542fcf59
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date: Fri Apr 10 15:31:16 2026 -0700
Remove unused function pt_in_ring_2d()
diff --git a/liblwgeom/liblwgeom.h.in b/liblwgeom/liblwgeom.h.in
index 69ed8f354..ab2ff2114 100644
--- a/liblwgeom/liblwgeom.h.in
+++ b/liblwgeom/liblwgeom.h.in
@@ -1342,7 +1342,6 @@ extern LWPOINT* lwcompound_get_endpoint(const LWCOMPOUND *lwcmp);
extern LWPOINT* lwcompound_get_lwpoint(const LWCOMPOUND *lwcmp, uint32_t where);
extern double ptarray_length_2d(const POINTARRAY *pts);
-extern int pt_in_ring_2d(const POINT2D *p, const POINTARRAY *ring);
extern int azimuth_pt_pt(const POINT2D *p1, const POINT2D *p2, double *ret);
extern LWPOINT* lwpoint_project_lwpoint(const LWPOINT* lwpoint1, const LWPOINT* lwpoint2, double distance);
extern LWPOINT* lwpoint_project(const LWPOINT* lwpoint1, double distance, double azimuth);
diff --git a/liblwgeom/liblwgeom_internal.h b/liblwgeom/liblwgeom_internal.h
index 66dabaffa..86816ddd5 100644
--- a/liblwgeom/liblwgeom_internal.h
+++ b/liblwgeom/liblwgeom_internal.h
@@ -446,7 +446,6 @@ int lw_arc_is_pt(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3);
int lw_pt_on_segment(const POINT2D* p1, const POINT2D* p2, const POINT2D* p);
double lw_seg_length(const POINT2D *A1, const POINT2D *A2);
double lw_arc_length(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3);
-int pt_in_ring_2d(const POINT2D *p, const POINTARRAY *ring);
int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt);
int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt);
int ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number);
diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c
index 3cf3a7d33..1697320c1 100644
--- a/liblwgeom/lwalgorithm.c
+++ b/liblwgeom/lwalgorithm.c
@@ -285,62 +285,6 @@ lw_arc_center(const POINT2D *p1, const POINT2D *p2, const POINT2D *p3, POINT2D *
return cr;
}
-int
-pt_in_ring_2d(const POINT2D *p, const POINTARRAY *ring)
-{
- int cn = 0; /* the crossing number counter */
- uint32_t i;
- const POINT2D *v1, *v2;
- const POINT2D *first, *last;
-
- first = getPoint2d_cp(ring, 0);
- last = getPoint2d_cp(ring, ring->npoints-1);
- if ( memcmp(first, last, sizeof(POINT2D)) )
- {
- lwerror("pt_in_ring_2d: V[n] != V[0] (%g %g != %g %g)",
- first->x, first->y, last->x, last->y);
- return LW_FALSE;
-
- }
-
- LWDEBUGF(2, "pt_in_ring_2d called with point: %g %g", p->x, p->y);
- /* printPA(ring); */
-
- /* loop through all edges of the polygon */
- v1 = getPoint2d_cp(ring, 0);
- for (i=0; i<ring->npoints-1; i++)
- {
- double vt;
- v2 = getPoint2d_cp(ring, i+1);
-
- /* edge from vertex i to vertex i+1 */
- if
- (
- /* an upward crossing */
- ((v1->y <= p->y) && (v2->y > p->y))
- /* a downward crossing */
- || ((v1->y > p->y) && (v2->y <= p->y))
- )
- {
-
- vt = (double)(p->y - v1->y) / (v2->y - v1->y);
-
- /* P->x <intersect */
- if (p->x < v1->x + vt * (v2->x - v1->x))
- {
- /* a valid crossing of y=p->y right of p->x */
- ++cn;
- }
- }
- v1 = v2;
- }
-
- LWDEBUGF(3, "pt_in_ring_2d returning %d", cn&1);
-
- return (cn&1); /* 0 if even (out), and 1 if odd (in) */
-}
-
-
static int
lw_seg_interact(const POINT2D *p1, const POINT2D *p2, const POINT2D *q1, const POINT2D *q2)
{
commit 02597250d8753f072363872d35b558fd43911d24
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date: Fri Apr 10 15:29:19 2026 -0700
Remove reported crash in lwcompound_add_lwgeom()
diff --git a/liblwgeom/lwcompound.c b/liblwgeom/lwcompound.c
index 3fc5de4f7..94fe04a52 100644
--- a/liblwgeom/lwcompound.c
+++ b/liblwgeom/lwcompound.c
@@ -155,6 +155,9 @@ int lwcompound_add_lwgeom(LWCOMPOUND *comp, LWGEOM *geom)
/* Last point of the previous component */
LWLINE *prevline = (LWLINE*)(col->geoms[col->ngeoms-1]);
+ if (lwline_is_empty(prevline))
+ return LW_FAILURE;
+
getPoint4d_p(newline->points, 0, &first);
getPoint4d_p(prevline->points, prevline->points->npoints-1, &last);
commit 10f8aa4840b2fa57f8d24abc92dd1b3f36d92daa
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date: Fri Apr 10 13:56:41 2026 -0700
Remove reported crash in lwline_set_effective_area()
diff --git a/liblwgeom/effectivearea.c b/liblwgeom/effectivearea.c
index e9859218d..3c038c5f5 100644
--- a/liblwgeom/effectivearea.c
+++ b/liblwgeom/effectivearea.c
@@ -464,7 +464,8 @@ static LWLINE* lwline_set_effective_area(const LWLINE *iline,int set_area, doubl
LWLINE *oline = lwline_construct_empty(iline->srid, FLAGS_GET_Z(iline->flags), set_m);
-
+ if (iline->points->npoints < 2)
+ return oline;
oline = lwline_construct(iline->srid, NULL, ptarray_set_effective_area(iline->points,2,set_area,trshld));
@@ -491,7 +492,12 @@ static LWPOLY* lwpoly_set_effective_area(const LWPOLY *ipoly,int set_area, doubl
for (i = 0; i < ipoly->nrings; i++)
{
- POINTARRAY *pa = ptarray_set_effective_area(ipoly->rings[i],avoid_collapse,set_area,trshld);
+ POINTARRAY *pa;
+
+ if (ipoly->rings[i]->npoints < 4)
+ continue;
+
+ pa = ptarray_set_effective_area(ipoly->rings[i],avoid_collapse,set_area,trshld);
/* Add ring to simplified polygon */
if(pa->npoints>=4)
{
commit 1a9074a7bbbea7ea5f24af593034485cdd499a26
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date: Fri Apr 10 14:56:21 2026 -0700
Remove reported crash in lwcompound_is_closed()
diff --git a/liblwgeom/lwcompound.c b/liblwgeom/lwcompound.c
index 666b455da..3fc5de4f7 100644
--- a/liblwgeom/lwcompound.c
+++ b/liblwgeom/lwcompound.c
@@ -29,43 +29,94 @@
#include "liblwgeom_internal.h"
#include "lwgeom_log.h"
-
-
-int
-lwcompound_is_closed(const LWCOMPOUND *compound)
+static int
+lwcompound_is_valid(const LWCOMPOUND *compound)
{
- size_t size;
- int npoints=0;
+ int hasz = lwgeom_has_z(lwcompound_as_lwgeom(compound));
+ if (lwgeom_is_empty(lwcompound_as_lwgeom(compound)))
+ return LW_TRUE;
- if ( lwgeom_has_z((LWGEOM*)compound) )
- {
- size = sizeof(POINT3D);
- }
- else
- {
- size = sizeof(POINT2D);
- }
+ /* Only one component, do not need to test connectivity */
+ if (compound->ngeoms == 1)
+ return LW_TRUE;
- if ( compound->geoms[compound->ngeoms - 1]->type == CIRCSTRINGTYPE )
+ /* Check internal connectivity between components */
+ for (uint32_t i = 1; i < compound->ngeoms; i++)
{
- npoints = ((LWCIRCSTRING *)compound->geoms[compound->ngeoms - 1])->points->npoints;
- }
- else if (compound->geoms[compound->ngeoms - 1]->type == LINETYPE)
- {
- npoints = ((LWLINE *)compound->geoms[compound->ngeoms - 1])->points->npoints;
- }
+ const POINTARRAY *pa_start, *pa_end;
+ const LWLINE *line_start = (LWLINE *)(compound->geoms[i]);
+ const LWLINE *line_end = (LWLINE *)(compound->geoms[i-1]);
- if ( memcmp(getPoint_internal( (POINTARRAY *)compound->geoms[0]->data, 0),
- getPoint_internal( (POINTARRAY *)compound->geoms[compound->ngeoms - 1]->data,
- npoints - 1),
- size) )
- {
- return LW_FALSE;
+ /* Empty cannot be a compound component, because it joins nothing */
+ if (lwline_is_empty(line_start) || (lwline_is_empty(line_end)))
+ return LW_FALSE;
+
+ pa_start = line_start->points;
+ pa_end = line_end->points;
+
+ if (hasz)
+ {
+ const POINT3D *pt_start = getPoint3d_cp(pa_start, 0);
+ const POINT3D *pt_end = getPoint3d_cp(pa_end, pa_end->npoints-1);
+ if (!p3d_same(pt_start, pt_end))
+ return LW_FALSE;
+ }
+ else
+ {
+ const POINT2D *pt_start = getPoint2d_cp(pa_start, 0);
+ const POINT2D *pt_end = getPoint2d_cp(pa_end, pa_end->npoints-1);
+ if (!p2d_same(pt_start, pt_end))
+ return LW_FALSE;
+ }
}
return LW_TRUE;
}
+int
+lwcompound_is_closed(const LWCOMPOUND *compound)
+{
+ const LWLINE *line_start, *line_end;
+ const POINTARRAY *pa_start, *pa_end;
+
+ int hasz = lwgeom_has_z(lwcompound_as_lwgeom(compound));
+ if (lwgeom_is_empty(lwcompound_as_lwgeom(compound)))
+ return LW_FALSE;
+
+ /* Single entry, closes on itself */
+ if (compound->ngeoms == 1 && lwline_is_closed((LWLINE *)(compound->geoms[0])))
+ return LW_TRUE;
+
+ /* If internal connectivity is lacking, so is closure */
+ if (!lwcompound_is_valid(compound))
+ return LW_FALSE;
+
+ /* Internal connection is good, what about start/end points? */
+ line_start = (LWLINE *)(compound->geoms[0]);
+ line_end = (LWLINE *)(compound->geoms[compound->ngeoms-1]);
+ pa_start = line_start->points;
+ pa_end = line_end->points;
+
+ if (hasz)
+ {
+ const POINT3D *pt_start = getPoint3d_cp(pa_start, 0);
+ const POINT3D *pt_end = getPoint3d_cp(pa_end, pa_end->npoints-1);
+ if (!p3d_same(pt_start, pt_end))
+ return LW_FALSE;
+ }
+ else
+ {
+ const POINT2D *pt_start = getPoint2d_cp(pa_start, 0);
+ const POINT2D *pt_end = getPoint2d_cp(pa_end, pa_end->npoints-1);
+ if (!p2d_same(pt_start, pt_end))
+ return LW_FALSE;
+ }
+
+ return LW_TRUE;
+}
+
+
+
double lwcompound_length(const LWCOMPOUND *comp)
{
return lwcompound_length_2d(comp);
-----------------------------------------------------------------------
Summary of changes:
liblwgeom/effectivearea.c | 13 +++++-
liblwgeom/liblwgeom.h.in | 1 -
liblwgeom/liblwgeom_internal.h | 1 -
liblwgeom/lwalgorithm.c | 56 ------------------------
liblwgeom/lwcompound.c | 98 ++++++++++++++++++++++++++++++++----------
liblwgeom/lwstroke.c | 7 ++-
liblwgeom/measures3d.c | 3 ++
liblwgeom/ptarray.c | 5 ++-
8 files changed, 99 insertions(+), 85 deletions(-)
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list