[postgis-commits] svn - r2721 - trunk/lwgeom
postgis-commits at postgis.refractions.net
postgis-commits at postgis.refractions.net
Fri Nov 30 05:04:44 PST 2007
Author: mcayland
Date: 2007-11-30 05:04:39 -0800 (Fri, 30 Nov 2007)
New Revision: 2721
Modified:
trunk/lwgeom/lwgparse.c
Log:
Fix the (E)WKB parser so that it performs validation checks in the same way as the WKT parser, e.g. ensure POLYGON rings are closed, LINESTRINGs consist of at least 2 points and that curves have at least 3 points. As discovered when looking simplify() bug submitted by Ivan Mincik.
Modified: trunk/lwgeom/lwgparse.c
===================================================================
--- trunk/lwgeom/lwgparse.c 2007-11-30 02:37:10 UTC (rev 2720)
+++ trunk/lwgeom/lwgparse.c 2007-11-30 13:04:39 UTC (rev 2721)
@@ -151,8 +151,11 @@
int4 read_wkb_int(const char **in);
double read_wkb_double(const char **in, int convert_from_int);
void read_wkb_point(const char **b);
+void read_wkb_polygon(const char **b);
+void read_wkb_linestring(const char **b);
+void read_wkb_curve(const char **b);
+void read_wkb_ordinate_array(const char **b);
void read_collection(const char **b, read_col_func f);
-void read_collection2(const char **b);
void parse_wkb(const char **b);
void alloc_wkb(const char *parser);
SERIALIZED_LWGEOM* parse_it(const char* geometry, allocator allocfunc, report_error errfunc);
@@ -269,6 +272,7 @@
void
popc(void)
{
+
if ( the_geom.stack->uu.nn.num < minpoints){
error("geometry requires more points");
}
@@ -281,7 +285,8 @@
{
error("geometry contains non-closed rings");
}
- }
+ }
+
the_geom.stack = the_geom.stack->uu.nn.stack_next;
}
@@ -946,31 +951,97 @@
}
}
+
+ /* keep track of point */
+ if ( checkclosed ) {
+ if ( ! the_geom.stack->uu.nn.num )
+ first_point = p->uu.points;
+ last_point = p->uu.points;
+ }
+
inc_num();
check_dims(the_geom.ndims);
}
void
-read_collection(const char **b, read_col_func f)
+read_wkb_polygon(const char **b)
{
+ /* Stack the number of ORDINATE_ARRAYs (rings) */
int4 cnt=read_wkb_int(b);
alloc_counter();
+ /* Read through each ORDINATE_ARRAY in turn */
while(cnt--){
if ( ferror_occured ) return;
- f(b);
+
+ /* Things to check for POLYGON ORDINATE_ARRAYs */
+ minpoints=3;
+ checkclosed=1;
+ isodd=-1;
+
+ read_wkb_ordinate_array(b);
}
pop();
}
void
-read_collection2(const char **b)
+read_wkb_linestring(const char **b)
{
- read_collection(b, read_wkb_point);
+
+ /* Things to check for LINESTRING ORDINATE_ARRAYs */
+ minpoints=2;
+ checkclosed=0;
+ isodd=-1;
+
+ read_wkb_ordinate_array(b);
}
+
void
+read_wkb_curve(const char **b)
+{
+
+ /* Things to check for CURVE ORDINATE_ARRAYs */
+ minpoints=3;
+ checkclosed=0;
+ isodd=-1;
+
+ read_wkb_ordinate_array(b);
+}
+
+void
+read_wkb_ordinate_array(const char **b)
+{
+ /* Read through a WKB ordinate array */
+ int4 cnt=read_wkb_int(b);
+ alloc_counter();
+
+ while(cnt--){
+ if ( ferror_occured ) return;
+ read_wkb_point(b);
+ }
+
+ /* Perform a check of the ordinate array */
+ popc();
+}
+
+void
+read_collection(const char **b, read_col_func f)
+{
+ /* Read through a COLLECTION or an EWKB */
+ int4 cnt=read_wkb_int(b);
+ alloc_counter();
+
+ while(cnt--){
+ if ( ferror_occured ) return;
+ f(b);
+ }
+
+ pop();
+}
+
+void
parse_wkb(const char **b)
{
@@ -1043,15 +1114,15 @@
break;
case LINETYPE:
- read_collection(b,read_wkb_point);
+ read_wkb_linestring(b);
break;
case CURVETYPE:
- read_collection(b,read_wkb_point);
+ read_wkb_curve(b);
break;
case POLYGONTYPE:
- read_collection(b,read_collection2);
+ read_wkb_polygon(b);
break;
case COMPOUNDTYPE:
@@ -1078,12 +1149,12 @@
case LINETYPEI:
the_geom.from_lwgi=1;
- read_collection(b,read_wkb_point);
+ read_wkb_linestring(b);
break;
case POLYGONTYPEI:
the_geom.from_lwgi=1;
- read_collection(b,read_collection2);
+ read_wkb_polygon(b);
break;
default:
More information about the postgis-commits
mailing list