PostGIS  3.4.0dev-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  if (g) {
54  char *outhex = lwgeom_to_hexwkb_buffer(g, 0);
55  printf("cu_wkb_malformed_in input: %s\n", hex);
56  printf("cu_wkb_malformed_in output: %s\n", outhex);
57  lwfree(outhex);
58  }
59  CU_ASSERT( g == NULL );
60 }
61 
62 static void cu_wkb_in(char *wkt)
63 {
65  LWGEOM *g_a, *g_b;
66  lwvarlena_t *wkb_a, *wkb_b;
67  /* int i; char *hex; */
68 
69  if ( hex_a ) free(hex_a);
70  if ( hex_b ) free(hex_b);
71 
72  /* Turn WKT into geom */
74  if ( pr.errcode )
75  {
76  printf("ERROR: %s\n", pr.message);
77  printf("POSITION: %d\n", pr.errlocation);
78  exit(0);
79  }
80 
81  /* Get the geom */
82  g_a = pr.geom;
83 
84  /* Turn geom into WKB */
86 
87  /* Turn WKB back into geom */
88  g_b = lwgeom_from_wkb((uint8_t *)wkb_a->data, LWSIZE_GET(wkb_a->size) - LWVARHDRSZ, LW_PARSER_CHECK_NONE);
89 
90  /* Turn geom to WKB again */
92 
93  /* Turn geoms into WKB for comparisons */
94  hex_a = hexbytes_from_bytes((uint8_t *)wkb_a->data, LWSIZE_GET(wkb_a->size) - LWVARHDRSZ);
95  hex_b = hexbytes_from_bytes((uint8_t *)wkb_b->data, LWSIZE_GET(wkb_b->size) - LWVARHDRSZ);
96 
97  /* Clean up */
98  lwfree(wkb_a);
99  lwfree(wkb_b);
101  lwgeom_free(g_b);
102 }
103 
104 static void test_wkb_in_point(void)
105 {
106  cu_wkb_in("POINT(0 0 0 0)");
107 // printf("old: %s\nnew: %s\n",hex_a, hex_b);
108  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
109 
110  cu_wkb_in("SRID=4;POINTM(1 1 1)");
111  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
112 
113  cu_wkb_in("POINT EMPTY");
114  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
115 
116  cu_wkb_in("SRID=4326;POINT EMPTY");
117  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
118 
119  cu_wkb_in("POINT Z EMPTY");
120  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
121 
122  cu_wkb_in("POINT M EMPTY");
123  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
124 
125  cu_wkb_in("POINT ZM EMPTY");
126  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
127 
128 }
129 
130 static void test_wkb_in_linestring(void)
131 {
132  cu_wkb_in("LINESTRING(0 0,1 1)");
133  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
134 
135  cu_wkb_in("LINESTRING(0 0 1,1 1 2,2 2 3)");
136  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
137 }
138 
139 static void test_wkb_in_polygon(void)
140 {
141  cu_wkb_in("SRID=4;POLYGON((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0))");
142  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
143 
144  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))");
145  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
146 
147  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))");
148  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
149 
150  cu_wkb_in("POLYGON EMPTY");
151  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
152 }
153 
154 static void test_wkb_in_multipoint(void)
155 {
156  cu_wkb_in("SRID=4;MULTIPOINT(0 0 0,0 1 0,1 1 0,1 0 0,0 0 1)");
157  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
158 
159  cu_wkb_in("MULTIPOINT(0 0 0, 0.26794919243112270647255365849413 1 3)");
160  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
161 }
162 
163 static void test_wkb_in_multilinestring(void) {}
164 
165 static void test_wkb_in_multipolygon(void)
166 {
167  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)))");
168  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
169  //printf("old: %s\nnew: %s\n",hex_a, hex_b);
170 }
171 
172 static void test_wkb_in_collection(void)
173 {
174  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))");
175  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
176 
177  cu_wkb_in("GEOMETRYCOLLECTION EMPTY");
178  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
179 
180  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))");
181  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
182 
183 }
184 
185 static void test_wkb_in_circularstring(void)
186 {
187  cu_wkb_in("CIRCULARSTRING(0 -2,-2 0,0 2,2 0,0 -2)");
188  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
189 
190  cu_wkb_in("CIRCULARSTRING(-5 0 0 4, 0 5 1 3, 5 0 2 2, 10 -5 3 1, 15 0 4 0)");
191  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
192 
193  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)");
194  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
195 }
196 
197 static void test_wkb_in_compoundcurve(void)
198 {
199  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))");
200  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
201 }
202 
203 static void test_wkb_in_curvpolygon(void)
204 {
205  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))");
206  CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
207 }
208 
209 static void test_wkb_in_multicurve(void) {}
210 
211 static void test_wkb_in_multisurface(void) {}
212 
213 static void test_wkb_in_malformed(void)
214 {
215  /* OSSFUXX */
216  cu_wkb_malformed_in("0000000008200000002020202020202020");
217 
218  /* See http://trac.osgeo.org/postgis/ticket/1445 */
219  cu_wkb_malformed_in("01060000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F");
220  cu_wkb_malformed_in("01050000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F");
221  cu_wkb_malformed_in("01040000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F");
222  cu_wkb_malformed_in("01030000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F");
223 
224  /* See http://trac.osgeo.org/postgis/ticket/168 */
225  cu_wkb_malformed_in("01060000C00100000001030000C00100000003000000E3D9107E234F5041A3DB66BC97A30F4122ACEF440DAF9440FFFFFFFFFFFFEFFFE3D9107E234F5041A3DB66BC97A30F4122ACEF440DAF9440FFFFFFFFFFFFEFFFE3D9107E234F5041A3DB66BC97A30F4122ACEF440DAF9440FFFFFFFFFFFFEFFF");
226 
227  /* Oracle "WKB" */
228  cu_wkb_malformed_in("00000f424200000007000000020000000240b92ab16861e92940d6c3e0f5be5d9e40ba1a50623d0bfa40d6ef6f2b020c4a000f42410000000340ba1a50623d0bfa40d6ef6f2b020c4a40ba1ebb14cce52440d6f048fed27bec40ba22f374aba38740d6f1323d6c7219000000020000000240ba22f374aba38740d6f1323d6c721940ba5725e34330d740d6fd1dc28f5c29000f42410000002740ba5725e34330d740d6fd1dc28f5c2940ba5b26dbc90e1940d6fe04a63c03cf40ba5f1ced80a17b40d6feee8726d04e40ba64fab16b244a40d700545391e30840ba6aba5e24788540d701c1db1e9f2740ba705be892932540d703384e2d19da40ba75d91676640a40d704b74bc6a7f040ba7b3120b0397b40d7063fe6e24e3d40ba805df3a57eaa40d707d1a9fbe76d40ba80dc43d054f140d707f92b656dd940ba815a1c9b413a40d70820c497742540ba86048c041b5440d7098df370651840ba8a8666559f6f40d70b03332f017540ba929a863f35bf40d70ddd2c513fcd40ba9a0c08205ff240d710d24dd2f1aa40ba9e1c9f51a16040d7129a3226dd1140baa1f53f6c269a40d71469cabc515540baa59752e7123040d7163fbd0bd2f440baa905e34330d740d7181bd70a3d7140baac425b1082b440d719fcc009c75240baaf50623d0bfa40d71be27ef9db2340bab157404ac14d40d71d3785fe998c40bab34a3d5fdcdf40d71e8e666234a840bab66a43c834e340d721170a535ffd40bab94e977c88e840d723a4188f42ff40babb5fc577e64340d7259a5666c23440babd53f7be121f40d727926e978d5040babf2cd708467540d7298a75344b5340bac0ef1a8ef77f40d72b83c6a7ef9e40bac29c6faca73a40d72d7c9a4a17e740bac4399988d2a240d72f76459d990340bac5c8b018b9dc40d7316efed2743140bac74e146a1a5040d733683126e97940bac8cbda53946e40d735601daf2bd440baca4666559f6f40d737583126e97940bacab55b9b068340d737ec8d0113b440bacb249b951c5c40d73880e55c0fcb40bacdc490bfe33240d73ac7bdc376b240bad210623d0bfa40d73ce46a7ac81d000000020000000240bad210623d0bfa40d73ce46a7ac81d40badf86a7ded6bb40d742325e353f7d000f42410000000540badf86a7ded6bb40d742325e353f7d40bae9151fb3633540d74738abbc084240bae8f89363f57340d74cc8f5be5d9e40bae7c450ce91b940d74ec51a03a44340bae7d374aba38740d750c70a3d70a4000000020000000340bae7d374aba38740d750c70a3d70a440bafb1c28e4fb9840d75bedb228dc9840bb24d3b634dad340d76c4126e54717");
229 
230 }
231 
232 static void
234 {
235  /* OSS-FUZZ https://trac.osgeo.org/postgis/ticket/4534 */
236  uint8_t wkb[36] = {000, 000, 000, 000, 015, 000, 000, 000, 003, 000, 200, 000, 000, 010, 000, 000, 000, 000,
237  000, 000, 000, 000, 010, 000, 000, 000, 000, 000, 000, 000, 000, 010, 000, 000, 000, 000};
239  lwgeom_free(g);
240 
241  /* OSS-FUZZ https://trac.osgeo.org/postgis/ticket/4536 */
242  uint8_t wkb2[319] = {
243  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001,
244  001, 001, 001, 001, 001, 012, 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, 001, 001, 001, 051, 001, 001,
246  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001,
247  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 000, 115, 001, 001, 001, 001,
248  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 000, 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, 001,
250  001, 001, 001, 001, 001, 001, 000, 000, 000, 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, 001, 002,
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, 001, 001, 001, 207, 001,
254  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001,
255  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 000, 000, 000, 000, 000,
256  000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 001,
257  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001,
258  001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001};
259  g = lwgeom_from_wkb(wkb2, 319, LW_PARSER_CHECK_NONE);
260  lwgeom_free(g);
261 
262  /* OSS-FUZZ: https://trac.osgeo.org/postgis/ticket/4535 */
263  uint8_t wkb3[9] = {0x01, 0x03, 0x00, 0x00, 0x10, 0x8d, 0x55, 0xf3, 0xff};
265  lwgeom_free(g);
266 
267  /* OSS-FUZZ: https://trac.osgeo.org/postgis/ticket/4544 */
268  uint8_t wkb4[22] = {0x01, 0x0f, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
269  0x00, 0x00, 0x11, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00};
270  g = lwgeom_from_wkb(wkb4, 22, LW_PARSER_CHECK_NONE);
271  lwgeom_free(g);
272 
273  /* OSS-FUZZ: https://trac.osgeo.org/postgis/ticket/4621 */
274  uint32_t big_size = 20000000;
275  uint8_t *wkb5 = lwalloc(big_size);
276  memset(wkb5, 0x01, big_size);
277  g = lwgeom_from_wkb(wkb5, big_size, LW_PARSER_CHECK_NONE);
278  lwgeom_free(g);
279  lwfree(wkb5);
280 }
281 
282 /*
283 ** Used by test harness to register the tests in this file.
284 */
285 void wkb_in_suite_setup(void);
287 {
288  CU_pSuite suite = CU_add_suite("wkb_input", init_wkb_in_suite, clean_wkb_in_suite);
302  PG_ADD_TEST(suite, test_wkb_fuzz);
303 }
static void test_wkb_in_multicurve(void)
Definition: cu_in_wkb.c:209
static void test_wkb_in_collection(void)
Definition: cu_in_wkb.c:172
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:130
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:104
static void test_wkb_in_compoundcurve(void)
Definition: cu_in_wkb.c:197
static void test_wkb_fuzz(void)
Definition: cu_in_wkb.c:233
static void test_wkb_in_malformed(void)
Definition: cu_in_wkb.c:213
void wkb_in_suite_setup(void)
Definition: cu_in_wkb.c:286
static void test_wkb_in_polygon(void)
Definition: cu_in_wkb.c:139
static void test_wkb_in_multisurface(void)
Definition: cu_in_wkb.c:211
static void test_wkb_in_multipoint(void)
Definition: cu_in_wkb.c:154
static void test_wkb_in_multipolygon(void)
Definition: cu_in_wkb.c:165
static void test_wkb_in_circularstring(void)
Definition: cu_in_wkb.c:185
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:203
static void test_wkb_in_multilinestring(void)
Definition: cu_in_wkb.c:163
#define PG_ADD_TEST(suite, testfunc)
#define LW_PARSER_CHECK_ALL
Definition: liblwgeom.h:2115
LWGEOM * lwgeom_from_hexwkb(const char *hexwkb, const char check)
Definition: lwin_wkb.c:858
#define LWVARHDRSZ
Definition: liblwgeom.h:311
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1155
char * hexbytes_from_bytes(const uint8_t *bytes, size_t size)
Definition: lwout_wkb.c:40
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:2114
#define LWSIZE_GET(varsize)
Macro for reading the size from the GSERIALIZED size attribute.
Definition: liblwgeom.h:324
int lwgeom_parse_wkt(LWGEOM_PARSER_RESULT *parser_result, char *wktstr, int parse_flags)
Parse a WKT geometry string into an LWGEOM structure.
char * lwgeom_to_hexwkb_buffer(const LWGEOM *geom, uint8_t variant)
Definition: lwout_wkb.c:845
void lwfree(void *mem)
Definition: lwutil.c:242
#define WKB_EXTENDED
Definition: liblwgeom.h:2177
#define WKB_NDR
Definition: liblwgeom.h:2178
void * lwalloc(size_t size)
Definition: lwutil.c:227
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:834
lwvarlena_t * lwgeom_to_wkb_varlena(const LWGEOM *geom, uint8_t variant)
Definition: lwout_wkb.c:851
void lwgeom_parser_result_free(LWGEOM_PARSER_RESULT *parser_result)
Definition: lwin_wkt.c:886
void free(void *)
uint32_t size
Definition: liblwgeom.h:307
char data[]
Definition: liblwgeom.h:308
Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM.
Definition: liblwgeom.h:2122