1 #include "ares-test.h"
2 #include "dns-proto.h"
3
4 #include <string>
5 #include <vector>
6
7 namespace ares {
8 namespace test {
9
TEST_F(DefaultChannelTest,GetServers)10 TEST_F(DefaultChannelTest, GetServers) {
11 std::vector<std::string> servers = GetNameServers(channel_);
12 if (verbose) {
13 for (const std::string& server : servers) {
14 std::cerr << "Nameserver: " << server << std::endl;
15 }
16 }
17 }
18
TEST_F(DefaultChannelTest,GetServersFailures)19 TEST_F(DefaultChannelTest, GetServersFailures) {
20 EXPECT_EQ(ARES_SUCCESS,
21 ares_set_servers_csv(channel_, "1.2.3.4,2.3.4.5"));
22 struct ares_addr_node* servers = nullptr;
23 SetAllocFail(1);
24 EXPECT_EQ(ARES_ENOMEM, ares_get_servers(channel_, &servers));
25 SetAllocFail(2);
26 EXPECT_EQ(ARES_ENOMEM, ares_get_servers(channel_, &servers));
27 EXPECT_EQ(ARES_ENODATA, ares_get_servers(nullptr, &servers));
28 }
29
TEST_F(DefaultChannelTest,SetServers)30 TEST_F(DefaultChannelTest, SetServers) {
31 EXPECT_EQ(ARES_SUCCESS, ares_set_servers(channel_, nullptr));
32 std::vector<std::string> empty;
33 EXPECT_EQ(empty, GetNameServers(channel_));
34
35 struct ares_addr_node server1;
36 struct ares_addr_node server2;
37 server1.next = &server2;
38 server1.family = AF_INET;
39 server1.addr.addr4.s_addr = htonl(0x01020304);
40 server2.next = nullptr;
41 server2.family = AF_INET;
42 server2.addr.addr4.s_addr = htonl(0x02030405);
43 EXPECT_EQ(ARES_ENODATA, ares_set_servers(nullptr, &server1));
44
45 EXPECT_EQ(ARES_SUCCESS, ares_set_servers(channel_, &server1));
46 std::vector<std::string> expected = {"1.2.3.4", "2.3.4.5"};
47 EXPECT_EQ(expected, GetNameServers(channel_));
48 }
49
TEST_F(DefaultChannelTest,SetServersPorts)50 TEST_F(DefaultChannelTest, SetServersPorts) {
51 EXPECT_EQ(ARES_SUCCESS, ares_set_servers_ports(channel_, nullptr));
52 std::vector<std::string> empty;
53 EXPECT_EQ(empty, GetNameServers(channel_));
54
55 struct ares_addr_port_node server1;
56 struct ares_addr_port_node server2;
57 server1.next = &server2;
58 server1.family = AF_INET;
59 server1.addr.addr4.s_addr = htonl(0x01020304);
60 server1.udp_port = 111;
61 server1.tcp_port = 111;
62 server2.next = nullptr;
63 server2.family = AF_INET;
64 server2.addr.addr4.s_addr = htonl(0x02030405);
65 server2.udp_port = 0;
66 server2.tcp_port = 0;;
67 EXPECT_EQ(ARES_ENODATA, ares_set_servers_ports(nullptr, &server1));
68
69 EXPECT_EQ(ARES_SUCCESS, ares_set_servers_ports(channel_, &server1));
70 std::vector<std::string> expected = {"1.2.3.4:111", "2.3.4.5"};
71 EXPECT_EQ(expected, GetNameServers(channel_));
72 }
73
TEST_F(DefaultChannelTest,SetServersCSV)74 TEST_F(DefaultChannelTest, SetServersCSV) {
75 EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "1.2.3.4"));
76 EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "xyzzy,plugh"));
77 EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "256.1.2.3"));
78 EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "1.2.3.4.5"));
79 EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "1:2:3:4:5"));
80
81 EXPECT_EQ(ARES_SUCCESS,
82 ares_set_servers_csv(channel_, "1.2.3.4,0102:0304:0506:0708:0910:1112:1314:1516,2.3.4.5"));
83 std::vector<std::string> expected = {"1.2.3.4", "0102:0304:0506:0708:0910:1112:1314:1516", "2.3.4.5"};
84 EXPECT_EQ(expected, GetNameServers(channel_));
85
86 // Same, with spaces
87 EXPECT_EQ(ARES_EBADSTR,
88 ares_set_servers_csv(channel_, "1.2.3.4 , 0102:0304:0506:0708:0910:1112:1314:1516, 2.3.4.5"));
89
90 // Same, with ports
91 EXPECT_EQ(ARES_SUCCESS,
92 ares_set_servers_csv(channel_, "1.2.3.4:54,[0102:0304:0506:0708:0910:1112:1314:1516]:80,2.3.4.5:55"));
93 EXPECT_EQ(expected, GetNameServers(channel_));
94 EXPECT_EQ(ARES_SUCCESS,
95 ares_set_servers_ports_csv(channel_, "1.2.3.4:54,[0102:0304:0506:0708:0910:1112:1314:1516]:80,2.3.4.5:55"));
96 std::vector<std::string> expected2 = {"1.2.3.4:54", "[0102:0304:0506:0708:0910:1112:1314:1516]:80", "2.3.4.5:55"};
97 EXPECT_EQ(expected2, GetNameServers(channel_));
98
99 // Should survive duplication
100 ares_channel channel2;
101 EXPECT_EQ(ARES_SUCCESS, ares_dup(&channel2, channel_));
102 EXPECT_EQ(expected2, GetNameServers(channel2));
103 ares_destroy(channel2);
104
105 // Allocation failure cases
106 for (int fail = 1; fail <= 5; fail++) {
107 SetAllocFail(fail);
108 EXPECT_EQ(ARES_ENOMEM,
109 ares_set_servers_csv(channel_, "1.2.3.4,0102:0304:0506:0708:0910:1112:1314:1516,2.3.4.5"));
110 }
111
112 // Blank servers
113 EXPECT_EQ(ARES_SUCCESS, ares_set_servers_csv(channel_, ""));
114 std::vector<std::string> none;
115 EXPECT_EQ(none, GetNameServers(channel_));
116
117 EXPECT_EQ(ARES_EBADSTR, ares_set_servers_csv(channel_, "2.3.4.5,1.2.3.4:,3.4.5.6"));
118 EXPECT_EQ(ARES_EBADSTR, ares_set_servers_csv(channel_, "2.3.4.5,1.2.3.4:Z,3.4.5.6"));
119 }
120
TEST_F(DefaultChannelTest,TimeoutValue)121 TEST_F(DefaultChannelTest, TimeoutValue) {
122 struct timeval tinfo;
123 tinfo.tv_sec = 0;
124 tinfo.tv_usec = 0;
125 struct timeval tmax;
126 tmax.tv_sec = 0;
127 tmax.tv_usec = 10;
128 struct timeval* pt;
129
130 // No timers => get max back.
131 pt = ares_timeout(channel_, &tmax, &tinfo);
132 EXPECT_EQ(&tmax, pt);
133 EXPECT_EQ(0, pt->tv_sec);
134 EXPECT_EQ(10, pt->tv_usec);
135
136 pt = ares_timeout(channel_, nullptr, &tinfo);
137 EXPECT_EQ(nullptr, pt);
138
139 HostResult result;
140 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
141
142 // Now there's a timer running.
143 pt = ares_timeout(channel_, &tmax, &tinfo);
144 EXPECT_EQ(&tmax, pt);
145 EXPECT_EQ(0, pt->tv_sec);
146 EXPECT_EQ(10, pt->tv_usec);
147
148 tmax.tv_sec = 100;
149 pt = ares_timeout(channel_, &tmax, &tinfo);
150 EXPECT_EQ(&tinfo, pt);
151
152 pt = ares_timeout(channel_, nullptr, &tinfo);
153 EXPECT_EQ(&tinfo, pt);
154
155 Process();
156 }
157
TEST_F(LibraryTest,InetNtoP)158 TEST_F(LibraryTest, InetNtoP) {
159 struct in_addr addr;
160 addr.s_addr = htonl(0x01020304);
161 char buffer[256];
162 EXPECT_EQ(buffer, ares_inet_ntop(AF_INET, &addr, buffer, sizeof(buffer)));
163 EXPECT_EQ("1.2.3.4", std::string(buffer));
164 }
165
TEST_F(LibraryTest,Mkquery)166 TEST_F(LibraryTest, Mkquery) {
167 byte* p;
168 int len;
169 ares_mkquery("example.com", ns_c_in, ns_t_a, 0x1234, 0, &p, &len);
170 std::vector<byte> data(p, p + len);
171 ares_free_string(p);
172
173 std::string actual = PacketToString(data);
174 DNSPacket pkt;
175 pkt.set_qid(0x1234).add_question(new DNSQuestion("example.com", ns_t_a));
176 std::string expected = PacketToString(pkt.data());
177 EXPECT_EQ(expected, actual);
178 }
179
TEST_F(LibraryTest,CreateQuery)180 TEST_F(LibraryTest, CreateQuery) {
181 byte* p;
182 int len;
183 EXPECT_EQ(ARES_SUCCESS,
184 ares_create_query("exam\\@le.com", ns_c_in, ns_t_a, 0x1234, 0,
185 &p, &len, 0));
186 std::vector<byte> data(p, p + len);
187 ares_free_string(p);
188
189 std::string actual = PacketToString(data);
190 DNSPacket pkt;
191 pkt.set_qid(0x1234).add_question(new DNSQuestion("exam@le.com", ns_t_a));
192 std::string expected = PacketToString(pkt.data());
193 EXPECT_EQ(expected, actual);
194 }
195
TEST_F(LibraryTest,CreateQueryTrailingEscapedDot)196 TEST_F(LibraryTest, CreateQueryTrailingEscapedDot) {
197 byte* p;
198 int len;
199 EXPECT_EQ(ARES_SUCCESS,
200 ares_create_query("example.com\\.", ns_c_in, ns_t_a, 0x1234, 0,
201 &p, &len, 0));
202 std::vector<byte> data(p, p + len);
203 ares_free_string(p);
204
205 std::string actual = PacketToString(data);
206 EXPECT_EQ("REQ QRY Q:{'example.com\\.' IN A}", actual);
207 }
208
TEST_F(LibraryTest,CreateQueryNameTooLong)209 TEST_F(LibraryTest, CreateQueryNameTooLong) {
210 byte* p;
211 int len;
212 EXPECT_EQ(ARES_EBADNAME,
213 ares_create_query(
214 "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789."
215 "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789."
216 "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789."
217 "x1234567890123456789.y1234567890123456789.",
218 ns_c_in, ns_t_a, 0x1234, 0, &p, &len, 0));
219 }
220
TEST_F(LibraryTest,CreateQueryFailures)221 TEST_F(LibraryTest, CreateQueryFailures) {
222 byte* p;
223 int len;
224 // RC1035 has a 255 byte limit on names.
225 std::string longname;
226 for (int ii = 0; ii < 17; ii++) {
227 longname += "fedcba9876543210";
228 }
229 p = nullptr;
230 EXPECT_EQ(ARES_EBADNAME,
231 ares_create_query(longname.c_str(), ns_c_in, ns_t_a, 0x1234, 0,
232 &p, &len, 0));
233 if (p) ares_free_string(p);
234
235 SetAllocFail(1);
236
237 p = nullptr;
238 EXPECT_EQ(ARES_ENOMEM,
239 ares_create_query("example.com", ns_c_in, ns_t_a, 0x1234, 0,
240 &p, &len, 0));
241 if (p) ares_free_string(p);
242
243 // 63-char limit on a single label
244 std::string longlabel = "a.a123456789b123456789c123456789d123456789e123456789f123456789g123456789.org";
245 p = nullptr;
246 EXPECT_EQ(ARES_EBADNAME,
247 ares_create_query(longlabel.c_str(), ns_c_in, ns_t_a, 0x1234, 0,
248 &p, &len, 0));
249 if (p) ares_free_string(p);
250
251 // Empty non-terminal label
252 p = nullptr;
253 EXPECT_EQ(ARES_EBADNAME,
254 ares_create_query("example..com", ns_c_in, ns_t_a, 0x1234, 0,
255 &p, &len, 0));
256 if (p) ares_free_string(p);
257 }
258
TEST_F(LibraryTest,CreateQueryOnionDomain)259 TEST_F(LibraryTest, CreateQueryOnionDomain) {
260 byte* p;
261 int len;
262 EXPECT_EQ(ARES_ENOTFOUND,
263 ares_create_query("dontleak.onion", ns_c_in, ns_t_a, 0x1234, 0,
264 &p, &len, 0));
265 }
266
TEST_F(DefaultChannelTest,HostByNameOnionDomain)267 TEST_F(DefaultChannelTest, HostByNameOnionDomain) {
268 HostResult result;
269 ares_gethostbyname(channel_, "dontleak.onion", AF_INET, HostCallback, &result);
270 EXPECT_TRUE(result.done_);
271 EXPECT_EQ(ARES_ENOTFOUND, result.status_);
272 }
273
TEST_F(DefaultChannelTest,HostByNameFileOnionDomain)274 TEST_F(DefaultChannelTest, HostByNameFileOnionDomain) {
275 struct hostent *h;
276 EXPECT_EQ(ARES_ENOTFOUND,
277 ares_gethostbyname_file(channel_, "dontleak.onion", AF_INET, &h));
278 }
279
TEST_F(DefaultChannelTest,GetAddrinfoOnionDomain)280 TEST_F(DefaultChannelTest, GetAddrinfoOnionDomain) {
281 AddrInfoResult result;
282 struct ares_addrinfo_hints hints = {};
283 hints.ai_family = AF_UNSPEC;
284 ares_getaddrinfo(channel_, "dontleak.onion", NULL, &hints, AddrInfoCallback, &result);
285 EXPECT_TRUE(result.done_);
286 EXPECT_EQ(ARES_ENOTFOUND, result.status_);
287 }
288
289 // Interesting question: should tacking on a search domain let the query
290 // through? It seems safer to reject it because "supersecret.onion.search"
291 // still leaks information about the query to malicious resolvers.
TEST_F(DefaultChannelTest,SearchOnionDomain)292 TEST_F(DefaultChannelTest, SearchOnionDomain) {
293 SearchResult result;
294 ares_search(channel_, "dontleak.onion", ns_c_in, ns_t_a,
295 SearchCallback, &result);
296 EXPECT_TRUE(result.done_);
297 EXPECT_EQ(ARES_ENOTFOUND, result.status_);
298 }
299
TEST_F(DefaultChannelTest,SendFailure)300 TEST_F(DefaultChannelTest, SendFailure) {
301 unsigned char buf[2];
302 SearchResult result;
303 ares_send(channel_, buf, sizeof(buf), SearchCallback, &result);
304 EXPECT_TRUE(result.done_);
305 EXPECT_EQ(ARES_EBADQUERY, result.status_);
306 }
307
ExpandName(const std::vector<byte> & data,int offset,long * enclen)308 std::string ExpandName(const std::vector<byte>& data, int offset,
309 long *enclen) {
310 char *name = nullptr;
311 int rc = ares_expand_name(data.data() + offset, data.data(), data.size(),
312 &name, enclen);
313 EXPECT_EQ(ARES_SUCCESS, rc);
314 std::string result;
315 if (rc == ARES_SUCCESS) {
316 result = name;
317 } else {
318 result = "<error>";
319 }
320 ares_free_string(name);
321 return result;
322 }
323
TEST_F(LibraryTest,ExpandName)324 TEST_F(LibraryTest, ExpandName) {
325 long enclen;
326 std::vector<byte> data1 = {1, 'a', 2, 'b', 'c', 3, 'd', 'e', 'f', 0};
327 EXPECT_EQ("a.bc.def", ExpandName(data1, 0, &enclen));
328 EXPECT_EQ(data1.size(), enclen);
329
330 std::vector<byte> data2 = {0};
331 EXPECT_EQ("", ExpandName(data2, 0, &enclen));
332 EXPECT_EQ(1, enclen);
333
334 // Complete name indirection
335 std::vector<byte> data3 = {0x12, 0x23,
336 3, 'd', 'e', 'f', 0,
337 0xC0, 2};
338 EXPECT_EQ("def", ExpandName(data3, 2, &enclen));
339 EXPECT_EQ(5, enclen);
340 EXPECT_EQ("def", ExpandName(data3, 7, &enclen));
341 EXPECT_EQ(2, enclen);
342
343 // One label then indirection
344 std::vector<byte> data4 = {0x12, 0x23,
345 3, 'd', 'e', 'f', 0,
346 1, 'a', 0xC0, 2};
347 EXPECT_EQ("def", ExpandName(data4, 2, &enclen));
348 EXPECT_EQ(5, enclen);
349 EXPECT_EQ("a.def", ExpandName(data4, 7, &enclen));
350 EXPECT_EQ(4, enclen);
351
352 // Two labels then indirection
353 std::vector<byte> data5 = {0x12, 0x23,
354 3, 'd', 'e', 'f', 0,
355 1, 'a', 1, 'b', 0xC0, 2};
356 EXPECT_EQ("def", ExpandName(data5, 2, &enclen));
357 EXPECT_EQ(5, enclen);
358 EXPECT_EQ("a.b.def", ExpandName(data5, 7, &enclen));
359 EXPECT_EQ(6, enclen);
360
361 // Empty name, indirection to empty name
362 std::vector<byte> data6 = {0x12, 0x23,
363 0,
364 0xC0, 2};
365 EXPECT_EQ("", ExpandName(data6, 2, &enclen));
366 EXPECT_EQ(1, enclen);
367 EXPECT_EQ("", ExpandName(data6, 3, &enclen));
368 EXPECT_EQ(2, enclen);
369 }
370
TEST_F(LibraryTest,ExpandNameFailure)371 TEST_F(LibraryTest, ExpandNameFailure) {
372 std::vector<byte> data1 = {0x03, 'c', 'o', 'm', 0x00};
373 char *name = nullptr;
374 long enclen;
375 SetAllocFail(1);
376 EXPECT_EQ(ARES_ENOMEM,
377 ares_expand_name(data1.data(), data1.data(), data1.size(),
378 &name, &enclen));
379
380 // Empty packet
381 EXPECT_EQ(ARES_EBADNAME,
382 ares_expand_name(data1.data(), data1.data(), 0, &name, &enclen));
383
384 // Start beyond enclosing data
385 EXPECT_EQ(ARES_EBADNAME,
386 ares_expand_name(data1.data() + data1.size(), data1.data(), data1.size(),
387 &name, &enclen));
388
389 // Length beyond size of enclosing data
390 std::vector<byte> data2a = {0x13, 'c', 'o', 'm', 0x00};
391 EXPECT_EQ(ARES_EBADNAME,
392 ares_expand_name(data2a.data(), data2a.data(), data2a.size(),
393 &name, &enclen));
394 std::vector<byte> data2b = {0x1};
395 EXPECT_EQ(ARES_EBADNAME,
396 ares_expand_name(data2b.data(), data2b.data(), data2b.size(),
397 &name, &enclen));
398 std::vector<byte> data2c = {0xC0};
399 EXPECT_EQ(ARES_EBADNAME,
400 ares_expand_name(data2c.data(), data2c.data(), data2c.size(),
401 &name, &enclen));
402
403 // Indirection beyond enclosing data
404 std::vector<byte> data3a = {0xC0, 0x02};
405 EXPECT_EQ(ARES_EBADNAME,
406 ares_expand_name(data3a.data(), data3a.data(), data3a.size(),
407 &name, &enclen));
408 std::vector<byte> data3b = {0xC0, 0x0A, 'c', 'o', 'm', 0x00};
409 EXPECT_EQ(ARES_EBADNAME,
410 ares_expand_name(data3b.data(), data3b.data(), data3b.size(),
411 &name, &enclen));
412
413 // Invalid top bits in label length
414 std::vector<byte> data4 = {0x03, 'c', 'o', 'm', 0x00, 0x80, 0x00};
415 EXPECT_EQ(ARES_EBADNAME,
416 ares_expand_name(data4.data() + 5, data4.data(), data4.size(),
417 &name, &enclen));
418
419 // Label too long: 64-byte label, with invalid top 2 bits of length (01).
420 std::vector<byte> data5 = {0x40,
421 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
422 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
423 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
424 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
425 0x00};
426 EXPECT_EQ(ARES_EBADNAME,
427 ares_expand_name(data5.data(), data5.data(), data5.size(),
428 &name, &enclen)) << name;
429
430 // Incomplete indirect length
431 std::vector<byte> data6 = {0x03, 'c', 'o', 'm', 0x00, 0xC0};
432 EXPECT_EQ(ARES_EBADNAME,
433 ares_expand_name(data6.data() + 5, data6.data(), data6.size(),
434 &name, &enclen));
435
436 // Indirection loops
437 std::vector<byte> data7 = {0xC0, 0x02, 0xC0, 0x00};
438 EXPECT_EQ(ARES_EBADNAME,
439 ares_expand_name(data7.data(), data7.data(), data7.size(),
440 &name, &enclen));
441 std::vector<byte> data8 = {3, 'd', 'e', 'f', 0xC0, 0x08, 0x00, 0x00,
442 3, 'a', 'b', 'c', 0xC0, 0x00};
443 EXPECT_EQ(ARES_EBADNAME,
444 ares_expand_name(data8.data(), data8.data(), data8.size(),
445 &name, &enclen));
446 std::vector<byte> data9 = {0x12, 0x23, // start 2 bytes in
447 3, 'd', 'e', 'f', 0xC0, 0x02};
448 EXPECT_EQ(ARES_EBADNAME,
449 ares_expand_name(data9.data() + 2, data9.data(), data9.size(),
450 &name, &enclen));
451 }
452
TEST_F(LibraryTest,CreateEDNSQuery)453 TEST_F(LibraryTest, CreateEDNSQuery) {
454 byte* p;
455 int len;
456 EXPECT_EQ(ARES_SUCCESS,
457 ares_create_query("example.com", ns_c_in, ns_t_a, 0x1234, 0,
458 &p, &len, 1280));
459 std::vector<byte> data(p, p + len);
460 ares_free_string(p);
461
462 std::string actual = PacketToString(data);
463 DNSPacket pkt;
464 pkt.set_qid(0x1234).add_question(new DNSQuestion("example.com", ns_t_a))
465 .add_additional(new DNSOptRR(0, 1280));
466 std::string expected = PacketToString(pkt.data());
467 EXPECT_EQ(expected, actual);
468 }
469
TEST_F(LibraryTest,CreateRootQuery)470 TEST_F(LibraryTest, CreateRootQuery) {
471 byte* p;
472 int len;
473 ares_create_query(".", ns_c_in, ns_t_a, 0x1234, 0, &p, &len, 0);
474 std::vector<byte> data(p, p + len);
475 ares_free_string(p);
476
477 std::string actual = PacketToString(data);
478 DNSPacket pkt;
479 pkt.set_qid(0x1234).add_question(new DNSQuestion("", ns_t_a));
480 std::string expected = PacketToString(pkt.data());
481 EXPECT_EQ(expected, actual);
482 }
483
TEST_F(LibraryTest,Version)484 TEST_F(LibraryTest, Version) {
485 // Assume linked to same version
486 EXPECT_EQ(std::string(ARES_VERSION_STR),
487 std::string(ares_version(nullptr)));
488 int version;
489 ares_version(&version);
490 EXPECT_EQ(ARES_VERSION, version);
491 }
492
TEST_F(LibraryTest,Strerror)493 TEST_F(LibraryTest, Strerror) {
494 EXPECT_EQ("Successful completion",
495 std::string(ares_strerror(ARES_SUCCESS)));
496 EXPECT_EQ("DNS query cancelled",
497 std::string(ares_strerror(ARES_ECANCELLED)));
498 EXPECT_EQ("unknown",
499 std::string(ares_strerror(99)));
500 }
501
TEST_F(LibraryTest,ExpandString)502 TEST_F(LibraryTest, ExpandString) {
503 std::vector<byte> s1 = { 3, 'a', 'b', 'c'};
504 char* result = nullptr;
505 long len;
506 EXPECT_EQ(ARES_SUCCESS,
507 ares_expand_string(s1.data(), s1.data(), s1.size(),
508 (unsigned char**)&result, &len));
509 EXPECT_EQ("abc", std::string(result));
510 EXPECT_EQ(1 + 3, len); // amount of data consumed includes 1 byte len
511 ares_free_string(result);
512 result = nullptr;
513 EXPECT_EQ(ARES_EBADSTR,
514 ares_expand_string(s1.data() + 1, s1.data(), s1.size(),
515 (unsigned char**)&result, &len));
516 EXPECT_EQ(ARES_EBADSTR,
517 ares_expand_string(s1.data() + 4, s1.data(), s1.size(),
518 (unsigned char**)&result, &len));
519 SetAllocSizeFail(3 + 1);
520 EXPECT_EQ(ARES_ENOMEM,
521 ares_expand_string(s1.data(), s1.data(), s1.size(),
522 (unsigned char**)&result, &len));
523 }
524
525 } // namespace test
526 } // namespace ares
527