PostGIS  3.4.0dev-r@@SVN_REVISION@@
cu_in_wkt.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  * Copyright 2010 Paul Ramsey <pramsey@cleverelephant.ca>
6  *
7  * This is free software; you can redistribute and/or modify it under
8  * the terms of the GNU General Public Licence. See the COPYING file.
9  *
10  **********************************************************************/
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include "CUnit/Basic.h"
16 
17 #include "liblwgeom_internal.h"
18 #include "cu_tester.h"
19 
20 /*
21 ** Globals used by tests
22 */
23 char *s;
24 char *r;
25 
26 /*
27 ** The suite initialization function.
28 ** Create any re-used objects.
29 */
30 static int init_wkt_in_suite(void)
31 {
32  return 0;
33 }
34 
35 /*
36 ** The suite cleanup function.
37 ** Frees any global objects.
38 */
39 static int clean_wkt_in_suite(void)
40 {
41  return 0;
42 }
43 
44 /*
45 * Return a char* that results from taking the input
46 * WKT, creating an LWGEOM, then writing it back out
47 * as an output WKT using the supplied variant.
48 * If there is an error, return that.
49 */
50 static char* cu_wkt_in(char *wkt, uint8_t variant)
51 {
53  int rv = 0;
54  char *s = 0;
55 
56  rv = lwgeom_parse_wkt(&p, wkt, 0);
57  if (p.errcode)
58  {
59  CU_ASSERT_EQUAL(rv, LW_FAILURE);
60  CU_ASSERT(!p.geom);
61  return strdup(p.message);
62  }
63  CU_ASSERT_EQUAL(rv, LW_SUCCESS);
64  s = lwgeom_to_wkt(p.geom, variant, 8, NULL);
66  return s;
67 }
68 
69 #include <ctype.h>
70 static void cu_strtolower(char* str)
71 {
72  size_t i;
73  for (i = 0; i < strlen(str); ++i) {
74  str[i] = tolower(str[i]);
75  }
76 }
77 
78 static void test_wkt_in_point(void)
79 {
80  s = "POINT(1 2) foobar";
81  r = cu_wkt_in(s, WKT_SFSQL);
82  CU_ASSERT_STRING_EQUAL("parse error - invalid geometry", r);
83  lwfree(r);
84 
85  s = "POINT(1e700 0)";
86  r = cu_wkt_in(s, WKT_SFSQL);
87  CU_TEST ( ! strcmp(r, "POINT(inf 0)") || ! strcmp(r, "POINT(1.#INF 0)") || ! strcmp(r, "POINT(Infinity 0)") );
88  lwfree(r);
89 
90  s = "POINT(0 0)";
91  r = cu_wkt_in(s, WKT_SFSQL);
92  CU_ASSERT_STRING_EQUAL(r,s);
93  lwfree(r);
94 
95  s = "POINT EMPTY";
96  r = cu_wkt_in(s, WKT_SFSQL);
97  CU_ASSERT_STRING_EQUAL(r,s);
98  lwfree(r);
99 
100  s = "POINT M EMPTY";
101  r = cu_wkt_in(s, WKT_ISO);
102  CU_ASSERT_STRING_EQUAL(r,s);
103  lwfree(r);
104 
105  s = "point(nan 10)";
106  r = cu_wkt_in(s, WKT_ISO);
107  cu_strtolower(r);
108  CU_ASSERT_STRING_EQUAL(r,s);
109  lwfree(r);
110 
111  // printf("\nIN: %s\nOUT: %s\n",s,r);
112 }
113 
114 static void test_wkt_in_linestring(void)
115 {
116  s = "LINESTRING EMPTY";
117  r = cu_wkt_in(s, WKT_SFSQL);
118  CU_ASSERT_STRING_EQUAL(r,s);
119  lwfree(r);
120 
121  s = "LINESTRING(0 0,1 1)";
122  r = cu_wkt_in(s, WKT_SFSQL);
123  CU_ASSERT_STRING_EQUAL(r,s);
124  lwfree(r);
125 
126  s = "LINESTRING(0 0 0,1 1 1)";
128  CU_ASSERT_STRING_EQUAL(r,s);
129  lwfree(r);
130 
131  s = "LINESTRING M (0 0 0,1 1 1)";
132  r = cu_wkt_in(s, WKT_ISO);
133  CU_ASSERT_STRING_EQUAL(r,s);
134  lwfree(r);
135 
136  s = "LINESTRING ZM (0 0 0 1,1 1 1 1,2 2 2 2,0.141231 4 5 4)";
137  r = cu_wkt_in(s, WKT_ISO);
138  CU_ASSERT_STRING_EQUAL(r,s);
139  lwfree(r);
140 
141  s = "LINESTRINGM(0 0 0,1 1 1)";
143  CU_ASSERT_STRING_EQUAL(r,s);
144  lwfree(r);
145 
146  s = "LINESTRING ZM EMPTY";
147  r = cu_wkt_in(s, WKT_ISO);
148  CU_ASSERT_STRING_EQUAL(r,s);
149  lwfree(r);
150 
151  s = "LINESTRING Z (0 0 0 1, 0 1 0 1)";
153  CU_ASSERT_STRING_EQUAL(r,"can not mix dimensionality in a geometry");
154  //printf("\nIN: %s\nOUT: %s\n",s,r);
155  lwfree(r);
156 
157 }
158 
159 static void test_wkt_in_polygon(void)
160 {
161  s = "POLYGON((0 0,0 1,1 1,0 0))";
162  r = cu_wkt_in(s, WKT_SFSQL);
163  CU_ASSERT_STRING_EQUAL(r,s);
164  lwfree(r);
165 
166  s = "POLYGON Z ((0 0,0 10,10 10,10 0,0 0),(1 1 1,1 2 1,2 2 1,2 1 1,1 1 1))";
167  r = cu_wkt_in(s, WKT_SFSQL);
168  CU_ASSERT_STRING_EQUAL(r,"can not mix dimensionality in a geometry");
169  lwfree(r);
170 
171  s = "POLYGON Z ((0 0,0 10,10 10,10 0,0 0),(1 1,1 2,2 2,2 1,1 1))";
172  r = cu_wkt_in(s, WKT_SFSQL);
173  CU_ASSERT_STRING_EQUAL(r,"can not mix dimensionality in a geometry");
174  //printf("\nIN: %s\nOUT: %s\n",s,r);
175  lwfree(r);
176 }
177 
178 static void test_wkt_in_multipoint(void)
179 {
184  // s = "MULTIPOINT(-1 -2 -3,5.4 6.6 7.77,-5.4 -6.6 -7.77,1000000 1e-06 -1000000,-1.3e-06 -1.4e-05 0)";
185  // r = cu_wkt_in(s, WKT_EXTENDED);
186  // CU_ASSERT_STRING_EQUAL(r,s);
187  // printf("\nIN: %s\nOUT: %s\n",s,r);
188  // lwfree(r);
189 
190  s = "MULTIPOINT(0 0)";
191  r = cu_wkt_in(s, WKT_SFSQL);
192  CU_ASSERT_STRING_EQUAL(r,s);
193  //printf("\nIN: %s\nOUT: %s\n",s,r);
194  lwfree(r);
195 
196  s = "MULTIPOINT(0 0,1 1)";
197  r = cu_wkt_in(s, WKT_SFSQL);
198  CU_ASSERT_STRING_EQUAL(r,s);
199  //printf("\nIN: %s\nOUT: %s\n",s,r);
200  lwfree(r);
201 }
202 
204 {
205  s = "MULTILINESTRING((0 0,1 1),(1 1,2 2),(3 3,3 3,3 3,2 2,2 1))";
206  r = cu_wkt_in(s, WKT_SFSQL);
207  CU_ASSERT_STRING_EQUAL(r,s);
208  //printf("\nIN: %s\nOUT: %s\n",s,r);
209  lwfree(r);
210 
211 }
212 
213 static void test_wkt_in_multipolygon(void)
214 {
215  s = "MULTIPOLYGON(((0 0,0 1,1 1,0 0)))";
216  r = cu_wkt_in(s, WKT_SFSQL);
217  CU_ASSERT_STRING_EQUAL(r,s);
218  //printf("\nIN: %s\nOUT: %s\n",s,r);
219  lwfree(r);
220 
221  s = "MULTIPOLYGON(((0 0,0 10,10 10,0 0),(1 1,1 2,2 2,1 1)),((-10 -10,-10 -5,-5 -5,-10 -10)))";
222  r = cu_wkt_in(s, WKT_SFSQL);
223  CU_ASSERT_STRING_EQUAL(r,s);
224  //printf("\nIN: %s\nOUT: %s\n",s,r);
225  lwfree(r);
226 
227  s = "SRID=4;MULTIPOLYGON(((0 0,0 1,1 1,0 0)))";
229  CU_ASSERT_STRING_EQUAL(r,s);
230  //printf("\nIN: %s\nOUT: %s\n",s,r);
231  lwfree(r);
232 
233 }
234 
235 static void test_wkt_in_collection(void)
236 {
237  s = "SRID=5;GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(1 0,0 0),CIRCULARSTRING(0 0,0 1,1 1,0 1,2 2))";
239  //printf("\nIN: %s\nOUT: %s\n",s,r);
240  CU_ASSERT_STRING_EQUAL(r,s);
241  lwfree(r);
242 
243  s = "GEOMETRYCOLLECTION(POINT(0 0),POINT EMPTY,LINESTRING(1 0,0 0),POLYGON EMPTY,CIRCULARSTRING(0 0,0 1,1 1,0 1,2 2))";
244  r = cu_wkt_in(s, WKT_SFSQL);
245  //printf("\nIN: %s\nOUT: %s\n",s,r);
246  CU_ASSERT_STRING_EQUAL(r,s);
247  lwfree(r);
248 
249  s = "GEOMETRYCOLLECTION Z (POINT Z (0 0 0))";
250  r = cu_wkt_in(s, WKT_ISO);
251  //printf("\nIN: %s\nOUT: %s\n",s,r);
252  CU_ASSERT_STRING_EQUAL(r,s);
253  lwfree(r);
254 
255  s = "GEOMETRYCOLLECTION M (MULTILINESTRING M ((0 0 5,2 0 5),(1 1 5,2 2 5)))";
256  r = cu_wkt_in(s, WKT_ISO);
257  //printf("\nIN: %s\nOUT: %s\n",s,r);
258  CU_ASSERT_STRING_EQUAL(r,s);
259  lwfree(r);
260 
261  /* See http://trac.osgeo.org/postgis/ticket/1455#comment:3 */
262  s = "GEOMETRYCOLLECTION Z (MULTILINESTRING Z ((0 0 5,2 0 5),(1 1 5,2 2 5)))";
263  r = cu_wkt_in(s, WKT_ISO);
264  //printf("\nIN: %s\nOUT: %s\n",s,r);
265  CU_ASSERT_STRING_EQUAL(r,s);
266  lwfree(r);
267 }
268 
269 static void test_wkt_in_circularstring(void)
270 {
271  s = "CIRCULARSTRING(0 0,0 1,1 1,0 1,2 2)";
272  r = cu_wkt_in(s, WKT_SFSQL);
273  //printf("\nIN: %s\nOUT: %s\n",s,r);
274  CU_ASSERT_STRING_EQUAL(r,s);
275  lwfree(r);
276 }
277 
278 static void test_wkt_in_compoundcurve(void)
279 {
280  s = "SRID=4326;COMPOUNDCURVEM(CIRCULARSTRINGM(0 0 2,1 1 2,1 0 2),(1 0 2,0 1 2))";
282  CU_ASSERT_STRING_EQUAL(r,s);
283  //printf("\nIN: %s\nOUT: %s\n",s,r);
284  lwfree(r);
285 
286  s = "COMPOUNDCURVE Z (CIRCULARSTRING Z (0 0 0,0 1 0,1 1 0,0 0 0,2 2 0),(2 2 0,0 0 1,1 1 1,2 2 1))";
287  r = cu_wkt_in(s, WKT_ISO);
288  CU_ASSERT_STRING_EQUAL(r,s);
289  //printf("\nIN: %s\nOUT: %s\n",s,r);
290  lwfree(r);
291 }
292 
293 static void test_wkt_in_curvpolygon(void)
294 {
295  s = "CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,0 1,1 1,2 2,0 0),(0 0,1 1,2 2)),CIRCULARSTRING(0 0,0 1,1 1,0 0,2 2),(0 0,1 1,2 1))";
296  r = cu_wkt_in(s, WKT_ISO);
297  CU_ASSERT_STRING_EQUAL(r,s);
298  //printf("\nIN: %s\nOUT: %s\n",s,r);
299  lwfree(r);
300 }
301 
302 static void test_wkt_in_multicurve(void)
303 {
304  s = "SRID=4326;MULTICURVE(COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1)))";
306  CU_ASSERT_STRING_EQUAL(r,s);
307  //printf("\nIN: %s\nOUT: %s\n",s,r);
308  lwfree(r);
309 }
310 
311 static void test_wkt_in_multisurface(void)
312 {
313  s = "SRID=4326;MULTICURVE(COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1)))";
315  CU_ASSERT_STRING_EQUAL(r,s);
316  //printf("\nIN: %s\nOUT: %s\n",s,r);
317  lwfree(r);
318 }
319 
320 static void test_wkt_in_tin(void)
321 {
322  s = "TIN(((0 1 2,3 4 5,6 7 8,0 1 2)),((0 1 2,3 4 5,6 7 8,9 10 11,0 1 2)))";
324  CU_ASSERT_STRING_EQUAL(r,"triangle must have exactly 4 points");
325  //printf("\nIN: %s\nOUT: %s\n",s,r);
326  lwfree(r);
327 }
328 
330 {
331  s = "POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))";
333  CU_ASSERT_STRING_EQUAL(r,s);
334  //printf("\nIN: %s\nOUT: %s\n",s,r);
335  lwfree(r);
336 
337  s = "POLYHEDRALSURFACE Z (((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))";
338  r = cu_wkt_in(s, WKT_ISO);
339  CU_ASSERT_STRING_EQUAL(r,s);
340  //printf("\nIN: %s\nOUT: %s\n",s,r);
341  lwfree(r);
342 
343  s = "POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7,0 1 2)))";
344  r = cu_wkt_in(s, WKT_ISO);
345  CU_ASSERT_STRING_EQUAL(r,"can not mix dimensionality in a geometry");
346  //printf("\nIN: %s\nOUT: %s\n",s,r);
347  lwfree(r);
348 
349 }
350 
351 static void test_wkt_in_errlocation(void)
352 {
354  int rv = 0;
355  char *wkt = 0;
356 
357  wkt = "LINESTRING((0 0 0,1 1)";
359  rv = lwgeom_parse_wkt(&p, wkt, LW_PARSER_CHECK_ALL);
360  CU_ASSERT_EQUAL( rv, LW_FAILURE );
361  CU_ASSERT((12 - p.errlocation) < 1.5);
362 
363 // printf("errlocation %d\n", p.errlocation);
364 // printf("message %s\n", p.message);
365 
367 
368 }
369 
370 static void test_wkt_double(void)
371 {
373  int rv = 0;
374  char *wkt = 0;
375 
376  wkt = "LINESTRING(1.1.1, 2.2.2)";
378  rv = lwgeom_parse_wkt(&p, wkt, LW_PARSER_CHECK_ALL);
379  CU_ASSERT( LW_FAILURE == rv );
380  CU_ASSERT( p.errcode );
381  CU_ASSERT( ! p.geom );
383 
384  wkt = "LINESTRING(1.1 .1, 2.2 .2)";
386  rv = lwgeom_parse_wkt(&p, wkt, LW_PARSER_CHECK_ALL);
387  CU_ASSERT_EQUAL( rv, LW_SUCCESS );
389 
390  wkt = "LINESTRING( 1.1 .1 , 2.2 .2 )";
392  rv = lwgeom_parse_wkt(&p, wkt, LW_PARSER_CHECK_ALL);
393  CU_ASSERT_EQUAL( rv, LW_SUCCESS );
395 
396  wkt = "LINESTRING(\n1.1\n.1,\n2.2\n.2\n)";
398  rv = lwgeom_parse_wkt(&p, wkt, LW_PARSER_CHECK_ALL);
399  CU_ASSERT_EQUAL( rv, LW_SUCCESS );
401 
402  wkt = "LINESTRING(1.1\t.1\t,\t2.2\t.2\t)";
404  rv = lwgeom_parse_wkt(&p, wkt, LW_PARSER_CHECK_ALL);
405  CU_ASSERT_EQUAL( rv, LW_SUCCESS );
407 }
408 
409 static void test_wkt_leak(void)
410 {
411  /* OSS-FUZZ: https://trac.osgeo.org/postgis/ticket/4537 */
412  char *wkt = "TINEMPTY,";
413  char *err = cu_wkt_in(wkt, WKT_EXTENDED);
414  CU_ASSERT_STRING_EQUAL(err, "parse error - invalid geometry");
415  lwfree(err);
416 
417  /* OSS-FUZZ: https://trac.osgeo.org/postgis/ticket/4545 */
418  wkt = "GEOMeTRYCOLLECTION(POLYHEDRALSURFACEEMPTY ";
419  err = cu_wkt_in(wkt, WKT_EXTENDED);
420  CU_ASSERT_STRING_EQUAL(err, "parse error - invalid geometry");
421  lwfree(err);
422 }
423 
424 /*
425 ** Used by test harness to register the tests in this file.
426 */
427 void wkt_in_suite_setup(void);
429 {
430  CU_pSuite suite = CU_add_suite("wkt_input", init_wkt_in_suite, clean_wkt_in_suite);
447  PG_ADD_TEST(suite, test_wkt_leak);
448 }
static uint8_t variant
Definition: cu_in_twkb.c:26
static void test_wkt_in_tin(void)
Definition: cu_in_wkt.c:320
static void test_wkt_leak(void)
Definition: cu_in_wkt.c:409
static void test_wkt_in_linestring(void)
Definition: cu_in_wkt.c:114
static void test_wkt_in_point(void)
Definition: cu_in_wkt.c:78
static void test_wkt_in_multipoint(void)
Definition: cu_in_wkt.c:178
static void cu_strtolower(char *str)
Definition: cu_in_wkt.c:70
static int clean_wkt_in_suite(void)
Definition: cu_in_wkt.c:39
static void test_wkt_in_multisurface(void)
Definition: cu_in_wkt.c:311
static void test_wkt_in_polygon(void)
Definition: cu_in_wkt.c:159
static void test_wkt_in_multipolygon(void)
Definition: cu_in_wkt.c:213
static void test_wkt_in_collection(void)
Definition: cu_in_wkt.c:235
static void test_wkt_in_curvpolygon(void)
Definition: cu_in_wkt.c:293
static void test_wkt_double(void)
Definition: cu_in_wkt.c:370
static void test_wkt_in_multicurve(void)
Definition: cu_in_wkt.c:302
static void test_wkt_in_errlocation(void)
Definition: cu_in_wkt.c:351
static void test_wkt_in_polyhedralsurface(void)
Definition: cu_in_wkt.c:329
char * s
Definition: cu_in_wkt.c:23
char * r
Definition: cu_in_wkt.c:24
static void test_wkt_in_multilinestring(void)
Definition: cu_in_wkt.c:203
void wkt_in_suite_setup(void)
Definition: cu_in_wkt.c:428
static void test_wkt_in_circularstring(void)
Definition: cu_in_wkt.c:269
static char * cu_wkt_in(char *wkt, uint8_t variant)
Definition: cu_in_wkt.c:50
static void test_wkt_in_compoundcurve(void)
Definition: cu_in_wkt.c:278
static int init_wkt_in_suite(void)
Definition: cu_in_wkt.c:30
#define PG_ADD_TEST(suite, testfunc)
#define LW_PARSER_CHECK_ALL
Definition: liblwgeom.h:2115
#define WKT_SFSQL
Definition: liblwgeom.h:2185
#define LW_FAILURE
Definition: liblwgeom.h:96
#define WKT_EXTENDED
Definition: liblwgeom.h:2186
#define LW_SUCCESS
Definition: liblwgeom.h:97
void lwgeom_parser_result_init(LWGEOM_PARSER_RESULT *parser_result)
Definition: lwin_wkt.c:880
int lwgeom_parse_wkt(LWGEOM_PARSER_RESULT *parser_result, char *wktstr, int parse_flags)
Parse a WKT geometry string into an LWGEOM structure.
void lwfree(void *mem)
Definition: lwutil.c:242
#define WKT_ISO
Definition: liblwgeom.h:2184
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Definition: lwout_wkt.c:708
void lwgeom_parser_result_free(LWGEOM_PARSER_RESULT *parser_result)
Definition: lwin_wkt.c:886
#define str(s)
Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM.
Definition: liblwgeom.h:2122