PostGIS  2.5.7dev-r@@SVN_REVISION@@
cu_in_wkb.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 ** Global variable to hold WKB strings
22 */
23 static char *hex_a;
24 static char *hex_b;
25 
26 /*
27 ** The suite initialization function.
28 ** Create any re-used objects.
29 */
30 static int init_wkb_in_suite(void)
31 {
32  hex_a = NULL;
33  hex_b = NULL;
34  return 0;
35 }
36 
37 /*
38 ** The suite cleanup function.
39 ** Frees any global objects.
40 */
41 static int clean_wkb_in_suite(void)
42 {
43  if (hex_a) free(hex_a);
44  if (hex_b) free(hex_b);
45  hex_a = NULL;
46  hex_b = NULL;
47  return 0;
48 }
49 
50 static void cu_wkb_malformed_in(char *hex)
51 {
53  int rv = 0;
54 
55  rv = lwgeom_parse_wkt(&p, hex, 0);
56  CU_ASSERT( LW_FAILURE == rv );
57  CU_ASSERT( p.errcode );
58  CU_ASSERT( ! p.geom );
60 }
61 
62 static void cu_wkb_in(char *wkt)
63 {
65  LWGEOM *g_a, *g_b;
66  uint8_t *wkb_a, *wkb_b;
67  size_t wkb_size_a, wkb_size_b;
68  /* int i; char *hex; */
69 
70  if ( hex_a ) free(hex_a);
71  if ( hex_b ) free(hex_b);
72 
73  /* Turn WKT into geom */
75  if ( pr.errcode )
76  {
77  printf("ERROR: %s\n", pr.message);
78  printf("POSITION: %d\n", pr.errlocation);
79  exit(0);
80  }
81 
82  /* Get the geom */
83  g_a = pr.geom;
84 
85  /* Turn geom into WKB */
86  wkb_a = lwgeom_to_wkb(g_a, WKB_NDR | WKB_EXTENDED, &wkb_size_a);
87 
88  /* Turn WKB back into geom */
89  g_b = lwgeom_from_wkb(wkb_a, wkb_size_a, LW_PARSER_CHECK_NONE);
90 
91  /* Turn geom to WKB again */
92  wkb_b = lwgeom_to_wkb(g_b, WKB_NDR | WKB_EXTENDED, &wkb_size_b);
93 
94  /* Turn geoms into WKB for comparisons */
95  hex_a = hexbytes_from_bytes(wkb_a, wkb_size_a);
96  hex_b = hexbytes_from_bytes(wkb_b, wkb_size_b);
97 
98  /* Clean up */
99  lwfree(wkb_a);
100  lwfree(wkb_b);
102  lwgeom_free(g_b);
103 }
104 
105 static void test_wkb_in_point(void)
106 {
107  cu_wkb_in("POINT(0 0 0 0)");
108 // printf("old: %s\nnew: %s\n",hex_a, hex_b);
109  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
110 
111  cu_wkb_in("SRID=4;POINTM(1 1 1)");
112  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
113 
114  cu_wkb_in("POINT EMPTY");
115  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
116 
117  cu_wkb_in("SRID=4326;POINT EMPTY");
118  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
119 
120  cu_wkb_in("POINT Z EMPTY");
121  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
122 
123  cu_wkb_in("POINT M EMPTY");
124  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
125 
126  cu_wkb_in("POINT ZM EMPTY");
127  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
128 
129 }
130 
131 static void test_wkb_in_linestring(void)
132 {
133  cu_wkb_in("LINESTRING(0 0,1 1)");
134  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
135 
136  cu_wkb_in("LINESTRING(0 0 1,1 1 2,2 2 3)");
137  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
138 }
139 
140 static void test_wkb_in_polygon(void)
141 {
142  cu_wkb_in("SRID=4;POLYGON((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0))");
143  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
144 
145  cu_wkb_in("SRID=14;POLYGON((0 0 0 1,0 1 0 2,1 1 0 3,1 0 0 4,0 0 0 5))");
146  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
147 
148  cu_wkb_in("SRID=4;POLYGON((0 0 0 1,0 1 0 2,1 1 0 3,1 0 0 4,0 0 0 5))");
149  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
150 
151  cu_wkb_in("POLYGON EMPTY");
152  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
153 }
154 
155 static void test_wkb_in_multipoint(void)
156 {
157  cu_wkb_in("SRID=4;MULTIPOINT(0 0 0,0 1 0,1 1 0,1 0 0,0 0 1)");
158  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
159 
160  cu_wkb_in("MULTIPOINT(0 0 0, 0.26794919243112270647255365849413 1 3)");
161  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
162 }
163 
164 static void test_wkb_in_multilinestring(void) {}
165 
166 static void test_wkb_in_multipolygon(void)
167 {
168  cu_wkb_in("SRID=14;MULTIPOLYGON(((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((-1 -1 0,-1 2 0,2 2 0,2 -1 0,-1 -1 0),(0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)))");
169  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
170  //printf("old: %s\nnew: %s\n",hex_a, hex_b);
171 }
172 
173 static void test_wkb_in_collection(void)
174 {
175  cu_wkb_in("SRID=14;GEOMETRYCOLLECTION(POLYGON((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),POINT(1 1 1))");
176  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
177 
178  cu_wkb_in("GEOMETRYCOLLECTION EMPTY");
179  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
180 
181  cu_wkb_in("SRID=14;GEOMETRYCOLLECTION(MULTIPOLYGON(((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0))),POLYGON((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),POINT(1 1 1),LINESTRING(0 0 0, 1 1 1))");
182  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
183 
184 }
185 
186 static void test_wkb_in_circularstring(void)
187 {
188  cu_wkb_in("CIRCULARSTRING(0 -2,-2 0,0 2,2 0,0 -2)");
189  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
190 
191  cu_wkb_in("CIRCULARSTRING(-5 0 0 4, 0 5 1 3, 5 0 2 2, 10 -5 3 1, 15 0 4 0)");
192  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
193 
194  cu_wkb_in("SRID=43;CIRCULARSTRING(-5 0 0 4, 0 5 1 3, 5 0 2 2, 10 -5 3 1, 15 0 4 0)");
195  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
196 }
197 
198 static void test_wkb_in_compoundcurve(void)
199 {
200  cu_wkb_in("COMPOUNDCURVE(CIRCULARSTRING(0 0 0, 0.26794919243112270647255365849413 1 3, 0.5857864376269049511983112757903 1.4142135623730950488016887242097 1),(0.5857864376269049511983112757903 1.4142135623730950488016887242097 1,2 0 0,0 0 0))");
201  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
202 }
203 
204 static void test_wkb_in_curvpolygon(void)
205 {
206  cu_wkb_in("CURVEPOLYGON(CIRCULARSTRING(-2 0 0 0,-1 -1 1 2,0 0 2 4,1 -1 3 6,2 0 4 8,0 2 2 4,-2 0 0 0),(-1 0 1 2,0 0.5 2 4,1 0 3 6,0 1 3 4,-1 0 1 2))");
207  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
208 }
209 
210 static void test_wkb_in_multicurve(void) {}
211 
212 static void test_wkb_in_multisurface(void) {}
213 
214 static void test_wkb_in_malformed(void)
215 {
216 
217  /* OSSFUXX */
218  cu_wkb_malformed_in("0000000008200000002020202020202020");
219 
220  /* See http://trac.osgeo.org/postgis/ticket/1445 */
221  cu_wkb_malformed_in("01060000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F");
222  cu_wkb_malformed_in("01050000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F");
223  cu_wkb_malformed_in("01040000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F");
224  cu_wkb_malformed_in("01030000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F");
225 
226  /* See http://trac.osgeo.org/postgis/ticket/168 */
227  cu_wkb_malformed_in("01060000C00100000001030000C00100000003000000E3D9107E234F5041A3DB66BC97A30F4122ACEF440DAF9440FFFFFFFFFFFFEFFFE3D9107E234F5041A3DB66BC97A30F4122ACEF440DAF9440FFFFFFFFFFFFEFFFE3D9107E234F5041A3DB66BC97A30F4122ACEF440DAF9440FFFFFFFFFFFFEFFF");
228 }
229 
230 static void
232 {
233  /* OSS-FUZZ https://trac.osgeo.org/postgis/ticket/4534 */
234  uint8_t wkb[36] = {000, 000, 000, 000, 015, 000, 000, 000, 003, 000, 200, 000, 000, 010, 000, 000, 000, 000,
235  000, 000, 000, 000, 010, 000, 000, 000, 000, 000, 000, 000, 000, 010, 000, 000, 000, 000};
237  lwgeom_free(g);
238 
239  /* OSS-FUZZ https://trac.osgeo.org/postgis/ticket/4536 */
240  uint8_t wkb2[319] = {
241  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001,
242  001, 001, 001, 001, 001, 012, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001,
243  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 051, 001, 001,
244  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001,
245  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 000, 115, 001, 001, 001, 001,
246  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 000, 001, 001, 001, 001, 001, 001, 001,
247  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001,
248  001, 001, 001, 001, 001, 001, 000, 000, 000, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001,
249  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 002,
250  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001,
251  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 207, 001,
252  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001,
253  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 000, 000, 000, 000, 000,
254  000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 001,
255  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001,
256  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001};
257  g = lwgeom_from_wkb(wkb2, 319, LW_PARSER_CHECK_NONE);
258  lwgeom_free(g);
259 
260  /* OSS-FUZZ: https://trac.osgeo.org/postgis/ticket/4621 */
261  uint32_t big_size = 20000000;
262  uint8_t *wkb5 = lwalloc(big_size);
263  memset(wkb5, 0x01, big_size);
264  g = lwgeom_from_wkb(wkb5, big_size, LW_PARSER_CHECK_NONE);
265  lwgeom_free(g);
266  lwfree(wkb5);
267 }
268 
269 /*
270 ** Used by test harness to register the tests in this file.
271 */
272 void wkb_in_suite_setup(void);
274 {
275  CU_pSuite suite = CU_add_suite("wkb_input", init_wkb_in_suite, clean_wkb_in_suite);
289  PG_ADD_TEST(suite, test_wkb_leak);
290 }
static void test_wkb_in_multicurve(void)
Definition: cu_in_wkb.c:210
static void test_wkb_in_collection(void)
Definition: cu_in_wkb.c:173
static void cu_wkb_malformed_in(char *hex)
Definition: cu_in_wkb.c:50
static char * hex_a
Definition: cu_in_wkb.c:23
static int init_wkb_in_suite(void)
Definition: cu_in_wkb.c:30
static void test_wkb_in_linestring(void)
Definition: cu_in_wkb.c:131
static void cu_wkb_in(char *wkt)
Definition: cu_in_wkb.c:62
static void test_wkb_in_point(void)
Definition: cu_in_wkb.c:105
static void test_wkb_in_compoundcurve(void)
Definition: cu_in_wkb.c:198
static void test_wkb_in_malformed(void)
Definition: cu_in_wkb.c:214
void wkb_in_suite_setup(void)
Definition: cu_in_wkb.c:273
static void test_wkb_leak(void)
Definition: cu_in_wkb.c:231
static void test_wkb_in_polygon(void)
Definition: cu_in_wkb.c:140
static void test_wkb_in_multisurface(void)
Definition: cu_in_wkb.c:212
static void test_wkb_in_multipoint(void)
Definition: cu_in_wkb.c:155
static void test_wkb_in_multipolygon(void)
Definition: cu_in_wkb.c:166
static void test_wkb_in_circularstring(void)
Definition: cu_in_wkb.c:186
static int clean_wkb_in_suite(void)
Definition: cu_in_wkb.c:41
static char * hex_b
Definition: cu_in_wkb.c:24
static void test_wkb_in_curvpolygon(void)
Definition: cu_in_wkb.c:204
static void test_wkb_in_multilinestring(void)
Definition: cu_in_wkb.c:164
#define PG_ADD_TEST(suite, testfunc)
#define LW_FAILURE
Definition: liblwgeom.h:79
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1144
char * hexbytes_from_bytes(const uint8_t *bytes, size_t size)
Definition: lwout_wkb.c:39
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:2005
int lwgeom_parse_wkt(LWGEOM_PARSER_RESULT *parser_result, char *wktstr, int parse_flags)
Parse a WKT geometry string into an LWGEOM structure.
uint8_t * lwgeom_to_wkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
Convert LWGEOM to a char* in WKB format.
Definition: lwout_wkb.c:764
void lwfree(void *mem)
Definition: lwutil.c:244
#define WKB_EXTENDED
Definition: liblwgeom.h:2068
#define WKB_NDR
Definition: liblwgeom.h:2069
void * lwalloc(size_t size)
Definition: lwutil.c:229
LWGEOM * lwgeom_from_wkb(const uint8_t *wkb, const size_t wkb_size, const char check)
WKB inputs must have a declared size, to prevent malformed WKB from reading off the end of the memory...
Definition: lwin_wkb.c:789
void lwgeom_parser_result_free(LWGEOM_PARSER_RESULT *parser_result)
Definition: lwin_wkt.c:885
void free(void *)
Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM.
Definition: liblwgeom.h:2013
unsigned int uint32_t
Definition: uthash.h:78
unsigned char uint8_t
Definition: uthash.h:79