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,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
+ }