geoip2_c 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,249 @@
1
+ #include "maxminddb_test_helper.h"
2
+
3
+ void test_array_0_result(int status, MMDB_entry_data_s entry_data,
4
+ char *function)
5
+ {
6
+ cmp_ok(status, "==", MMDB_SUCCESS,
7
+ "status for %s() is MMDB_SUCCESS - array[0]", function);
8
+ ok(entry_data.has_data, "found a value for array[0]");
9
+ cmp_ok(entry_data.type, "==", MMDB_DATA_TYPE_UINT32,
10
+ "returned entry type is uint32 - array[0]");
11
+ cmp_ok(entry_data.uint32, "==", 1, "entry value is 1 - array[0]");
12
+ }
13
+
14
+ void test_array_2_result(int status, MMDB_entry_data_s entry_data,
15
+ char *function)
16
+ {
17
+ cmp_ok(status, "==", MMDB_SUCCESS,
18
+ "status for %s() is MMDB_SUCCESS - array[2]", function);
19
+ ok(entry_data.has_data, "found a value for array[2]");
20
+ cmp_ok(entry_data.type, "==", MMDB_DATA_TYPE_UINT32,
21
+ "returned entry type is uint32 - array[2]");
22
+ cmp_ok(entry_data.uint32, "==", 3, "entry value is 3 - array[2]");
23
+ }
24
+
25
+ int call_vget_value(MMDB_entry_s *entry, MMDB_entry_data_s *entry_data, ...)
26
+ {
27
+ va_list keys;
28
+ va_start(keys, entry_data);
29
+
30
+ int status = MMDB_vget_value(entry, entry_data, keys);
31
+
32
+ va_end(keys);
33
+
34
+ return status;
35
+ }
36
+
37
+ void test_simple_structure(int mode, const char *mode_desc)
38
+ {
39
+ const char *filename = "MaxMind-DB-test-decoder.mmdb";
40
+ const char *path = test_database_path(filename);
41
+ MMDB_s *mmdb = open_ok(path, mode, mode_desc);
42
+ free((void *)path);
43
+
44
+ const char *ip = "1.1.1.1";
45
+ MMDB_lookup_result_s result =
46
+ lookup_string_ok(mmdb, ip, filename, mode_desc);
47
+
48
+ {
49
+ MMDB_entry_data_s entry_data;
50
+ const char *lookup_path[] = { "array", "0", NULL };
51
+ int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
52
+ test_array_0_result(status, entry_data, "MMDB_aget_value");
53
+
54
+ status = MMDB_get_value(&result.entry, &entry_data, "array", "0", NULL);
55
+ test_array_0_result(status, entry_data, "MMDB_get_value");
56
+
57
+ status =
58
+ call_vget_value(&result.entry, &entry_data, "array", "0", NULL);
59
+ test_array_0_result(status, entry_data, "MMDB_vget_value");
60
+ }
61
+
62
+ {
63
+ MMDB_entry_data_s entry_data;
64
+ const char *lookup_path[] = { "array", "2", NULL };
65
+ int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
66
+ test_array_2_result(status, entry_data, "MMDB_aget_value");
67
+
68
+ status = MMDB_get_value(&result.entry, &entry_data, "array", "2", NULL);
69
+ test_array_2_result(status, entry_data, "MMDB_get_value");
70
+
71
+ status =
72
+ call_vget_value(&result.entry, &entry_data, "array", "2", NULL);
73
+ test_array_2_result(status, entry_data, "MMDB_vget_value");
74
+ }
75
+
76
+
77
+ {
78
+ MMDB_entry_data_s entry_data;
79
+ int status = MMDB_get_value(&result.entry, &entry_data, "array", "zero",
80
+ NULL);
81
+ cmp_ok(status, "==", MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR,
82
+ "MMDB_get_value() returns error on non-integer array index");
83
+ }
84
+
85
+ {
86
+ MMDB_entry_data_s entry_data;
87
+ int status = MMDB_get_value(&result.entry, &entry_data, "array", "-1",
88
+ NULL);
89
+ cmp_ok(status, "==", MMDB_INVALID_LOOKUP_PATH_ERROR,
90
+ "MMDB_get_value() returns error on negative integer");
91
+ }
92
+
93
+ {
94
+ MMDB_entry_data_s entry_data;
95
+ int status =
96
+ MMDB_get_value(&result.entry, &entry_data, "array",
97
+ "18446744073709551616",
98
+ NULL);
99
+ cmp_ok(status, "==", MMDB_INVALID_LOOKUP_PATH_ERROR,
100
+ "MMDB_get_value() returns error on integer larger than LONG_MAX");
101
+ }
102
+
103
+ MMDB_close(mmdb);
104
+ free(mmdb);
105
+ }
106
+
107
+ void test_complex_map_a_result(int status, MMDB_entry_data_s entry_data,
108
+ char *function)
109
+ {
110
+ cmp_ok(status, "==", MMDB_SUCCESS,
111
+ "status for %s() is MMDB_SUCCESS - map1{map2}{array}[0]{map3}{a}",
112
+ function);
113
+ ok(entry_data.has_data,
114
+ "found a value for map1{map2}{array}[0]{map3}{a}");
115
+ cmp_ok(entry_data.type, "==", MMDB_DATA_TYPE_UINT32,
116
+ "returned entry type is uint32 - map1{map2}{array}[0]{map3}{a}");
117
+ cmp_ok(entry_data.uint32, "==", 1,
118
+ "entry value is 1 - map1{map2}{array}[0]{map3}{a}");
119
+ }
120
+
121
+ void test_complex_map_c_result(int status, MMDB_entry_data_s entry_data,
122
+ char *function)
123
+ {
124
+ cmp_ok(
125
+ status, "==", MMDB_SUCCESS,
126
+ "status for %s() is MMDB_SUCCESS - map1{map2}{array}[0]{map3}{c}",
127
+ function);
128
+ ok(entry_data.has_data,
129
+ "found a value for map1{map2}{array}[0]{map3}{c}");
130
+ cmp_ok(entry_data.type, "==", MMDB_DATA_TYPE_UINT32,
131
+ "returned entry type is uint32 - map1{map2}{array}[0]{map3}{c}");
132
+ cmp_ok(entry_data.uint32, "==", 3,
133
+ "entry value is 3 - map1{map2}{array}[0]{map3}{c}");
134
+ }
135
+
136
+ void test_no_result(int status, MMDB_entry_data_s entry_data, char *function,
137
+ char *path_description)
138
+ {
139
+ cmp_ok(status, "==", MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR,
140
+ "status for %s() is MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR - %s",
141
+ function, path_description);
142
+ ok(!entry_data.has_data, "did not find a value for %s", path_description);
143
+ }
144
+
145
+ void test_nested_structure(int mode, const char *mode_desc)
146
+ {
147
+ const char *filename = "MaxMind-DB-test-nested.mmdb";
148
+ const char *path = test_database_path(filename);
149
+ MMDB_s *mmdb = open_ok(path, mode, mode_desc);
150
+ free((void *)path);
151
+
152
+ const char *ip = "1.1.1.1";
153
+ MMDB_lookup_result_s result =
154
+ lookup_string_ok(mmdb, ip, filename, mode_desc);
155
+
156
+ {
157
+ MMDB_entry_data_s entry_data;
158
+ const char *lookup_path[] =
159
+ { "map1", "map2", "array", "0", "map3", "a", NULL };
160
+ int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
161
+ test_complex_map_a_result(status, entry_data, "MMDB_aget_value");
162
+
163
+ status = MMDB_get_value(&result.entry, &entry_data,
164
+ "map1", "map2", "array", "0", "map3", "a",
165
+ NULL);
166
+ test_complex_map_a_result(status, entry_data, "MMDB_get_value");
167
+
168
+ status = call_vget_value(&result.entry, &entry_data,
169
+ "map1", "map2", "array", "0", "map3", "a",
170
+ NULL);
171
+ test_complex_map_a_result(status, entry_data, "MMDB_vget_value");
172
+ }
173
+
174
+ {
175
+ MMDB_entry_data_s entry_data;
176
+ const char *lookup_path[] =
177
+ { "map1", "map2", "array", "0", "map3", "c", NULL };
178
+ int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
179
+ test_complex_map_c_result(status, entry_data, "MMDB_aget_value");
180
+
181
+ status = MMDB_get_value(&result.entry, &entry_data,
182
+ "map1", "map2", "array", "0", "map3", "c",
183
+ NULL);
184
+ test_complex_map_c_result(status, entry_data, "MMDB_get_value");
185
+
186
+ status = call_vget_value(&result.entry, &entry_data,
187
+ "map1", "map2", "array", "0", "map3", "c",
188
+ NULL);
189
+ test_complex_map_c_result(status, entry_data, "MMDB_vget_value");
190
+ }
191
+
192
+ {
193
+ MMDB_entry_data_s entry_data;
194
+ const char *lookup_path[] =
195
+ { "map1", "map42", "array", "0", "map3", "c", NULL };
196
+ int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
197
+ test_no_result(status, entry_data, "MMDB_aget_value",
198
+ "map1{map42}{array}[0]{map3}{c}");
199
+
200
+ status = MMDB_get_value(&result.entry, &entry_data,
201
+ "map1", "map42", "array", "0", "map3", "c",
202
+ NULL);
203
+ test_no_result(status, entry_data, "MMDB_get_value",
204
+ "map1{map42}{array}[0]{map3}{c}");
205
+
206
+ status = call_vget_value(&result.entry, &entry_data,
207
+ "map1", "map42", "array", "0", "map3", "c",
208
+ NULL);
209
+ test_no_result(status, entry_data, "MMDB_vget_value",
210
+ "map1{map42}{array}[0]{map3}{c}");
211
+ }
212
+
213
+ {
214
+ MMDB_entry_data_s entry_data;
215
+ const char *lookup_path[] =
216
+ { "map1", "map2", "array", "9", "map3", "c", NULL };
217
+ int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
218
+ test_no_result(status, entry_data, "MMDB_aget_value",
219
+ "map1{map42}{array}[9]{map3}{c}");
220
+
221
+ status = MMDB_get_value(&result.entry, &entry_data,
222
+ "map1", "map2", "array", "9", "map3", "c",
223
+ NULL);
224
+ test_no_result(status, entry_data, "MMDB_get_value",
225
+ "map1{map42}{array}[9]{map3}{c}");
226
+
227
+ status = call_vget_value(&result.entry, &entry_data,
228
+ "map1", "map2", "array", "9", "map3", "c",
229
+ NULL);
230
+ test_no_result(status, entry_data, "MMDB_vget_value",
231
+ "map1{map42}{array}[9]{map3}{c}");
232
+ }
233
+
234
+ MMDB_close(mmdb);
235
+ free(mmdb);
236
+ }
237
+
238
+ void run_tests(int mode, const char *mode_desc)
239
+ {
240
+ test_simple_structure(mode, mode_desc);
241
+ test_nested_structure(mode, mode_desc);
242
+ }
243
+
244
+ int main(void)
245
+ {
246
+ plan(NO_PLAN);
247
+ for_all_modes(&run_tests);
248
+ done_testing();
249
+ }
@@ -0,0 +1,36 @@
1
+ #include "maxminddb_test_helper.h"
2
+
3
+ void test_one_ip(MMDB_s *mmdb, const char *ip, const char *filename,
4
+ const char *mode_desc)
5
+ {
6
+ MMDB_lookup_result_s result =
7
+ lookup_string_ok(mmdb, ip, filename, mode_desc);
8
+
9
+ ok(
10
+ result.found_entry,
11
+ "got a result for an IPv4 address included in a larger-than-IPv4 subnet - %s - %s",
12
+ ip, mode_desc);
13
+
14
+ data_ok(&result, MMDB_DATA_TYPE_UTF8_STRING, "string value for IP", NULL);
15
+ }
16
+
17
+ void run_tests(int mode, const char *mode_desc)
18
+ {
19
+ const char *filename = "MaxMind-DB-no-ipv4-search-tree.mmdb";
20
+ const char *path = test_database_path(filename);
21
+ MMDB_s *mmdb = open_ok(path, mode, mode_desc);
22
+ free((void *)path);
23
+
24
+ test_one_ip(mmdb, "1.1.1.1", filename, mode_desc);
25
+ test_one_ip(mmdb, "255.255.255.255", filename, mode_desc);
26
+
27
+ MMDB_close(mmdb);
28
+ free(mmdb);
29
+ }
30
+
31
+ int main(void)
32
+ {
33
+ plan(NO_PLAN);
34
+ for_all_modes(&run_tests);
35
+ done_testing();
36
+ }
@@ -0,0 +1,48 @@
1
+ #include "maxminddb_test_helper.h"
2
+
3
+ void run_tests(int mode, const char *mode_desc)
4
+ {
5
+ const char *filename = "MaxMind-DB-test-ipv4-28.mmdb";
6
+ const char *path = test_database_path(filename);
7
+ MMDB_s *mmdb = open_ok(path, mode, mode_desc);
8
+ free((void *)path);
9
+
10
+ const char *ip = "::abcd";
11
+ int gai_error, mmdb_error;
12
+ MMDB_lookup_result_s UNUSED(result) =
13
+ MMDB_lookup_string(mmdb, ip, &gai_error, &mmdb_error);
14
+
15
+ cmp_ok(
16
+ mmdb_error, "==", MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR,
17
+ "MMDB_lookup_string sets mmdb_error to MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR when we try to look up an IPv6 address in an IPv4-only database");
18
+
19
+ struct addrinfo hints = {
20
+ .ai_family = AF_INET6,
21
+ .ai_flags = AI_NUMERICHOST
22
+ };
23
+
24
+ struct addrinfo *addresses;
25
+ gai_error = getaddrinfo("2001:db8:85a3:0:0:8a2e:370:7334", NULL,
26
+ &hints, &addresses);
27
+ if (gai_error) {
28
+ BAIL_OUT("getaddrinfo failed: %s", gai_strerror(gai_error));
29
+ }
30
+
31
+ mmdb_error = 0;
32
+ MMDB_lookup_sockaddr(mmdb, addresses->ai_addr, &mmdb_error);
33
+
34
+ cmp_ok(
35
+ mmdb_error, "==", MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR,
36
+ "MMDB_lookup_sockaddr sets mmdb_error to MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR when we try to look up an IPv6 address in an IPv4-only database");
37
+
38
+ freeaddrinfo(addresses);
39
+ MMDB_close(mmdb);
40
+ free(mmdb);
41
+ }
42
+
43
+ int main(void)
44
+ {
45
+ plan(NO_PLAN);
46
+ for_all_modes(&run_tests);
47
+ done_testing();
48
+ }
@@ -0,0 +1,255 @@
1
+ #if HAVE_CONFIG_H
2
+ #include <config.h>
3
+ #endif
4
+
5
+ #define _POSIX_C_SOURCE 200112L
6
+ #include <assert.h>
7
+ #include <stdarg.h>
8
+ #include <sys/types.h>
9
+
10
+ #include "maxminddb.h"
11
+ #include "maxminddb_test_helper.h"
12
+
13
+ #ifdef _WIN32
14
+ #include <io.h>
15
+ #else
16
+ #include <libgen.h>
17
+ #include <unistd.h>
18
+ #endif
19
+
20
+ #define NO_PROTO
21
+
22
+ #ifndef strndup
23
+ /* *INDENT-OFF* */
24
+ /* Copied from the libiberty strndup.c, which is LPGPL 2+ */
25
+ NO_PROTO char *strndup (const char *s, size_t n)
26
+ {
27
+ char *result;
28
+ size_t len = strlen (s);
29
+
30
+ if (n < len)
31
+ len = n;
32
+
33
+ result = (char *) malloc (len + 1);
34
+ if (!result)
35
+ return 0;
36
+
37
+ result[len] = '\0';
38
+ return (char *) memcpy (result, s, len);
39
+ }
40
+ /* *INDENT-ON* */
41
+ #endif
42
+
43
+ void for_all_record_sizes(const char *filename_fmt,
44
+ void (*tests)(int record_size, const char *filename,
45
+ const char *description))
46
+ {
47
+ int sizes[] = { 24, 28, 32 };
48
+ for (int i = 0; i < 3; i++) {
49
+ int size = sizes[i];
50
+
51
+ char filename[500];
52
+ snprintf(filename, 500, filename_fmt, size);
53
+
54
+ char description[14];
55
+ snprintf(description, 14, "%i bit record", size);
56
+
57
+ tests(size, filename, description);
58
+ }
59
+ }
60
+
61
+ void for_all_modes(void (*tests)(int mode, const char *description))
62
+ {
63
+ tests(MMDB_MODE_MMAP, "mmap mode");
64
+ }
65
+
66
+ const char *test_database_path(const char *filename)
67
+ {
68
+ char cwd[500];
69
+ char *UNUSED(tmp) = getcwd(cwd, 500);
70
+
71
+ char *test_db_dir;
72
+ #ifdef _WIN32
73
+ test_db_dir = "./t/maxmind-db/test-data";
74
+ #else
75
+ if (strcmp(basename(cwd), "t") == 0) {
76
+ test_db_dir = "./maxmind-db/test-data";
77
+ } else {
78
+ test_db_dir = "./t/maxmind-db/test-data";
79
+ }
80
+ #endif
81
+
82
+ char *path = malloc(500);
83
+ assert(NULL != path);
84
+
85
+ snprintf(path, 500, "%s/%s", test_db_dir, filename);
86
+
87
+ return (const char *)path;
88
+ }
89
+
90
+ const char *dup_entry_string_or_bail(MMDB_entry_data_s entry_data)
91
+ {
92
+ const char *string = strndup(entry_data.utf8_string, entry_data.data_size);
93
+ if (NULL == string) {
94
+ BAIL_OUT("strndup failed");
95
+ }
96
+
97
+ return string;
98
+ }
99
+
100
+ MMDB_s *open_ok(const char *db_file, int mode, const char *mode_desc)
101
+ {
102
+ if (0 != access(db_file, R_OK)) {
103
+ BAIL_OUT(
104
+ "could not read the specified file - %s\nIf you are in a git checkout try running 'git submodule update --init'",
105
+ db_file);
106
+ }
107
+
108
+ MMDB_s *mmdb = (MMDB_s *)calloc(1, sizeof(MMDB_s));
109
+
110
+ if (NULL == mmdb) {
111
+ BAIL_OUT("could not allocate memory for our MMDB_s struct");
112
+ }
113
+
114
+ int status = MMDB_open(db_file, mode, mmdb);
115
+
116
+ int is_ok = ok(MMDB_SUCCESS == status, "open %s status is success - %s",
117
+ db_file, mode_desc);
118
+
119
+ if (!is_ok) {
120
+ diag("open status code = %d (%s)", status, MMDB_strerror(status));
121
+ free(mmdb);
122
+ return NULL;
123
+ }
124
+
125
+ is_ok = ok(mmdb->file_size > 0,
126
+ "mmdb struct has been set for %s - %s",
127
+ db_file, mode_desc);
128
+
129
+ if (!is_ok) {
130
+ free(mmdb);
131
+ return NULL;
132
+ }
133
+
134
+ return mmdb;
135
+ }
136
+
137
+ MMDB_lookup_result_s lookup_string_ok(MMDB_s *mmdb, const char *ip,
138
+ const char *file, const char *mode_desc)
139
+ {
140
+ int gai_error, mmdb_error;
141
+ MMDB_lookup_result_s result =
142
+ MMDB_lookup_string(mmdb, ip, &gai_error, &mmdb_error);
143
+
144
+ test_lookup_errors(gai_error, mmdb_error, "MMDB_lookup_string", ip, file,
145
+ mode_desc);
146
+
147
+ return result;
148
+ }
149
+
150
+ MMDB_lookup_result_s lookup_sockaddr_ok(MMDB_s *mmdb, const char *ip,
151
+ const char *file, const char *mode_desc)
152
+ {
153
+ int ai_flags = AI_NUMERICHOST;
154
+ struct addrinfo hints = {
155
+ .ai_socktype = SOCK_STREAM
156
+ };
157
+ struct addrinfo *addresses = NULL;
158
+
159
+ if (ip[0] == ':') {
160
+ hints.ai_flags = ai_flags;
161
+ #if defined AI_V4MAPPED && !defined __FreeBSD__
162
+ hints.ai_flags |= AI_V4MAPPED;
163
+ #endif
164
+ hints.ai_family = AF_INET6;
165
+ } else {
166
+ hints.ai_flags = ai_flags;
167
+ hints.ai_family = AF_INET;
168
+ }
169
+
170
+ int gai_error = getaddrinfo(ip, NULL, &hints, &addresses);
171
+
172
+ int mmdb_error = 0;
173
+ MMDB_lookup_result_s result = { .found_entry = false };
174
+ if (gai_error == 0) {
175
+ result = MMDB_lookup_sockaddr(mmdb, addresses->ai_addr, &mmdb_error);
176
+ }
177
+ if (NULL != addresses) {
178
+ freeaddrinfo(addresses);
179
+ }
180
+
181
+ test_lookup_errors(gai_error, mmdb_error, "MMDB_lookup_sockaddr", ip, file,
182
+ mode_desc);
183
+
184
+ return result;
185
+ }
186
+
187
+ void test_lookup_errors(int gai_error, int mmdb_error,
188
+ const char *function, const char *ip,
189
+ const char *file, const char *mode_desc)
190
+ {
191
+
192
+ int is_ok = ok(0 == gai_error,
193
+ "no getaddrinfo error in call to %s for %s - %s - %s",
194
+ function, ip, file, mode_desc);
195
+
196
+ if (!is_ok) {
197
+ diag("error from call to getaddrinfo for %s - %s",
198
+ ip, gai_strerror(gai_error));
199
+ }
200
+
201
+ is_ok = ok(0 == mmdb_error,
202
+ "no MMDB error in call to %s for %s - %s - %s",
203
+ function, ip, file, mode_desc);
204
+
205
+ if (!is_ok) {
206
+ diag("MMDB error - %s", MMDB_strerror(mmdb_error));
207
+ }
208
+ }
209
+
210
+ MMDB_entry_data_s data_ok(MMDB_lookup_result_s *result, uint32_t expect_type,
211
+ const char *description, ...)
212
+ {
213
+ va_list keys;
214
+ va_start(keys, description);
215
+
216
+ MMDB_entry_data_s data;
217
+ int status = MMDB_vget_value(&result->entry, &data, keys);
218
+
219
+ va_end(keys);
220
+
221
+ if (cmp_ok(status, "==", MMDB_SUCCESS,
222
+ "no error from call to MMDB_vget_value - %s", description)) {
223
+
224
+ if (!cmp_ok(data.type, "==", expect_type,
225
+ "got the expected data type - %s", description)) {
226
+
227
+ diag(" data type value is %i but expected %i", data.type,
228
+ expect_type);
229
+ }
230
+ } else {
231
+ diag(" error from MMDB_vget_value - %s", MMDB_strerror(status));
232
+ }
233
+
234
+ return data;
235
+ }
236
+
237
+ void compare_double(double got, double expect)
238
+ {
239
+ double diff = fabs(got - expect);
240
+ int is_ok = ok(diff < 0.01, "double value was approximately %2.6f", expect);
241
+ if (!is_ok) {
242
+ diag(" got %2.6f but expected %2.6f (diff = %2.6f)",
243
+ got, expect, diff);
244
+ }
245
+ }
246
+
247
+ void compare_float(float got, float expect)
248
+ {
249
+ float diff = fabsf(got - expect);
250
+ int is_ok = ok(diff < 0.01, "float value was approximately %2.1f", expect);
251
+ if (!is_ok) {
252
+ diag(" got %2.4f but expected %2.1f (diff = %2.1f)",
253
+ got, expect, diff);
254
+ }
255
+ }
@@ -0,0 +1,69 @@
1
+ /* Some test files may require something newer */
2
+ #if !defined(_GNU_SOURCE) && !defined(_POSIX_C_SOURCE)
3
+ #define _POSIX_C_SOURCE 200112L
4
+ #endif
5
+
6
+ #if HAVE_CONFIG_H
7
+ #include <config.h>
8
+ #endif
9
+ #include <math.h>
10
+ #include <stdio.h>
11
+ #include <string.h>
12
+ #include "maxminddb.h"
13
+ #include "libtap/tap.h"
14
+
15
+ #ifdef _WIN32
16
+ #include <Winsock2.h>
17
+ #include <ws2tcpip.h>
18
+
19
+ #define R_OK 4
20
+
21
+ #else
22
+ #include <netdb.h>
23
+ #endif
24
+
25
+ #if (_MSC_VER && _MSC_VER < 1900)
26
+ /* _snprintf has security issues, but I don't think it is worth
27
+ worrying about for the unit tests. */
28
+ #define snprintf _snprintf
29
+ #endif
30
+
31
+ #ifndef MMDB_TEST_HELPER_C
32
+ #define MMDB_TEST_HELPER_C (1)
33
+
34
+ #ifdef __GNUC__
35
+ # define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
36
+ #else
37
+ # define UNUSED
38
+ #endif
39
+
40
+ #define MAX_DESCRIPTION_LENGTH 500
41
+
42
+ #ifndef strndup
43
+ extern char *strndup(const char *s, size_t n);
44
+ #endif
45
+
46
+ /* *INDENT-OFF* */
47
+ /* --prototypes automatically generated by dev-bin/regen-prototypes.pl - don't remove this comment */
48
+ extern void for_all_record_sizes(const char *filename_fmt,
49
+ void (*tests)(int record_size, const char *filename,
50
+ const char *description));
51
+ extern void for_all_modes(void (*tests)(int mode, const char *description));
52
+ extern const char *test_database_path(const char *filename);
53
+ extern const char *dup_entry_string_or_bail(MMDB_entry_data_s entry_data);
54
+ extern MMDB_s *open_ok(const char *db_file, int mode, const char *mode_desc);
55
+ extern MMDB_lookup_result_s lookup_string_ok(MMDB_s *mmdb, const char *ip,
56
+ const char *file, const char *mode_desc);
57
+ extern MMDB_lookup_result_s lookup_sockaddr_ok(MMDB_s *mmdb, const char *ip,
58
+ const char *file, const char *mode_desc);
59
+ extern void test_lookup_errors(int gai_error, int mmdb_error,
60
+ const char *function, const char *ip,
61
+ const char *file, const char *mode_desc);
62
+ extern MMDB_entry_data_s data_ok(MMDB_lookup_result_s *result, uint32_t expect_type,
63
+ const char *description, ...);
64
+ extern void compare_double(double got, double expect);
65
+ extern void compare_float(float got, float expect);
66
+ /* --prototypes end - don't remove this comment-- */
67
+ /* *INDENT-ON* */
68
+
69
+ #endif
@@ -0,0 +1,32 @@
1
+ #include "maxminddb_test_helper.h"
2
+
3
+ void run_tests(int mode, const char *mode_desc)
4
+ {
5
+ const char *filename = "MaxMind-DB-test-metadata-pointers.mmdb";
6
+ const char *path = test_database_path(filename);
7
+ MMDB_s *mmdb = open_ok(path, mode, mode_desc);
8
+ free((void *)path);
9
+
10
+ char *repeated_string = "Lots of pointers in metadata";
11
+
12
+ is(mmdb->metadata.database_type, repeated_string,
13
+ "decoded pointer database_type");
14
+
15
+ for (uint16_t i = 0; i < mmdb->metadata.description.count; i++) {
16
+ const char *language =
17
+ mmdb->metadata.description.descriptions[i]->language;
18
+ const char *description =
19
+ mmdb->metadata.description.descriptions[i]->description;
20
+ is(description, repeated_string, "%s description", language);
21
+ }
22
+
23
+ MMDB_close(mmdb);
24
+ free(mmdb);
25
+ }
26
+
27
+ int main(void)
28
+ {
29
+ plan(NO_PLAN);
30
+ for_all_modes(&run_tests);
31
+ done_testing();
32
+ }