geoip2_c 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/ext/geoip2/libmaxminddb/.gitignore +35 -0
  3. data/ext/geoip2/libmaxminddb/.gitmodules +9 -0
  4. data/ext/geoip2/libmaxminddb/.perltidyrc +11 -0
  5. data/ext/geoip2/libmaxminddb/.travis.yml +48 -0
  6. data/ext/geoip2/libmaxminddb/.uncrustify.cfg +78 -0
  7. data/ext/geoip2/libmaxminddb/AUTHORS +0 -0
  8. data/ext/geoip2/libmaxminddb/Changes.md +238 -0
  9. data/ext/geoip2/libmaxminddb/LICENSE +202 -0
  10. data/ext/geoip2/libmaxminddb/Makefile.am +41 -0
  11. data/ext/geoip2/libmaxminddb/NOTICE +13 -0
  12. data/ext/geoip2/libmaxminddb/README.dev.md +58 -0
  13. data/ext/geoip2/libmaxminddb/README.md +122 -0
  14. data/ext/geoip2/libmaxminddb/appveyor.yml +33 -0
  15. data/ext/geoip2/libmaxminddb/bin/Makefile.am +5 -0
  16. data/ext/geoip2/libmaxminddb/bin/mmdblookup.c +397 -0
  17. data/ext/geoip2/libmaxminddb/bootstrap +21 -0
  18. data/ext/geoip2/libmaxminddb/common.mk +7 -0
  19. data/ext/geoip2/libmaxminddb/configure.ac +132 -0
  20. data/ext/geoip2/libmaxminddb/dev-bin/make-man-pages.pl +76 -0
  21. data/ext/geoip2/libmaxminddb/dev-bin/ppa-release.sh +50 -0
  22. data/ext/geoip2/libmaxminddb/dev-bin/regen-prototypes.pl +136 -0
  23. data/ext/geoip2/libmaxminddb/dev-bin/regen-win32-test-projs.pl +54 -0
  24. data/ext/geoip2/libmaxminddb/dev-bin/release.sh +106 -0
  25. data/ext/geoip2/libmaxminddb/dev-bin/uncrustify-all.sh +21 -0
  26. data/ext/geoip2/libmaxminddb/dev-bin/valgrind-all.pl +46 -0
  27. data/ext/geoip2/libmaxminddb/doc/libmaxminddb.md +889 -0
  28. data/ext/geoip2/libmaxminddb/doc/mmdblookup.md +103 -0
  29. data/ext/geoip2/libmaxminddb/include/maxminddb.h +232 -0
  30. data/ext/geoip2/libmaxminddb/include/maxminddb_config.h.in +14 -0
  31. data/ext/geoip2/libmaxminddb/projects/VS12/README.md +59 -0
  32. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb-release.props +32 -0
  33. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb-x64.props +14 -0
  34. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.props +32 -0
  35. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.sln +150 -0
  36. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.vcxproj +141 -0
  37. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.vcxproj.filters +26 -0
  38. data/ext/geoip2/libmaxminddb/projects/VS12/maxminddb_config.h +14 -0
  39. data/ext/geoip2/libmaxminddb/projects/VS12-tests/bad_pointers.vcxproj +105 -0
  40. data/ext/geoip2/libmaxminddb/projects/VS12-tests/basic_lookup.vcxproj +105 -0
  41. data/ext/geoip2/libmaxminddb/projects/VS12-tests/data_entry_list.vcxproj +105 -0
  42. data/ext/geoip2/libmaxminddb/projects/VS12-tests/data_types.vcxproj +105 -0
  43. data/ext/geoip2/libmaxminddb/projects/VS12-tests/dump.vcxproj +105 -0
  44. data/ext/geoip2/libmaxminddb/projects/VS12-tests/get_value.vcxproj +105 -0
  45. data/ext/geoip2/libmaxminddb/projects/VS12-tests/get_value_pointer_bug.vcxproj +105 -0
  46. data/ext/geoip2/libmaxminddb/projects/VS12-tests/ipv4_start_cache.vcxproj +105 -0
  47. data/ext/geoip2/libmaxminddb/projects/VS12-tests/ipv6_lookup_in_ipv4.vcxproj +105 -0
  48. data/ext/geoip2/libmaxminddb/projects/VS12-tests/libtap.vcxproj +85 -0
  49. data/ext/geoip2/libmaxminddb/projects/VS12-tests/maxminddb_test_helper.vcxproj +107 -0
  50. data/ext/geoip2/libmaxminddb/projects/VS12-tests/metadata.vcxproj +105 -0
  51. data/ext/geoip2/libmaxminddb/projects/VS12-tests/metadata_pointers.vcxproj +105 -0
  52. data/ext/geoip2/libmaxminddb/projects/VS12-tests/no_map_get_value.vcxproj +105 -0
  53. data/ext/geoip2/libmaxminddb/projects/VS12-tests/read_node.vcxproj +105 -0
  54. data/ext/geoip2/libmaxminddb/projects/VS12-tests/shared.vcxproj +104 -0
  55. data/ext/geoip2/libmaxminddb/projects/VS12-tests/threads.vcxproj +103 -0
  56. data/ext/geoip2/libmaxminddb/projects/VS12-tests/version.vcxproj +105 -0
  57. data/ext/geoip2/libmaxminddb/projects/test.vcxproj.template +105 -0
  58. data/ext/geoip2/libmaxminddb/src/Makefile.am +9 -0
  59. data/ext/geoip2/libmaxminddb/src/libmaxminddb.pc.in +11 -0
  60. data/ext/geoip2/libmaxminddb/src/maxminddb-compat-util.h +167 -0
  61. data/ext/geoip2/libmaxminddb/src/maxminddb.c +2171 -0
  62. data/ext/geoip2/libmaxminddb/t/Makefile.am +23 -0
  63. data/ext/geoip2/libmaxminddb/t/bad_databases_t.c +66 -0
  64. data/ext/geoip2/libmaxminddb/t/bad_pointers_t.c +53 -0
  65. data/ext/geoip2/libmaxminddb/t/basic_lookup_t.c +172 -0
  66. data/ext/geoip2/libmaxminddb/t/compile_c++_t.pl +107 -0
  67. data/ext/geoip2/libmaxminddb/t/data_entry_list_t.c +353 -0
  68. data/ext/geoip2/libmaxminddb/t/data_types_t.c +439 -0
  69. data/ext/geoip2/libmaxminddb/t/dump_t.c +103 -0
  70. data/ext/geoip2/libmaxminddb/t/get_value_pointer_bug_t.c +66 -0
  71. data/ext/geoip2/libmaxminddb/t/get_value_t.c +249 -0
  72. data/ext/geoip2/libmaxminddb/t/ipv4_start_cache_t.c +36 -0
  73. data/ext/geoip2/libmaxminddb/t/ipv6_lookup_in_ipv4_t.c +48 -0
  74. data/ext/geoip2/libmaxminddb/t/maxminddb_test_helper.c +255 -0
  75. data/ext/geoip2/libmaxminddb/t/maxminddb_test_helper.h +69 -0
  76. data/ext/geoip2/libmaxminddb/t/metadata_pointers_t.c +32 -0
  77. data/ext/geoip2/libmaxminddb/t/metadata_t.c +226 -0
  78. data/ext/geoip2/libmaxminddb/t/mmdblookup_t.pl +158 -0
  79. data/ext/geoip2/libmaxminddb/t/no_map_get_value_t.c +32 -0
  80. data/ext/geoip2/libmaxminddb/t/read_node_t.c +157 -0
  81. data/ext/geoip2/libmaxminddb/t/threads_t.c +196 -0
  82. data/ext/geoip2/libmaxminddb/t/version_t.c +10 -0
  83. data/geoip2_c.gemspec +1 -1
  84. data/lib/geoip2/version.rb +1 -1
  85. metadata +82 -1
@@ -0,0 +1,439 @@
1
+ #include "maxminddb_test_helper.h"
2
+
3
+ void test_all_data_types(MMDB_lookup_result_s *result, const char *ip,
4
+ const char *UNUSED(filename), const char *mode_desc)
5
+ {
6
+ {
7
+ char description[500];
8
+ snprintf(description, 500, "utf8_string field for %s - %s", ip,
9
+ mode_desc);
10
+
11
+ MMDB_entry_data_s data =
12
+ data_ok(result, MMDB_DATA_TYPE_UTF8_STRING, description,
13
+ "utf8_string", NULL);
14
+ const char *string = strndup(data.utf8_string, data.data_size);
15
+ // This is hex for "unicode! ☯ - ♫" as bytes
16
+ char expect[19] =
17
+ { 0x75, 0x6e, 0x69, 0x63, 0x6f, 0x64, 0x65, 0x21, 0x20, 0xe2, 0x98,
18
+ 0xaf, 0x20, 0x2d, 0x20, 0xe2, 0x99, 0xab, 0x00 };
19
+ is(string, expect, "got expected utf8_string value");
20
+
21
+ free((char *)string);
22
+ }
23
+
24
+ {
25
+ char description[500];
26
+ snprintf(description, 500, "double field for %s - %s", ip, mode_desc);
27
+
28
+ MMDB_entry_data_s data =
29
+ data_ok(result, MMDB_DATA_TYPE_DOUBLE, description, "double", NULL);
30
+
31
+ compare_double(data.double_value, 42.123456);
32
+ }
33
+
34
+ {
35
+ char description[500];
36
+ snprintf(description, 500, "float field for %s - %s", ip, mode_desc);
37
+
38
+ MMDB_entry_data_s data =
39
+ data_ok(result, MMDB_DATA_TYPE_FLOAT, description, "float", NULL);
40
+
41
+ compare_float(data.float_value, 1.1F);
42
+ }
43
+
44
+ {
45
+ char description[500];
46
+ snprintf(description, 500, "bytes field for %s - %s", ip, mode_desc);
47
+
48
+ MMDB_entry_data_s data =
49
+ data_ok(result, MMDB_DATA_TYPE_BYTES, description, "bytes", NULL);
50
+ uint8_t expect[] = { 0x00, 0x00, 0x00, 0x2a };
51
+ ok(memcmp((uint8_t *)data.bytes, expect, 4) == 0,
52
+ "bytes field has expected value");
53
+ }
54
+
55
+ {
56
+ char description[500];
57
+ snprintf(description, 500, "uint16 field for %s - %s", ip, mode_desc);
58
+
59
+ MMDB_entry_data_s data =
60
+ data_ok(result, MMDB_DATA_TYPE_UINT16, description, "uint16", NULL);
61
+ uint16_t expect = 100;
62
+ ok(data.uint16 == expect, "uint16 field is 100");
63
+ }
64
+
65
+ {
66
+ char description[500];
67
+ snprintf(description, 500, "uint32 field for %s - %s", ip, mode_desc);
68
+
69
+ MMDB_entry_data_s data =
70
+ data_ok(result, MMDB_DATA_TYPE_UINT32, description, "uint32", NULL);
71
+ uint32_t expect = 1 << 28;
72
+ cmp_ok(data.uint32, "==", expect, "uint32 field is 2**28");
73
+ }
74
+
75
+ {
76
+ char description[500];
77
+ snprintf(description, 500, "int32 field for %s - %s", ip, mode_desc);
78
+
79
+ MMDB_entry_data_s data =
80
+ data_ok(result, MMDB_DATA_TYPE_INT32, description, "int32", NULL);
81
+ int32_t expect = 1 << 28;
82
+ expect *= -1;
83
+ cmp_ok(data.int32, "==", expect, "int32 field is -(2**28)");
84
+ }
85
+
86
+ {
87
+ char description[500];
88
+ snprintf(description, 500, "uint64 field for %s - %s", ip, mode_desc);
89
+
90
+ MMDB_entry_data_s data =
91
+ data_ok(result, MMDB_DATA_TYPE_UINT64, description, "uint64", NULL);
92
+ uint64_t expect = 1;
93
+ expect <<= 60;
94
+ cmp_ok(data.uint64, "==", expect, "uint64 field is 2**60");
95
+ }
96
+
97
+ {
98
+ char description[500];
99
+ snprintf(description, 500, "uint128 field for %s - %s", ip, mode_desc);
100
+
101
+ MMDB_entry_data_s data =
102
+ data_ok(result, MMDB_DATA_TYPE_UINT128, description, "uint128",
103
+ NULL);
104
+ #if MMDB_UINT128_IS_BYTE_ARRAY
105
+ uint8_t expect[16] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
107
+ ok(memcmp(data.uint128, expect, 16) == 0, "uint128 field is 2**120");
108
+ #else
109
+ mmdb_uint128_t expect = 1;
110
+ expect <<= 120;
111
+ cmp_ok(data.uint128, "==", expect, "uint128 field is 2**120");
112
+ #endif
113
+ }
114
+
115
+ {
116
+ char description[500];
117
+ snprintf(description, 500, "boolean field for %s - %s", ip, mode_desc);
118
+
119
+ MMDB_entry_data_s data =
120
+ data_ok(result, MMDB_DATA_TYPE_BOOLEAN, description, "boolean",
121
+ NULL);
122
+ cmp_ok(data.boolean, "==", true, "boolean field is true");
123
+ }
124
+
125
+ {
126
+ char description[500];
127
+ snprintf(description, 500, "array field for %s - %s", ip, mode_desc);
128
+
129
+ MMDB_entry_data_s data =
130
+ data_ok(result, MMDB_DATA_TYPE_ARRAY, description, "array", NULL);
131
+ ok(data.data_size == 3, "array field has 3 elements");
132
+
133
+ snprintf(description, 500, "array[0] for %s - %s", ip, mode_desc);
134
+ data =
135
+ data_ok(result, MMDB_DATA_TYPE_UINT32, description, "array", "0",
136
+ NULL);
137
+ ok(data.uint32 == 1, "array[0] is 1");
138
+
139
+ snprintf(description, 500, "array[1] for %s - %s", ip, mode_desc);
140
+ data =
141
+ data_ok(result, MMDB_DATA_TYPE_UINT32, description, "array", "1",
142
+ NULL);
143
+ ok(data.uint32 == 2, "array[1] is 1");
144
+
145
+ snprintf(description, 500, "array[2] for %s - %s", ip, mode_desc);
146
+ data =
147
+ data_ok(result, MMDB_DATA_TYPE_UINT32, description, "array", "2",
148
+ NULL);
149
+ ok(data.uint32 == 3, "array[2] is 1");
150
+ }
151
+
152
+ {
153
+ char description[500];
154
+ snprintf(description, 500, "map field for %s - %s", ip, mode_desc);
155
+
156
+ MMDB_entry_data_s data =
157
+ data_ok(result, MMDB_DATA_TYPE_MAP, description, "map", NULL);
158
+ ok(data.data_size == 1, "map field has 1 element");
159
+
160
+ snprintf(description, 500, "map{mapX} for %s - %s", ip, mode_desc);
161
+
162
+ data =
163
+ data_ok(result, MMDB_DATA_TYPE_MAP, description, "map", "mapX",
164
+ NULL);
165
+ ok(data.data_size == 2, "map{mapX} field has 2 elements");
166
+
167
+ snprintf(description, 500, "map{mapX}{utf8_stringX} for %s - %s", ip,
168
+ mode_desc);
169
+
170
+ data =
171
+ data_ok(result, MMDB_DATA_TYPE_UTF8_STRING, description, "map",
172
+ "mapX", "utf8_stringX", NULL);
173
+ const char *string = strndup(data.utf8_string, data.data_size);
174
+ is(string, "hello", "map{mapX}{utf8_stringX} is 'hello'");
175
+ free((char *)string);
176
+
177
+ snprintf(description, 500, "map{mapX}{arrayX} for %s - %s", ip,
178
+ mode_desc);
179
+ data =
180
+ data_ok(result, MMDB_DATA_TYPE_ARRAY, description, "map", "mapX",
181
+ "arrayX", NULL);
182
+ ok(data.data_size == 3, "map{mapX}{arrayX} field has 3 elements");
183
+
184
+ snprintf(description, 500, "map{mapX}{arrayX}[0] for %s - %s", ip,
185
+ mode_desc);
186
+ data =
187
+ data_ok(result, MMDB_DATA_TYPE_UINT32, description, "map", "mapX",
188
+ "arrayX", "0", NULL);
189
+ ok(data.uint32 == 7, "map{mapX}{arrayX}[0] is 7");
190
+
191
+ snprintf(description, 500, "map{mapX}{arrayX}[1] for %s - %s", ip,
192
+ mode_desc);
193
+ data =
194
+ data_ok(result, MMDB_DATA_TYPE_UINT32, description, "map", "mapX",
195
+ "arrayX", "1", NULL);
196
+ ok(data.uint32 == 8, "map{mapX}{arrayX}[1] is 8");
197
+
198
+ snprintf(description, 500, "map{mapX}{arrayX}[2] for %s - %s", ip,
199
+ mode_desc);
200
+ data =
201
+ data_ok(result, MMDB_DATA_TYPE_UINT32, description, "map", "mapX",
202
+ "arrayX", "2", NULL);
203
+ ok(data.uint32 == 9, "map{mapX}{arrayX}[2] is 9");
204
+ }
205
+
206
+ }
207
+
208
+ void test_all_data_types_as_zero(MMDB_lookup_result_s *result, const char *ip,
209
+ const char *UNUSED(
210
+ filename), const char *mode_desc)
211
+ {
212
+ {
213
+ char description[500];
214
+ snprintf(description, 500, "utf8_string field for %s - %s", ip,
215
+ mode_desc);
216
+
217
+ MMDB_entry_data_s data =
218
+ data_ok(result, MMDB_DATA_TYPE_UTF8_STRING, description,
219
+ "utf8_string", NULL);
220
+ is(data.utf8_string, "", "got expected utf8_string value (NULL)");
221
+ }
222
+
223
+ {
224
+ char description[500];
225
+ snprintf(description, 500, "double field for %s - %s", ip, mode_desc);
226
+
227
+ MMDB_entry_data_s data =
228
+ data_ok(result, MMDB_DATA_TYPE_DOUBLE, description, "double", NULL);
229
+
230
+ compare_double(data.double_value, 0.0);
231
+ }
232
+
233
+ {
234
+ char description[500];
235
+ snprintf(description, 500, "float field for %s - %s", ip, mode_desc);
236
+
237
+ MMDB_entry_data_s data =
238
+ data_ok(result, MMDB_DATA_TYPE_FLOAT, description, "float", NULL);
239
+
240
+ compare_float(data.float_value, 0.0F);
241
+ }
242
+
243
+ {
244
+ char description[500];
245
+ snprintf(description, 500, "bytes field for %s - %s", ip, mode_desc);
246
+
247
+ MMDB_entry_data_s data =
248
+ data_ok(result, MMDB_DATA_TYPE_BYTES, description, "bytes", NULL);
249
+ ok(data.data_size == 0, "bytes field data_size is 0");
250
+ /* In C does it makes sense to write something like this?
251
+ uint8_t expect[0] = {};
252
+ ok(memcmp(data.bytes, expect, 0) == 0, "got expected bytes value (NULL)"); */
253
+ }
254
+
255
+ {
256
+ char description[500];
257
+ snprintf(description, 500, "uint16 field for %s - %s", ip, mode_desc);
258
+
259
+ MMDB_entry_data_s data =
260
+ data_ok(result, MMDB_DATA_TYPE_UINT16, description, "uint16", NULL);
261
+ uint16_t expect = 0;
262
+ ok(data.uint16 == expect, "uint16 field is 0");
263
+ }
264
+
265
+ {
266
+ char description[500];
267
+ snprintf(description, 500, "uint32 field for %s - %s", ip, mode_desc);
268
+
269
+ MMDB_entry_data_s data =
270
+ data_ok(result, MMDB_DATA_TYPE_UINT32, description, "uint32", NULL);
271
+ uint32_t expect = 0;
272
+ cmp_ok(data.uint32, "==", expect, "uint32 field is 0");
273
+ }
274
+
275
+ {
276
+ char description[500];
277
+ snprintf(description, 500, "int32 field for %s - %s", ip, mode_desc);
278
+
279
+ MMDB_entry_data_s data =
280
+ data_ok(result, MMDB_DATA_TYPE_INT32, description, "int32", NULL);
281
+ int32_t expect = 0;
282
+ expect *= -1;
283
+ cmp_ok(data.int32, "==", expect, "int32 field is 0");
284
+ }
285
+
286
+ {
287
+ char description[500];
288
+ snprintf(description, 500, "uint64 field for %s - %s", ip, mode_desc);
289
+
290
+ MMDB_entry_data_s data =
291
+ data_ok(result, MMDB_DATA_TYPE_UINT64, description, "uint64", NULL);
292
+ uint64_t expect = 0;
293
+ cmp_ok(data.uint64, "==", expect, "uint64 field is 0");
294
+ }
295
+
296
+ {
297
+ char description[500];
298
+ snprintf(description, 500, "uint128 field for %s - %s", ip, mode_desc);
299
+
300
+ MMDB_entry_data_s data =
301
+ data_ok(result, MMDB_DATA_TYPE_UINT128, description, "uint128",
302
+ NULL);
303
+ #if MMDB_UINT128_IS_BYTE_ARRAY
304
+ uint8_t expect[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
306
+ ok(memcmp(data.uint128, expect, 16) == 0, "uint128 field is 0");
307
+ #else
308
+ mmdb_uint128_t expect = 0;
309
+ cmp_ok(data.uint128, "==", expect, "uint128 field is 0");
310
+ #endif
311
+ }
312
+
313
+ {
314
+ char description[500];
315
+ snprintf(description, 500, "boolean field for %s - %s", ip, mode_desc);
316
+
317
+ MMDB_entry_data_s data =
318
+ data_ok(result, MMDB_DATA_TYPE_BOOLEAN, description, "boolean",
319
+ NULL);
320
+ cmp_ok(data.boolean, "==", false, "boolean field is false");
321
+ }
322
+
323
+ {
324
+ char description[500];
325
+ snprintf(description, 500, "array field for %s - %s", ip, mode_desc);
326
+
327
+ MMDB_entry_data_s data =
328
+ data_ok(result, MMDB_DATA_TYPE_ARRAY, description, "array", NULL);
329
+ ok(data.data_size == 0, "array field has 0 elements");
330
+ }
331
+
332
+ {
333
+ char description[500];
334
+ snprintf(description, 500, "map field for %s - %s", ip, mode_desc);
335
+
336
+ MMDB_entry_data_s data =
337
+ data_ok(result, MMDB_DATA_TYPE_MAP, description, "map", NULL);
338
+ ok(data.data_size == 0, "map field has 0 elements");
339
+ }
340
+ }
341
+
342
+ void run_tests(int mode, const char *mode_desc)
343
+ {
344
+ const char *filename = "MaxMind-DB-test-decoder.mmdb";
345
+ const char *path = test_database_path(filename);
346
+ MMDB_s *mmdb = open_ok(path, mode, mode_desc);
347
+
348
+ // All of the remaining tests require an open mmdb
349
+ if (NULL == mmdb) {
350
+ diag("could not open %s - skipping remaining tests", path);
351
+ return;
352
+ }
353
+
354
+ free((void *)path);
355
+
356
+ {
357
+ const char *ip = "not an ip";
358
+
359
+ int gai_error, mmdb_error;
360
+ MMDB_lookup_result_s result =
361
+ MMDB_lookup_string(mmdb, ip, &gai_error, &mmdb_error);
362
+
363
+ cmp_ok(gai_error, "==", EAI_NONAME,
364
+ "MMDB_lookup populates getaddrinfo error properly - %s", ip);
365
+
366
+ ok(!result.found_entry,
367
+ "no result entry struct returned for invalid IP address '%s'", ip);
368
+ }
369
+
370
+ {
371
+ const char *ip = "e900::";
372
+ MMDB_lookup_result_s result =
373
+ lookup_string_ok(mmdb, ip, filename, mode_desc);
374
+
375
+ ok(
376
+ !result.found_entry,
377
+ "no result entry struct returned for IP address not in the database - %s - %s - %s",
378
+ ip, filename, mode_desc);
379
+ }
380
+
381
+ {
382
+ const char *ip = "::1.1.1.1";
383
+ MMDB_lookup_result_s result =
384
+ lookup_string_ok(mmdb, ip, filename, mode_desc);
385
+
386
+ ok(
387
+ result.found_entry,
388
+ "got a result entry struct for IP address in the database - %s - %s - %s",
389
+ ip, filename, mode_desc);
390
+
391
+ cmp_ok(
392
+ result.entry.offset, ">", 0,
393
+ "result.entry.offset > 0 for address in the database - %s - %s - %s",
394
+ ip, filename, mode_desc);
395
+
396
+ test_all_data_types(&result, ip, filename, mode_desc);
397
+ }
398
+
399
+ {
400
+ const char *ip = "::4.5.6.7";
401
+ MMDB_lookup_result_s result =
402
+ lookup_string_ok(mmdb, ip, filename, mode_desc);
403
+
404
+ ok(
405
+ result.found_entry,
406
+ "got a result entry struct for IP address in the database - %s - %s - %s",
407
+ ip, filename, mode_desc);
408
+
409
+ cmp_ok(
410
+ result.entry.offset, ">", 0,
411
+ "result.entry.offset > 0 for address in the database - %s - %s - %s",
412
+ ip, filename, mode_desc);
413
+
414
+ test_all_data_types(&result, ip, filename, mode_desc);
415
+ }
416
+
417
+ {
418
+ const char *ip = "::0.0.0.0";
419
+ MMDB_lookup_result_s result =
420
+ lookup_string_ok(mmdb, ip, filename, mode_desc);
421
+
422
+ ok(
423
+ result.found_entry,
424
+ "got a result entry struct for IP address in the database - %s - %s - %s",
425
+ ip, filename, mode_desc);
426
+
427
+ test_all_data_types_as_zero(&result, ip, filename, mode_desc);
428
+ }
429
+
430
+ MMDB_close(mmdb);
431
+ free(mmdb);
432
+ }
433
+
434
+ int main(void)
435
+ {
436
+ plan(NO_PLAN);
437
+ for_all_modes(&run_tests);
438
+ done_testing();
439
+ }
@@ -0,0 +1,103 @@
1
+ #define _GNU_SOURCE
2
+ #include "maxminddb_test_helper.h"
3
+
4
+ #ifdef HAVE_OPEN_MEMSTREAM
5
+ void run_tests(int mode, const char *mode_desc)
6
+ {
7
+ const char *filename = "MaxMind-DB-test-decoder.mmdb";
8
+ const char *path = test_database_path(filename);
9
+ MMDB_s *mmdb = open_ok(path, mode, mode_desc);
10
+ free((void *)path);
11
+
12
+ const char *ip = "1.1.1.1";
13
+ MMDB_lookup_result_s result =
14
+ lookup_string_ok(mmdb, ip, filename, mode_desc);
15
+
16
+ MMDB_entry_data_list_s *entry_data_list;
17
+ int status = MMDB_get_entry_data_list(&result.entry, &entry_data_list);
18
+
19
+ ok(MMDB_SUCCESS == status,
20
+ "MMDB_get_entry_data_list is successful");
21
+
22
+ char *dump_output;
23
+ size_t dump_size;
24
+ FILE *stream = open_memstream(&dump_output, &dump_size);
25
+ status = MMDB_dump_entry_data_list(stream, entry_data_list, 0);
26
+ fclose(stream);
27
+ MMDB_free_entry_data_list(entry_data_list);
28
+
29
+ ok(MMDB_SUCCESS == status,
30
+ "MMDB_dump_entry_data_list is successful - %s",
31
+ mode_desc);
32
+
33
+ cmp_ok(dump_size, ">", 0, "MMDB_dump produced output - %s", mode_desc);
34
+
35
+ char *expect[] = {
36
+ "{",
37
+ " \"array\": ",
38
+ " [",
39
+ " 1 <uint32>",
40
+ " 2 <uint32>",
41
+ " 3 <uint32>",
42
+ " ]",
43
+ " \"boolean\": ",
44
+ " true <boolean>",
45
+ " \"bytes\": ",
46
+ " 0000002A <bytes>",
47
+ " \"double\": ",
48
+ " 42.123456 <double>",
49
+ " \"float\": ",
50
+ " 1.100000 <float>",
51
+ " \"int32\": ",
52
+ " -268435456 <int32>",
53
+ " \"map\": ",
54
+ " {",
55
+ " \"mapX\": ",
56
+ " {",
57
+ " \"arrayX\": ",
58
+ " [",
59
+ " 7 <uint32>",
60
+ " 8 <uint32>",
61
+ " 9 <uint32>",
62
+ " ]",
63
+ " \"utf8_stringX\": ",
64
+ " \"hello\" <utf8_string>",
65
+ " }",
66
+ " }",
67
+ " \"uint128\": ",
68
+ " 0x01000000000000000000000000000000 <uint128>",
69
+ " \"uint16\": ",
70
+ " 100 <uint16>",
71
+ " \"uint32\": ",
72
+ " 268435456 <uint32>",
73
+ " \"uint64\": ",
74
+ " 1152921504606846976 <uint64>",
75
+ " \"utf8_string\": ",
76
+ " \"unicode! ☯ - ♫\" <utf8_string>",
77
+ "}"
78
+ };
79
+
80
+ for (int i = 0; i < 42; i++) {
81
+ ok((strstr(dump_output, expect[i]) != NULL),
82
+ "dump output contains expected line (%s) - %s", expect[i],
83
+ mode_desc);
84
+ }
85
+
86
+ free(dump_output);
87
+
88
+ MMDB_close(mmdb);
89
+ free(mmdb);
90
+ }
91
+
92
+ int main(void)
93
+ {
94
+ plan(NO_PLAN);
95
+ for_all_modes(&run_tests);
96
+ done_testing();
97
+ }
98
+ #else
99
+ int main(void)
100
+ {
101
+ plan(SKIP_ALL, "This test requires the open_memstream() function");
102
+ }
103
+ #endif
@@ -0,0 +1,66 @@
1
+ #include "maxminddb_test_helper.h"
2
+
3
+ /* This test exercises a bug found in MMDB_get_value for certain types of
4
+ * nested data structures which contain pointers. See
5
+ * https://github.com/maxmind/libmaxminddb/issues/2 and
6
+ * https://github.com/maxmind/libmaxminddb/issues/3.
7
+ *
8
+ * There is also the potential for a similar bug when looking up a value by
9
+ * path in an array. This is not tested (yet) as we don't have the right test
10
+ * data for it.
11
+ *
12
+ * These tests are somewhat fragile since they depend on a specific data
13
+ * layout in the database. Ideally the test would check that this layout
14
+ * exists before checking to see if the lookups are correct.
15
+ */
16
+
17
+ void test_one_ip(MMDB_s *mmdb, const char *filename, const char *mode_desc,
18
+ char *ip, char *country_code)
19
+ {
20
+ MMDB_lookup_result_s result =
21
+ lookup_string_ok(mmdb, ip, filename, mode_desc);
22
+
23
+ MMDB_entry_data_s entry_data =
24
+ data_ok(&result, MMDB_DATA_TYPE_UTF8_STRING, "country{iso_code}",
25
+ "country", "iso_code", NULL);
26
+
27
+ if (ok(entry_data.has_data, "found data for country{iso_code}")) {
28
+ char *string = strndup(entry_data.utf8_string, entry_data.data_size);
29
+ if (!string) {
30
+ ok(0, "strndup() call failed");
31
+ exit(1);
32
+ }
33
+ if (!ok(strcmp(string,
34
+ country_code) == 0, "iso_code is %s", country_code)) {
35
+ diag(" value is %s", string);
36
+ }
37
+ free(string);
38
+ }
39
+ }
40
+
41
+ void run_tests(int mode, const char *mode_desc)
42
+ {
43
+ const char *filename = "GeoIP2-City-Test.mmdb";
44
+ const char *path = test_database_path(filename);
45
+ MMDB_s *mmdb = open_ok(path, mode, mode_desc);
46
+ free((void *)path);
47
+
48
+ /* This exercises a bug where the entire top-level value is a pointer to
49
+ * another part of the data section. */
50
+ test_one_ip(mmdb, filename, mode_desc, "2001:218::", "JP");
51
+ /* This exercises a bug where one subnet's data shares part of the data
52
+ * with another subnet - in this case it is the "country" key (and others)
53
+ * in the top level map. We are testing that the "country" key's value is
54
+ * handled correctly. The value _should_ be a pointer to another map. */
55
+ test_one_ip(mmdb, filename, mode_desc, "81.2.69.160", "GB");
56
+
57
+ MMDB_close(mmdb);
58
+ free(mmdb);
59
+ }
60
+
61
+ int main(void)
62
+ {
63
+ plan(NO_PLAN);
64
+ for_all_modes(&run_tests);
65
+ done_testing();
66
+ }