1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/dns/dns_hosts.h"
7 #include "testing/gtest/include/gtest/gtest.h"
13 struct ExpectedHostsEntry
{
19 void PopulateExpectedHosts(const ExpectedHostsEntry
* entries
,
21 DnsHosts
* expected_hosts_out
) {
22 for (size_t i
= 0; i
< num_entries
; ++i
) {
23 DnsHostsKey
key(entries
[i
].host
, entries
[i
].family
);
24 IPAddressNumber
& ip_ref
= (*expected_hosts_out
)[key
];
25 ASSERT_TRUE(ip_ref
.empty());
26 ASSERT_TRUE(ParseIPLiteralToNumber(entries
[i
].ip
, &ip_ref
));
27 ASSERT_EQ(ip_ref
.size(),
28 (entries
[i
].family
== ADDRESS_FAMILY_IPV4
) ? 4u : 16u);
32 TEST(DnsHostsTest
, ParseHosts
) {
33 const std::string kContents
=
34 "127.0.0.1 localhost\tlocalhost.localdomain # standard\n"
36 "1.0.0.1 localhost # ignored, first hit above\n"
37 "fe00::x example company # ignored, malformed IPv6\n"
38 "1.0.0.300 company # ignored, malformed IPv4\n"
39 "1.0.0.1 # ignored, missing hostname\n"
40 "1.0.0.1\t CoMpANy # normalized to 'company' \n"
41 "::1\tlocalhost ip6-localhost ip6-loopback # comment # within a comment\n"
42 "\t fe00::0 ip6-localnet\r\n"
44 "2048::1 company example # ignored for 'example' \n"
46 "127.0.0.1 cache2 # should reuse parsed IP\n"
47 "256.0.0.0 cache3 # bogus IP should not clear parsed IP cache\n"
48 "127.0.0.1 cache4 # should still be reused\n"
52 const ExpectedHostsEntry kEntries
[] = {
53 { "localhost", ADDRESS_FAMILY_IPV4
, "127.0.0.1" },
54 { "localhost.localdomain", ADDRESS_FAMILY_IPV4
, "127.0.0.1" },
55 { "company", ADDRESS_FAMILY_IPV4
, "1.0.0.1" },
56 { "localhost", ADDRESS_FAMILY_IPV6
, "::1" },
57 { "ip6-localhost", ADDRESS_FAMILY_IPV6
, "::1" },
58 { "ip6-loopback", ADDRESS_FAMILY_IPV6
, "::1" },
59 { "ip6-localnet", ADDRESS_FAMILY_IPV6
, "fe00::0" },
60 { "company", ADDRESS_FAMILY_IPV6
, "2048::1" },
61 { "example", ADDRESS_FAMILY_IPV6
, "2048::2" },
62 { "cache1", ADDRESS_FAMILY_IPV4
, "127.0.0.1" },
63 { "cache2", ADDRESS_FAMILY_IPV4
, "127.0.0.1" },
64 { "cache4", ADDRESS_FAMILY_IPV4
, "127.0.0.1" },
65 { "cache5", ADDRESS_FAMILY_IPV4
, "127.0.0.2" },
68 DnsHosts expected_hosts
, actual_hosts
;
69 PopulateExpectedHosts(kEntries
, ARRAYSIZE_UNSAFE(kEntries
), &expected_hosts
);
70 ParseHosts(kContents
, &actual_hosts
);
71 ASSERT_EQ(expected_hosts
, actual_hosts
);
74 TEST(DnsHostsTest
, ParseHosts_CommaIsToken
) {
75 const std::string kContents
= "127.0.0.1 comma1,comma2";
77 const ExpectedHostsEntry kEntries
[] = {
78 { "comma1,comma2", ADDRESS_FAMILY_IPV4
, "127.0.0.1" },
81 DnsHosts expected_hosts
, actual_hosts
;
82 PopulateExpectedHosts(kEntries
, ARRAYSIZE_UNSAFE(kEntries
), &expected_hosts
);
83 ParseHostsWithCommaModeForTesting(
84 kContents
, &actual_hosts
, PARSE_HOSTS_COMMA_IS_TOKEN
);
85 ASSERT_EQ(expected_hosts
, actual_hosts
);
88 TEST(DnsHostsTest
, ParseHosts_CommaIsWhitespace
) {
89 std::string kContents
= "127.0.0.1 comma1,comma2";
91 const ExpectedHostsEntry kEntries
[] = {
92 { "comma1", ADDRESS_FAMILY_IPV4
, "127.0.0.1" },
93 { "comma2", ADDRESS_FAMILY_IPV4
, "127.0.0.1" },
96 DnsHosts expected_hosts
, actual_hosts
;
97 PopulateExpectedHosts(kEntries
, ARRAYSIZE_UNSAFE(kEntries
), &expected_hosts
);
98 ParseHostsWithCommaModeForTesting(
99 kContents
, &actual_hosts
, PARSE_HOSTS_COMMA_IS_WHITESPACE
);
100 ASSERT_EQ(expected_hosts
, actual_hosts
);
103 // Test that the right comma mode is used on each platform.
104 TEST(DnsHostsTest
, ParseHosts_CommaModeByPlatform
) {
105 std::string kContents
= "127.0.0.1 comma1,comma2";
107 #if defined(OS_MACOSX)
108 const ExpectedHostsEntry kEntries
[] = {
109 { "comma1", ADDRESS_FAMILY_IPV4
, "127.0.0.1" },
110 { "comma2", ADDRESS_FAMILY_IPV4
, "127.0.0.1" },
113 const ExpectedHostsEntry kEntries
[] = {
114 { "comma1,comma2", ADDRESS_FAMILY_IPV4
, "127.0.0.1" },
118 DnsHosts expected_hosts
, actual_hosts
;
119 PopulateExpectedHosts(kEntries
, ARRAYSIZE_UNSAFE(kEntries
), &expected_hosts
);
120 ParseHosts(kContents
, &actual_hosts
);
121 ASSERT_EQ(expected_hosts
, actual_hosts
);
124 TEST(DnsHostsTest
, HostsParser_Empty
) {
126 ParseHosts("", &hosts
);
127 EXPECT_EQ(0u, hosts
.size());
130 TEST(DnsHostsTest
, HostsParser_OnlyWhitespace
) {
132 ParseHosts(" ", &hosts
);
133 EXPECT_EQ(0u, hosts
.size());
136 TEST(DnsHostsTest
, HostsParser_EndsWithNothing
) {
138 ParseHosts("127.0.0.1 localhost", &hosts
);
139 EXPECT_EQ(1u, hosts
.size());
142 TEST(DnsHostsTest
, HostsParser_EndsWithWhitespace
) {
144 ParseHosts("127.0.0.1 localhost ", &hosts
);
145 EXPECT_EQ(1u, hosts
.size());
148 TEST(DnsHostsTest
, HostsParser_EndsWithComment
) {
150 ParseHosts("127.0.0.1 localhost # comment", &hosts
);
151 EXPECT_EQ(1u, hosts
.size());
154 TEST(DnsHostsTest
, HostsParser_EndsWithNewline
) {
156 ParseHosts("127.0.0.1 localhost\n", &hosts
);
157 EXPECT_EQ(1u, hosts
.size());
160 TEST(DnsHostsTest
, HostsParser_EndsWithTwoNewlines
) {
162 ParseHosts("127.0.0.1 localhost\n\n", &hosts
);
163 EXPECT_EQ(1u, hosts
.size());
166 TEST(DnsHostsTest
, HostsParser_EndsWithNewlineAndWhitespace
) {
168 ParseHosts("127.0.0.1 localhost\n ", &hosts
);
169 EXPECT_EQ(1u, hosts
.size());
172 TEST(DnsHostsTest
, HostsParser_EndsWithNewlineAndToken
) {
174 ParseHosts("127.0.0.1 localhost\ntoken", &hosts
);
175 EXPECT_EQ(1u, hosts
.size());