Changeset: 4e895eccbc05 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=4e895eccbc05 Modified Files: geom/lib/libgeom.h geom/monetdb5/geom.c geom/monetdb5/geom.h Branch: Jun2016 Log Message:
Lots of error checking and possible leaks fixed. diffs (truncated from 1934 to 300 lines): diff --git a/geom/lib/libgeom.h b/geom/lib/libgeom.h --- a/geom/lib/libgeom.h +++ b/geom/lib/libgeom.h @@ -134,7 +134,6 @@ libgeom_export void libgeom_exit(void); * On failure, returns NULL. */ //#define wkb2geos( geom ) wkb_isnil((geom))? NULL: GEOSGeomFromWKB_buf((unsigned char *)((geom)->data), (geom)->len) -//#define wkb_nil geos2wkb(NULL); #define mbr_nil mbrFromGeos(NULL); libgeom_export int wkb_isnil(wkb *wkbp); diff --git a/geom/monetdb5/geom.c b/geom/monetdb5/geom.c --- a/geom/monetdb5/geom.c +++ b/geom/monetdb5/geom.c @@ -15,6 +15,8 @@ int TYPE_mbr; +static wkb *geos2wkb(const GEOSGeometry *geosGeometry); + static inline int geometryHasZ(int info) { @@ -60,7 +62,7 @@ radians2degrees(double *x, double *y, do } static str -transformCoordSeq(int idx, int coordinatesNum, projPJ proj4_src, projPJ proj4_dst, const GEOSCoordSequence *gcs_old, GEOSCoordSequence **gcs_new) +transformCoordSeq(int idx, int coordinatesNum, projPJ proj4_src, projPJ proj4_dst, const GEOSCoordSequence *gcs_old, GEOSCoordSeq gcs_new) { double x = 0, y = 0, z = 0; int *errorNum = 0; @@ -91,11 +93,11 @@ transformCoordSeq(int idx, int coordinat if (pj_is_latlong(proj4_dst)) radians2degrees(&x, &y, &z); - GEOSCoordSeq_setX(*gcs_new, idx, x); - GEOSCoordSeq_setY(*gcs_new, idx, y); + GEOSCoordSeq_setX(gcs_new, idx, x); + GEOSCoordSeq_setY(gcs_new, idx, y); if (coordinatesNum > 2) - GEOSCoordSeq_setZ(*gcs_new, idx, z); + GEOSCoordSeq_setZ(gcs_new, idx, z); return MAL_SUCCEED; } @@ -108,28 +110,34 @@ transformPoint(GEOSGeometry **transforme GEOSCoordSeq gcs_new; str ret = MAL_SUCCEED; + *transformedGeometry = NULL; + /* get the number of coordinates the geometry has */ coordinatesNum = GEOSGeom_getCoordinateDimension(geosGeometry); /* get the coordinates of the points comprising the geometry */ gcs_old = GEOSGeom_getCoordSeq(geosGeometry); - if (gcs_old == NULL) { - *transformedGeometry = NULL; + if (gcs_old == NULL) throw(MAL, "geom.wkbTransform", "GEOSGeom_getCoordSeq failed"); - } /* create the coordinates sequence for the transformed geometry */ gcs_new = GEOSCoordSeq_create(1, coordinatesNum); + if (gcs_new == NULL) + throw(MAL, "geom.wkbTransform", "GEOSGeom_getCoordSeq failed"); /* create the transformed coordinates */ - ret = transformCoordSeq(0, coordinatesNum, proj4_src, proj4_dst, gcs_old, &gcs_new); + ret = transformCoordSeq(0, coordinatesNum, proj4_src, proj4_dst, gcs_old, gcs_new); if (ret != MAL_SUCCEED) { - *transformedGeometry = NULL; + GEOSCoordSeq_destroy(gcs_new); return ret; } - /* create the geometry from the coordinates seqience */ + /* create the geometry from the coordinates sequence */ *transformedGeometry = GEOSGeom_createPoint(gcs_new); + if (*transformedGeometry == NULL) { + GEOSCoordSeq_destroy(gcs_new); + throw(MAL, "geom.wkbTransform", "GEOSGeom_getCoordSeq failed"); + } return MAL_SUCCEED; } @@ -155,10 +163,12 @@ transformLine(GEOSCoordSeq *gcs_new, con /* create the coordinates sequence for the transformed geometry */ *gcs_new = GEOSCoordSeq_create(pointsNum, coordinatesNum); + if (*gcs_new == NULL) + throw(MAL, "geom.wkbTransform", "GEOSCoordSeq_create failed"); /* create the transformed coordinates */ for (i = 0; i < pointsNum; i++) { - ret = transformCoordSeq(i, coordinatesNum, proj4_src, proj4_dst, gcs_old, gcs_new); + ret = transformCoordSeq(i, coordinatesNum, proj4_src, proj4_dst, gcs_old, *gcs_new); if (ret != MAL_SUCCEED) { GEOSCoordSeq_destroy(*gcs_new); *gcs_new = NULL; @@ -176,7 +186,6 @@ transformLineString(GEOSGeometry **trans str ret = MAL_SUCCEED; ret = transformLine(&coordSeq, geosGeometry, proj4_src, proj4_dst); - if (ret != MAL_SUCCEED) { *transformedGeometry = NULL; return ret; @@ -184,6 +193,10 @@ transformLineString(GEOSGeometry **trans /* create the geometry from the coordinates sequence */ *transformedGeometry = GEOSGeom_createLineString(coordSeq); + if (*transformedGeometry == NULL) { + GEOSCoordSeq_destroy(coordSeq); + throw(MAL, "geom.Transform", "GEOSGeom_createLineString failed"); + } return ret; } @@ -195,7 +208,6 @@ transformLinearRing(GEOSGeometry **trans str ret = MAL_SUCCEED; ret = transformLine(&coordSeq, geosGeometry, proj4_src, proj4_dst); - if (ret != MAL_SUCCEED) { *transformedGeometry = NULL; return ret; @@ -203,11 +215,10 @@ transformLinearRing(GEOSGeometry **trans /* create the geometry from the coordinates sequence */ *transformedGeometry = GEOSGeom_createLinearRing(coordSeq); - - GEOSCoordSeq_destroy(coordSeq); - - if (*transformedGeometry == NULL) - throw(MAL, "geom.wkbTransform", "GEOSGeom_createLinearRing failed"); + if (*transformedGeometry == NULL) { + GEOSCoordSeq_destroy(coordSeq); + throw(MAL, "geom.Transform", "GEOSGeom_createLineString failed"); + } return ret; } @@ -223,7 +234,7 @@ transformPolygon(GEOSGeometry **transfor /* get the exterior ring of the polygon */ exteriorRingGeometry = GEOSGetExteriorRing(geosGeometry); - if (!exteriorRingGeometry) { + if (exteriorRingGeometry == NULL) { *transformedGeometry = NULL; throw(MAL, "geom.wkbTransform", "GEOSGetExteriorRing failed"); } @@ -255,6 +266,7 @@ transformPolygon(GEOSGeometry **transfor while (--i >= 0) GEOSGeom_destroy(transformedInteriorRingGeometries[i]); GDKfree(transformedInteriorRingGeometries); + GEOSGeom_destroy(transformedExteriorRingGeometry); *transformedGeometry = NULL; return ret; } @@ -268,6 +280,7 @@ transformPolygon(GEOSGeometry **transfor ret = createException(MAL, "geom.wkbTransform", "GEOSGeom_createPolygon failed"); } GDKfree(transformedInteriorRingGeometries); + GEOSGeom_destroy(transformedExteriorRingGeometry); return ret; } @@ -282,6 +295,8 @@ transformMultiGeometry(GEOSGeometry **tr geometriesNum = GEOSGetNumGeometries(geosGeometry); transformedMultiGeometries = GDKmalloc(geometriesNum * sizeof(GEOSGeometry *)); + if (transformedMultiGeometries == NULL) + throw(MAL, "geom.Transform", MAL_MALLOC_FAIL); for (i = 0; i < geometriesNum; i++) { multiGeometry = GEOSGetGeometryN(geosGeometry, i); @@ -302,12 +317,14 @@ transformMultiGeometry(GEOSGeometry **tr ret = transformPolygon(&transformedMultiGeometries[i], multiGeometry, proj4_src, proj4_dst, srid); break; default: - transformedMultiGeometries[i] = NULL; ret = createException(MAL, "geom.Transform", "Unknown geometry type"); + break; } if (ret != MAL_SUCCEED) { - GDKfree(*transformedMultiGeometries); + while (--i >= 0) + GEOSGeom_destroy(transformedMultiGeometries[i]); + GDKfree(transformedMultiGeometries); *transformedGeometry = NULL; return ret; } @@ -316,16 +333,22 @@ transformMultiGeometry(GEOSGeometry **tr } *transformedGeometry = GEOSGeom_createCollection(geometryType - 1, transformedMultiGeometries, geometriesNum); + if (*transformedGeometry == NULL) { + for (i = 0; i < geometriesNum; i++) + GEOSGeom_destroy(transformedMultiGeometries[i]); + ret = createException(MAL, "geom.Transform", "GEOSGeom_createCollection failed"); + } + GDKfree(transformedMultiGeometries); return ret; } /* the following function is used in postgis to get projPJ from str. - * it is necessary to do it ina detailed way like that because pj_init_plus + * it is necessary to do it in a detailed way like that because pj_init_plus * does not set all parameters correctly and I cannot test whether the * coordinate reference systems are geographic or not */ static projPJ -projFromStr(char *projStr) +projFromStr(const char *projStr) { int t; char *params[1024]; // one for each parameter @@ -345,25 +368,16 @@ projFromStr(char *projStr) params[0] = str; // 1st param, we'll null terminate at the " " soon - loc = str; t = 1; - while ((loc != NULL) && (*loc != 0)) { - loc = strchr(loc, ' '); - if (loc != NULL) { - *loc = 0; // null terminate - params[t] = loc + 1; - loc++; // next char - t++; //next param - } - } - - if (!(result = pj_init(t, params))) { - GDKfree(str); - return NULL; - } + for (loc = strchr(str, ' '); loc != NULL; loc = strchr(loc, ' ')) { + *loc++ = 0; // null terminate and advance + params[t++] = loc; + } + + result = pj_init(t, params); GDKfree(str); + return result; - } #endif @@ -390,13 +404,18 @@ wkbTransform(wkb **transformedWKB, wkb * throw(MAL, "geom.wkbTransform", "Could not find in spatial_ref_sys srid %d\n", *srid_src); if (!strcmp(*proj4_dst_str, "null")) throw(MAL, "geom.wkbTransform", "Could not find in spatial_ref_sys srid %d\n", *srid_dst); + + if (*geomWKB == NULL) + throw(MAL, "geom.Transform", "wkb is null"); + proj4_src = /*pj_init_plus */ projFromStr(*proj4_src_str); proj4_dst = /*pj_init_plus */ projFromStr(*proj4_dst_str); - - if (*geomWKB == NULL) { - pj_free(proj4_src); - pj_free(proj4_dst); - throw(MAL, "geom.Transform", "wkb is null"); + if (proj4_src == NULL || proj4_dst == NULL) { + if (proj4_src) + pj_free(proj4_src); + if (proj4_dst) + pj_free(proj4_dst); + throw(MAL, "geom.Transform", "pj_init failed"); } /* get the geosGeometry from the wkb */ @@ -431,7 +450,8 @@ wkbTransform(wkb **transformedWKB, wkb * /* set the new srid */ GEOSSetSRID(transformedGeosGeometry, *srid_dst); /* get the wkb */ - *transformedWKB = geos2wkb(transformedGeosGeometry); + if ((*transformedWKB = geos2wkb(transformedGeosGeometry)) == NULL) + ret = createException(MAL, "geom.wkbTransform", "geos2wkb failed"); /* destroy the geos geometries */ GEOSGeom_destroy(transformedGeosGeometry); } @@ -446,7 +466,7 @@ wkbTransform(wkb **transformedWKB, wkb * //gets a coord seq and forces it to have dim dimensions adding or removing extra dimensions static str -forceDimCoordSeq(int idx, int coordinatesNum, int dim, const GEOSCoordSequence *gcs_old, GEOSCoordSequence **gcs_new) +forceDimCoordSeq(int idx, int coordinatesNum, int dim, const GEOSCoordSequence *gcs_old, GEOSCoordSeq gcs_new) { double x = 0, y = 0, z = 0; @@ -460,12 +480,12 @@ forceDimCoordSeq(int idx, int coordinate throw(MAL, "geom.ForceDim", "GEOSCoordSeq_getZ failed"); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list