[SCM] PostGIS branch master updated. 3.7.0beta2-29-g321342d9e
git at osgeo.org
git at osgeo.org
Tue Aug 11 10:35:45 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 321342d9e1b2f88dfeae3d7050539bfacfd27d10 (commit)
via ee01b53cd8449eee04548d11bf00a8a5d2b7dd3b (commit)
via 5bbc1de9bf2c53f85a46a95b4726060454d6f213 (commit)
via 58300a97ac7b2c454461771c53298b4bf1d63beb (commit)
from 369235b92e0d03584916c42bf074cd02122addb9 (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 321342d9e1b2f88dfeae3d7050539bfacfd27d10
Merge: 369235b92 ee01b53cd
Author: Darafei Praliaskouski <komzpa at gmail.com>
Date: Tue Aug 11 10:35:44 2026 -0700
Merge pull request 'Handle topology and shp2pgsql allocation failures' (!728) from Komzpa/postgis:pick/gh-1170-1171-alloc-handlers into master
Ports two allocation-failure hardening patches from GitHub mirror pull requests into the canonical Gitea review flow.
- Handle failed topology ring-shell array allocation before constructing the shell polygon.
- Handle shp2pgsql loader allocation failures during loader creation, field metadata setup, geometry array construction, polygon ring construction, and escaped attribute output.
The branch also includes a review follow-up that replaces an assert-only polygon ring size guard with a runtime bounds check and shared allocation-failure cleanup.
References https://github.com/postgis/postgis/pull/1170
References https://github.com/postgis/postgis/pull/1171
Reviewed-on: https://gitea.osgeo.org/postgis/postgis/pulls/728
commit ee01b53cd8449eee04548d11bf00a8a5d2b7dd3b
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Tue Aug 11 19:29:07 2026 +0400
loader: harden allocation failure cleanup
diff --git a/liblwgeom/topo/lwgeom_topo.c b/liblwgeom/topo/lwgeom_topo.c
index 8e18e7be1..11fed9091 100644
--- a/liblwgeom/topo/lwgeom_topo.c
+++ b/liblwgeom/topo/lwgeom_topo.c
@@ -2072,9 +2072,9 @@ _lwt_MakeRingShell(LWT_TOPOLOGY *topo, LWT_ELEMID *signed_edge_ids, uint64_t num
POINTARRAY **points = lwalloc(sizeof(POINTARRAY*));
if (!points)
{
- ptarray_free(full_ring_pa);
- lwerror("Could not allocate ring shell rings array");
- return NULL;
+ ptarray_free(full_ring_pa);
+ lwerror("Could not allocate ring shell rings array");
+ return NULL;
}
points[0] = full_ring_pa;
diff --git a/loader/shp2pgsql-core.c b/loader/shp2pgsql-core.c
index ded9472e1..74415c039 100644
--- a/loader/shp2pgsql-core.c
+++ b/loader/shp2pgsql-core.c
@@ -16,7 +16,7 @@
#include "../postgis_config.h"
#include <math.h> /* for isnan */
-#include <limits.h>
+#include <stdint.h>
#include <strings.h>
#include "shp2pgsql-core.h"
@@ -469,6 +469,39 @@ PIP(Point P, Point *V, int n)
return (cn&1); /* 0 if even (out), and 1 if odd (in) */
}
+static void
+ShpLoaderFreeFieldMetadata(SHPLOADERSTATE *state)
+{
+ for (int j = 0; j < state->num_fields; j++)
+ {
+ if (state->field_names)
+ free(state->field_names[j]);
+ if (state->pgfieldtypes)
+ free(state->pgfieldtypes[j]);
+ }
+
+ free(state->field_names);
+ state->field_names = NULL;
+ free(state->types);
+ state->types = NULL;
+ free(state->widths);
+ state->widths = NULL;
+ free(state->precisions);
+ state->precisions = NULL;
+ free(state->pgfieldtypes);
+ state->pgfieldtypes = NULL;
+ free(state->col_names);
+ state->col_names = NULL;
+ state->num_fields = 0;
+}
+
+static int
+ShpLoaderOpenShapeFieldAllocFailure(SHPLOADERSTATE *state)
+{
+ ShpLoaderFreeFieldMetadata(state);
+ snprintf(state->message, SHPLOADERMSGLEN, "unable to allocate memory for field information");
+ return SHPLOADERERR;
+}
int
FindPolygons(SHPObject *obj, Ring ***Out)
@@ -516,7 +549,23 @@ FindPolygons(SHPObject *obj, Ring ***Out)
/* Compute number of vertices */
nv = ve - vs;
- assert(nv >= 0 && nv < INT_MAX / sizeof(Point));
+ if (nv <= 0 || (size_t)nv > SIZE_MAX / sizeof(*ring->list))
+ {
+ for (pi = 0; pi < out_index; pi++)
+ {
+ free(Outer[pi]->list);
+ free(Outer[pi]);
+ }
+ for (pi = 0; pi < in_index; pi++)
+ {
+ free(Inner[pi]->list);
+ free(Inner[pi]);
+ }
+ free(Outer);
+ free(Inner);
+ return -1;
+ }
+ size_t ring_list_size = sizeof(*ring->list) * (size_t)nv;
/* Allocate memory for a ring */
ring = (Ring *)malloc(sizeof(Ring));
@@ -537,7 +586,7 @@ FindPolygons(SHPObject *obj, Ring ***Out)
free(Inner);
return -1;
}
- ring->list = (Point *)malloc(sizeof(Point) * (size_t)nv);
+ ring->list = (Point *)malloc(ring_list_size);
if (!ring->list)
{
free(ring);
@@ -1391,7 +1440,7 @@ ShpLoaderOpenShape(SHPLOADERSTATE *state)
* field_names and pgfieldtypes hold per-field strings that are freed
* individually; use calloc so any slot never assigned stays NULL and
* free(NULL) is safe on the allocation-failure cleanup path. */
- state->field_names = calloc(state->num_fields, sizeof(char*));
+ state->field_names = calloc(state->num_fields, sizeof(char *));
state->types = (DBFFieldType *)malloc(state->num_fields * sizeof(int));
state->widths = malloc(state->num_fields * sizeof(int));
state->precisions = malloc(state->num_fields * sizeof(int));
@@ -1401,12 +1450,11 @@ ShpLoaderOpenShape(SHPLOADERSTATE *state)
(state->config->readshape ? strlen(state->geo_col) : 0) + 1,
sizeof(char)
);
- if (!state->col_names ||
- (state->num_fields && (!state->field_names || !state->types ||
- !state->widths || !state->precisions || !state->pgfieldtypes)))
+ int fields_allocated = !state->num_fields || (state->field_names && state->types && state->widths &&
+ state->precisions && state->pgfieldtypes);
+ if (!state->col_names || !fields_allocated)
{
- state->num_fields = 0;
- goto open_shape_field_alloc_failure;
+ return ShpLoaderOpenShapeFieldAllocFailure(state);
}
/* Generate a string of comma separated column names of the form "col1, col2 ... colN" for the SQL
@@ -1496,7 +1544,7 @@ ShpLoaderOpenShape(SHPLOADERSTATE *state)
state->field_names[j] = strdup(name);
if (!state->field_names[j])
- goto open_shape_field_alloc_failure;
+ return ShpLoaderOpenShapeFieldAllocFailure(state);
/* Now generate the PostgreSQL type name string and width based upon the shapefile type */
switch (state->types[j])
@@ -1553,7 +1601,7 @@ ShpLoaderOpenShape(SHPLOADERSTATE *state)
}
if (!state->pgfieldtypes[j])
- goto open_shape_field_alloc_failure;
+ return ShpLoaderOpenShapeFieldAllocFailure(state);
strcat(state->col_names, "\"");
strcat(state->col_names, name);
@@ -1575,31 +1623,6 @@ ShpLoaderOpenShape(SHPLOADERSTATE *state)
/* Return status */
return ret;
-
-open_shape_field_alloc_failure:
- /* Release the per-field strings populated so far; free(NULL) is safe for
- * the slots that were never assigned. */
- for (int j = 0; j < state->num_fields; j++)
- {
- free(state->field_names[j]);
- free(state->pgfieldtypes[j]);
- }
- free(state->field_names);
- state->field_names = NULL;
- free(state->types);
- state->types = NULL;
- free(state->widths);
- state->widths = NULL;
- free(state->precisions);
- state->precisions = NULL;
- free(state->pgfieldtypes);
- state->pgfieldtypes = NULL;
- free(state->col_names);
- state->col_names = NULL;
- state->num_fields = 0;
- state->num_records = 0;
- snprintf(state->message, SHPLOADERMSGLEN, "unable to allocate memory for field information");
- return SHPLOADERERR;
}
/* Return a pointer to an allocated string containing the header for the specified loader state */
@@ -1983,7 +2006,9 @@ ShpLoaderGenerateSQLRowStatement(SHPLOADERSTATE *state, int item, char **strreco
if (!escval)
{
- snprintf(state->message, SHPLOADERMSGLEN, "unable to allocate memory for escaped attribute value");
+ snprintf(state->message,
+ SHPLOADERMSGLEN,
+ "unable to allocate memory for escaped attribute value");
SHPDestroyObject(obj);
stringbuffer_destroy(sbwarn);
stringbuffer_destroy(sb);
@@ -2233,35 +2258,13 @@ void
ShpLoaderDestroy(SHPLOADERSTATE *state)
{
/* Destroy a state object created with ShpLoaderOpenShape */
- int i;
if (state != NULL)
{
if (state->hSHPHandle)
SHPClose(state->hSHPHandle);
if (state->hDBFHandle)
DBFClose(state->hDBFHandle);
- if (state->field_names)
- {
- for (i = 0; i < state->num_fields; i++)
- free(state->field_names[i]);
-
- free(state->field_names);
- }
- if (state->pgfieldtypes)
- {
- for (i = 0; i < state->num_fields; i++)
- free(state->pgfieldtypes[i]);
-
- free(state->pgfieldtypes);
- }
- if (state->types)
- free(state->types);
- if (state->widths)
- free(state->widths);
- if (state->precisions)
- free(state->precisions);
- if (state->col_names)
- free(state->col_names);
+ ShpLoaderFreeFieldMetadata(state);
/* Free any column map fieldnames if specified */
colmap_clean(&state->column_map);
diff --git a/loader/shp2pgsql-gui.c b/loader/shp2pgsql-gui.c
index 50f9c8623..16ba66a4b 100644
--- a/loader/shp2pgsql-gui.c
+++ b/loader/shp2pgsql-gui.c
@@ -1579,7 +1579,15 @@ pgui_action_import(GtkWidget *widget, gpointer data)
if (!state)
{
pgui_logf(_("Warning: Could not load shapefile %s"), loader_file_config->shp_file);
- goto import_cleanup;
+ ret = SHPLOADERERR;
+ is_running = FALSE;
+ PQfinish(pg_connection);
+ pg_connection = NULL;
+ pgui_logf(_("Shapefile import failed."));
+ free(progress_shapefile);
+ progress_shapefile = NULL;
+ is_valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(import_file_list_store), &iter);
+ continue;
}
/* Open the shapefile */
commit 5bbc1de9bf2c53f85a46a95b4726060454d6f213
Author: Maksim Korotkov <m.korotkov at postgrespro.ru>
Date: Tue Aug 11 19:29:06 2026 +0400
loader: handle shp2pgsql allocation failures
Check the return of malloc/calloc in the shp2pgsql loader paths and bail out cleanly instead of dereferencing NULL. Escaped-value and field-info allocation failures now error out before the value is written, so no unescaped attribute reaches the output buffer. The partial-allocation paths in FindPolygons and ShpLoaderOpenShape release what was already allocated and null the owning pointers so ShpLoaderDestroy stays safe.
Found by PostgresPro with Svace Static Analyzer.
Signed-off-by: Maksim Korotkov <m.korotkov at postgrespro.ru>
diff --git a/loader/shp2pgsql-cli.c b/loader/shp2pgsql-cli.c
index a7c6db37d..394140980 100644
--- a/loader/shp2pgsql-cli.c
+++ b/loader/shp2pgsql-cli.c
@@ -571,6 +571,11 @@ main (int argc, char **argv)
/* Create the shapefile state object */
state = ShpLoaderCreate(config);
+ if (!state)
+ {
+ fprintf(stderr, "Unable to allocate memory for loader state\n");
+ exit(1);
+ }
/* Open the shapefile */
ret = ShpLoaderOpenShape(state);
diff --git a/loader/shp2pgsql-core.c b/loader/shp2pgsql-core.c
index 9ebfa8fb4..ded9472e1 100644
--- a/loader/shp2pgsql-core.c
+++ b/loader/shp2pgsql-core.c
@@ -16,6 +16,7 @@
#include "../postgis_config.h"
#include <math.h> /* for isnan */
+#include <limits.h>
#include <strings.h>
#include "shp2pgsql-core.h"
@@ -170,6 +171,8 @@ escape_copy_string(char *str)
size = ptr - str + toescape + 1;
result = calloc(1, size);
+ if (!result)
+ return NULL;
optr = result;
ptr = str;
@@ -223,6 +226,8 @@ escape_insert_string(char *str)
size = ptr - str + toescape + 1;
result = calloc(1, size);
+ if (!result)
+ return NULL;
optr = result;
ptr = str;
@@ -271,6 +276,11 @@ GeneratePointGeometry(SHPLOADERSTATE *state, SHPObject *obj, char **geometry, in
{
/* Allocate memory for our array of LWPOINTs and our dynptarrays */
lwmultipoints = malloc(sizeof(LWPOINT *) * obj->nVertices);
+ if (!lwmultipoints)
+ {
+ snprintf(state->message, SHPLOADERMSGLEN, "unable to allocate memory for point geometry");
+ return SHPLOADERERR;
+ }
/* We need an array of pointers to each of our sub-geometries */
for (u = 0; u < obj->nVertices; u++)
@@ -361,6 +371,11 @@ GenerateLineStringGeometry(SHPLOADERSTATE *state, SHPObject *obj, char **geometr
/* Allocate memory for our array of LWLINEs and our dynptarrays */
lwmultilinestrings = malloc(sizeof(LWPOINT *) * obj->nParts);
+ if (!lwmultilinestrings)
+ {
+ snprintf(state->message, SHPLOADERMSGLEN, "unable to allocate memory for linestring geometry");
+ return SHPLOADERERR;
+ }
/* We need an array of pointers to each of our sub-geometries */
for (u = 0; u < obj->nParts; u++)
@@ -474,6 +489,12 @@ FindPolygons(SHPObject *obj, Ring ***Out)
/* Allocate initial memory */
Outer = (Ring **)malloc(sizeof(Ring *) * obj->nParts);
Inner = (Ring **)malloc(sizeof(Ring *) * obj->nParts);
+ if (!Outer || !Inner)
+ {
+ free(Outer);
+ free(Inner);
+ return -1;
+ }
/* Iterate over rings dividing in Outers and Inners */
for (pi=0; pi < obj->nParts; pi++)
@@ -495,10 +516,46 @@ FindPolygons(SHPObject *obj, Ring ***Out)
/* Compute number of vertices */
nv = ve - vs;
+ assert(nv >= 0 && nv < INT_MAX / sizeof(Point));
/* Allocate memory for a ring */
ring = (Ring *)malloc(sizeof(Ring));
- ring->list = (Point *)malloc(sizeof(Point) * nv);
+ if (!ring)
+ {
+ /* Free rings allocated so far (stored in Outer/Inner) */
+ for (pi = 0; pi < out_index; pi++)
+ {
+ free(Outer[pi]->list);
+ free(Outer[pi]);
+ }
+ for (pi = 0; pi < in_index; pi++)
+ {
+ free(Inner[pi]->list);
+ free(Inner[pi]);
+ }
+ free(Outer);
+ free(Inner);
+ return -1;
+ }
+ ring->list = (Point *)malloc(sizeof(Point) * (size_t)nv);
+ if (!ring->list)
+ {
+ free(ring);
+ /* Free rings allocated so far (stored in Outer/Inner) */
+ for (pi = 0; pi < out_index; pi++)
+ {
+ free(Outer[pi]->list);
+ free(Outer[pi]);
+ }
+ for (pi = 0; pi < in_index; pi++)
+ {
+ free(Inner[pi]->list);
+ free(Inner[pi]);
+ }
+ free(Outer);
+ free(Inner);
+ return -1;
+ }
ring->n = nv;
ring->next = NULL;
ring->linked = 0;
@@ -660,6 +717,12 @@ GeneratePolygonGeometry(SHPLOADERSTATE *state, SHPObject *obj, char **geometry)
polygon_total = FindPolygons(obj, &Outer);
+ if (polygon_total < 0)
+ {
+ snprintf(state->message, SHPLOADERMSGLEN, "unable to allocate memory for polygon rings");
+ return SHPLOADERERR;
+ }
+
if (state->config->simple_geometries == 1 && polygon_total != 1) /* We write Non-MULTI geometries, but have several parts: */
{
snprintf(state->message, SHPLOADERMSGLEN, _("We have a Multipolygon with %d parts, can't use -S switch!"), polygon_total);
@@ -669,6 +732,12 @@ GeneratePolygonGeometry(SHPLOADERSTATE *state, SHPObject *obj, char **geometry)
/* Allocate memory for our array of LWPOLYs */
lwpolygons = malloc(sizeof(LWPOLY *) * polygon_total);
+ if (!lwpolygons)
+ {
+ ReleasePolygons(Outer, polygon_total);
+ snprintf(state->message, SHPLOADERMSGLEN, "unable to allocate memory for polygon geometry");
+ return SHPLOADERERR;
+ }
/* Cycle through each individual polygon */
for (pi = 0; pi < polygon_total; pi++)
@@ -1000,6 +1069,8 @@ ShpLoaderCreate(SHPLOADERCONFIG *config)
/* Create a new state object and assign the config to it */
state = malloc(sizeof(SHPLOADERSTATE));
+ if (!state)
+ return NULL;
state->config = config;
/* Set any state defaults */
@@ -1316,17 +1387,27 @@ ShpLoaderOpenShape(SHPLOADERSTATE *state)
state->num_records = DBFGetRecordCount(state->hDBFHandle);
- /* Allocate storage for field information */
- state->field_names = malloc(state->num_fields * sizeof(char*));
+ /* Allocate storage for field information.
+ * field_names and pgfieldtypes hold per-field strings that are freed
+ * individually; use calloc so any slot never assigned stays NULL and
+ * free(NULL) is safe on the allocation-failure cleanup path. */
+ state->field_names = calloc(state->num_fields, sizeof(char*));
state->types = (DBFFieldType *)malloc(state->num_fields * sizeof(int));
state->widths = malloc(state->num_fields * sizeof(int));
state->precisions = malloc(state->num_fields * sizeof(int));
- state->pgfieldtypes = malloc(state->num_fields * sizeof(char *));
+ state->pgfieldtypes = calloc(state->num_fields, sizeof(char *));
state->col_names = calloc(
(size_t)state->num_fields * (MAXFIELDNAMELEN + 2) +
(state->config->readshape ? strlen(state->geo_col) : 0) + 1,
sizeof(char)
);
+ if (!state->col_names ||
+ (state->num_fields && (!state->field_names || !state->types ||
+ !state->widths || !state->precisions || !state->pgfieldtypes)))
+ {
+ state->num_fields = 0;
+ goto open_shape_field_alloc_failure;
+ }
/* Generate a string of comma separated column names of the form "col1, col2 ... colN" for the SQL
insertion string */
@@ -1414,6 +1495,8 @@ ShpLoaderOpenShape(SHPLOADERSTATE *state)
}
state->field_names[j] = strdup(name);
+ if (!state->field_names[j])
+ goto open_shape_field_alloc_failure;
/* Now generate the PostgreSQL type name string and width based upon the shapefile type */
switch (state->types[j])
@@ -1469,6 +1552,9 @@ ShpLoaderOpenShape(SHPLOADERSTATE *state)
return SHPLOADERERR;
}
+ if (!state->pgfieldtypes[j])
+ goto open_shape_field_alloc_failure;
+
strcat(state->col_names, "\"");
strcat(state->col_names, name);
@@ -1489,6 +1575,31 @@ ShpLoaderOpenShape(SHPLOADERSTATE *state)
/* Return status */
return ret;
+
+open_shape_field_alloc_failure:
+ /* Release the per-field strings populated so far; free(NULL) is safe for
+ * the slots that were never assigned. */
+ for (int j = 0; j < state->num_fields; j++)
+ {
+ free(state->field_names[j]);
+ free(state->pgfieldtypes[j]);
+ }
+ free(state->field_names);
+ state->field_names = NULL;
+ free(state->types);
+ state->types = NULL;
+ free(state->widths);
+ state->widths = NULL;
+ free(state->precisions);
+ state->precisions = NULL;
+ free(state->pgfieldtypes);
+ state->pgfieldtypes = NULL;
+ free(state->col_names);
+ state->col_names = NULL;
+ state->num_fields = 0;
+ state->num_records = 0;
+ snprintf(state->message, SHPLOADERMSGLEN, "unable to allocate memory for field information");
+ return SHPLOADERERR;
}
/* Return a pointer to an allocated string containing the header for the specified loader state */
@@ -1864,14 +1975,26 @@ ShpLoaderGenerateSQLRowStatement(SHPLOADERSTATE *state, int item, char **strreco
if (state->config->dump_format)
{
escval = escape_copy_string(val);
- stringbuffer_aprintf(sb, "%s", escval);
}
else
{
escval = escape_insert_string(val);
- stringbuffer_aprintf(sb, "'%s'", escval);
}
+ if (!escval)
+ {
+ snprintf(state->message, SHPLOADERMSGLEN, "unable to allocate memory for escaped attribute value");
+ SHPDestroyObject(obj);
+ stringbuffer_destroy(sbwarn);
+ stringbuffer_destroy(sb);
+ return SHPLOADERERR;
+ }
+
+ if (state->config->dump_format)
+ stringbuffer_aprintf(sb, "%s", escval);
+ else
+ stringbuffer_aprintf(sb, "'%s'", escval);
+
/* Free the escaped version if required */
if (val != escval)
free(escval);
diff --git a/loader/shp2pgsql-gui.c b/loader/shp2pgsql-gui.c
index 37a9a04d0..50f9c8623 100644
--- a/loader/shp2pgsql-gui.c
+++ b/loader/shp2pgsql-gui.c
@@ -1219,6 +1219,11 @@ validate_remote_loader_columns(SHPLOADERCONFIG *config, PGresult *result)
{
/* If we have a row then lets do some simple column validation... */
state = ShpLoaderCreate(config);
+ if (!state)
+ {
+ pgui_logf(_("Warning: Could not load shapefile %s"), config->shp_file);
+ return SHPLOADERERR;
+ }
ret = ShpLoaderOpenShape(state);
if (ret != SHPLOADEROK)
{
@@ -1571,6 +1576,11 @@ pgui_action_import(GtkWidget *widget, gpointer data)
/* Create the shapefile state object */
state = ShpLoaderCreate(loader_file_config);
+ if (!state)
+ {
+ pgui_logf(_("Warning: Could not load shapefile %s"), loader_file_config->shp_file);
+ goto import_cleanup;
+ }
/* Open the shapefile */
ret = ShpLoaderOpenShape(state);
@@ -1768,7 +1778,9 @@ import_cleanup:
pg_connection = NULL;
/* If we didn't finish inserting all of the items (and we expected to), an error occurred */
- if ((state->config->plan.load_data && i != ShpLoaderGetRecordCount(state)) || !ret)
+ if (state && ((state->config->plan.load_data && i != ShpLoaderGetRecordCount(state)) || !ret))
+ pgui_logf(_("Shapefile import failed."));
+ else if (!state)
pgui_logf(_("Shapefile import failed."));
else
pgui_logf(_("Shapefile import completed."));
commit 58300a97ac7b2c454461771c53298b4bf1d63beb
Author: Maksim Korotkov <m.korotkov at postgrespro.ru>
Date: Tue Aug 11 19:29:06 2026 +0400
topo: handle ring shell allocation failure
default_allocator can silently return NULL.
Signed-off-by: Maksim Korotkov <m.korotkov at postgrespro.ru>
diff --git a/liblwgeom/topo/lwgeom_topo.c b/liblwgeom/topo/lwgeom_topo.c
index 5ac10cb83..8e18e7be1 100644
--- a/liblwgeom/topo/lwgeom_topo.c
+++ b/liblwgeom/topo/lwgeom_topo.c
@@ -2070,6 +2070,12 @@ _lwt_MakeRingShell(LWT_TOPOLOGY *topo, LWT_ELEMID *signed_edge_ids, uint64_t num
*isccw = lwt_IsTopoRingCCW(full_ring_pa);
POINTARRAY **points = lwalloc(sizeof(POINTARRAY*));
+ if (!points)
+ {
+ ptarray_free(full_ring_pa);
+ lwerror("Could not allocate ring shell rings array");
+ return NULL;
+ }
points[0] = full_ring_pa;
/* NOTE: the ring may very well have collapsed components,
-----------------------------------------------------------------------
Summary of changes:
liblwgeom/topo/lwgeom_topo.c | 6 ++
loader/shp2pgsql-cli.c | 5 ++
loader/shp2pgsql-core.c | 184 ++++++++++++++++++++++++++++++++++++-------
loader/shp2pgsql-gui.c | 22 +++++-
4 files changed, 187 insertions(+), 30 deletions(-)
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list