• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 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.
4 
5 #include "discovery/dnssd/public/dns_sd_instance.h"
6 
7 #include <vector>
8 
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
11 
12 namespace openscreen {
13 namespace discovery {
14 
TEST(DnsSdInstanceTests,InstanceLength)15 TEST(DnsSdInstanceTests, InstanceLength) {
16   EXPECT_TRUE(IsInstanceValid("instance"));
17   EXPECT_TRUE(IsInstanceValid("name"));
18   EXPECT_TRUE(IsInstanceValid(""));
19   EXPECT_TRUE(IsInstanceValid(
20       "Something63CharsLongabcdefghijklmnopqrstuvwxyz1234567890ABCDEFG"));
21 
22   EXPECT_FALSE(IsInstanceValid(
23       "Something64CharsLongabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGH"));
24 }
25 
TEST(DnsSdInstanceTests,InstanceCharacters)26 TEST(DnsSdInstanceTests, InstanceCharacters) {
27   EXPECT_TRUE(IsInstanceValid("IncludingSpecialCharacters.+ =*&<<+`~\\/"));
28   EXPECT_TRUE(IsInstanceValid(".+ =*&<<+`~\\/ "));
29 
30   EXPECT_FALSE(IsInstanceValid(std::string(1, uint8_t{0x7F})));
31   EXPECT_FALSE(IsInstanceValid(std::string("name with ") +
32                                std::string(1, uint8_t{0x7F}) +
33                                " in the middle"));
34   for (uint8_t bad_char = 0x0; bad_char <= 0x1F; bad_char++) {
35     EXPECT_FALSE(IsInstanceValid(std::string(1, bad_char)));
36     EXPECT_FALSE(IsInstanceValid(std::string("name with ") +
37                                  std::string(1, bad_char) + " in the middle"));
38   }
39 }
40 
TEST(DnsSdInstanceTests,InstanceUTF8)41 TEST(DnsSdInstanceTests, InstanceUTF8) {
42   std::vector<uint8_t> char_sets[] = {
43       {0x80},
44       {0xC0},
45       {0xC0, 0xFF},
46       {0xE0},
47       {0xE0, 0xFF},
48       {0xE0, 0x80, 0x00},
49       {0xF0},
50       {0xF0, 0x00},
51       {0xF0, 0x80, 0xFF},
52       {0xF0, 0x80, 0x80, 0x0A},
53   };
54 
55   for (const auto& set : char_sets) {
56     std::string test_string = "start";
57     for (uint8_t ch : set) {
58       test_string.append(std::string(1, ch));
59     }
60 
61     EXPECT_FALSE(IsInstanceValid(test_string));
62   }
63 }
64 
TEST(DnsSdInstanceTests,ServiceLength)65 TEST(DnsSdInstanceTests, ServiceLength) {
66   // Too short.
67   EXPECT_TRUE(IsServiceValid("_a._udp"));
68   EXPECT_FALSE(IsServiceValid("_._udp"));
69 
70   // Too long.
71   EXPECT_TRUE(IsServiceValid("_abcdefghijklmno._udp"));
72   EXPECT_FALSE(IsServiceValid("_abcdefghijklmnop._udp"));
73 }
74 
TEST(DnsSdInstanceTests,ServiceNonProtocolNameFormatting)75 TEST(DnsSdInstanceTests, ServiceNonProtocolNameFormatting) {
76   EXPECT_TRUE(IsServiceValid("_abcd._udp"));
77 
78   // Unexprected protocol string,
79   EXPECT_FALSE(IsServiceValid("_abcd._ssl"));
80   EXPECT_FALSE(IsServiceValid("_abcd._tls"));
81   EXPECT_FALSE(IsServiceValid("_abcd._ucp"));
82 
83   // Extra characters before
84   EXPECT_FALSE(IsServiceValid(" _abcd._udp"));
85   EXPECT_FALSE(IsServiceValid("a_abcd._udp"));
86   EXPECT_FALSE(IsServiceValid("-_abcd._udp"));
87 
88   // Extra characters after.
89   EXPECT_FALSE(IsServiceValid("a_abcd._udp "));
90   EXPECT_FALSE(IsServiceValid("a_abcd._udp-"));
91   EXPECT_FALSE(IsServiceValid("a_abcd._udpp"));
92   EXPECT_FALSE(IsServiceValid("a_abcd._tcp_udp"));
93 }
94 
TEST(DnsSdInstanceTests,ServiceProtocolNameFormatting)95 TEST(DnsSdInstanceTests, ServiceProtocolNameFormatting) {
96   EXPECT_TRUE(IsServiceValid("_abcd._udp"));
97 
98   // Disallowed Characters
99   EXPECT_FALSE(IsServiceValid("_ab`d._udp"));
100   EXPECT_FALSE(IsServiceValid("_a\\cd._udp"));
101   EXPECT_FALSE(IsServiceValid("_ab.d._udp"));
102 
103   // Contains no letters
104   EXPECT_FALSE(IsServiceValid("_123._udp"));
105   EXPECT_FALSE(IsServiceValid("_1-3._udp"));
106 
107   // Improperly placed hyphen.
108   EXPECT_FALSE(IsServiceValid("_-abcd._udp"));
109   EXPECT_FALSE(IsServiceValid("_abcd-._udp"));
110 
111   // Adjacent hyphens.
112   EXPECT_FALSE(IsServiceValid("_abc--d._udp"));
113   EXPECT_FALSE(IsServiceValid("_a--bcd._tcp"));
114   EXPECT_FALSE(IsServiceValid("_0a1b--c02d._udp"));
115   EXPECT_FALSE(IsServiceValid("_0a--1._udp"));
116   EXPECT_FALSE(IsServiceValid("_a--b._udp"));
117 
118   // Multiple, non-adjacent hyphens.
119   EXPECT_TRUE(IsServiceValid("_a-b-c._udp"));
120   EXPECT_TRUE(IsServiceValid("_a-1-c._udp"));
121 }
122 
TEST(DnsSdInstanceTests,DomainDotPositions)123 TEST(DnsSdInstanceTests, DomainDotPositions) {
124   EXPECT_TRUE(IsDomainValid("192.168.0.0"));
125   EXPECT_TRUE(IsDomainValid("...."));
126   EXPECT_TRUE(IsDomainValid(
127       "Something63CharsLongabcdefghijklmnopqrstuvwxyz1234567890ABCDEFG."
128       "Something63CharsLongabcdefghijklmnopqrstuvwxyz1234567890ABCDEFG"));
129 
130   EXPECT_FALSE(IsDomainValid(
131       "Something64CharsLongabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGH."
132       "Something63CharsLongabcdefghijklmnopqrstuvwxyz1234567890ABCDEFG"));
133 }
134 
TEST(DnsSdInstanceTests,DomainCharacters)135 TEST(DnsSdInstanceTests, DomainCharacters) {
136   EXPECT_TRUE(IsDomainValid("IncludingSpecialCharacters.+ =*&<<+`~\\/"));
137   EXPECT_TRUE(IsDomainValid(".+ =*&<<+`~\\/ "));
138 
139   EXPECT_FALSE(IsDomainValid(std::string(1, uint8_t{0x7F})));
140   EXPECT_FALSE(IsDomainValid(std::string("name with ") +
141                              std::string(1, uint8_t{0x7F}) + " in the middle"));
142   for (uint8_t bad_char = 0x0; bad_char <= 0x1F; bad_char++) {
143     EXPECT_FALSE(IsDomainValid(std::string(1, bad_char)));
144     EXPECT_FALSE(IsDomainValid(std::string("name with ") +
145                                std::string(1, bad_char) + " in the middle"));
146   }
147 }
148 
TEST(DnsSdInstanceTests,DomainUTF8)149 TEST(DnsSdInstanceTests, DomainUTF8) {
150   std::vector<uint8_t> char_sets[] = {
151       {0x80},
152       {0xC0},
153       {0xC0, 0xFF},
154       {0xE0},
155       {0xE0, 0xFF},
156       {0xE0, 0x80, 0x00},
157       {0xF0},
158       {0xF0, 0x00},
159       {0xF0, 0x80, 0xFF},
160       {0xF0, 0x80, 0x80, 0x0A},
161   };
162 
163   for (const auto& set : char_sets) {
164     std::string test_string = "start";
165     for (uint8_t ch : set) {
166       test_string.append(std::string(1, ch));
167     }
168 
169     EXPECT_FALSE(IsDomainValid(test_string));
170   }
171 }
172 
TEST(DnsSdInstanceTests,SubtypeCharacters)173 TEST(DnsSdInstanceTests, SubtypeCharacters) {
174   EXPECT_TRUE(IsSubtypeValid("IncludingSpecialCharacters+ =*&<<+`~\\/"));
175   EXPECT_TRUE(IsSubtypeValid("+ =*&<<+`~\\/ "));
176 
177   EXPECT_FALSE(IsSubtypeValid("foo.bar"));
178   EXPECT_FALSE(IsSubtypeValid(std::string(1, uint8_t{0x7F})));
179   EXPECT_FALSE(IsSubtypeValid(std::string("name with ") +
180                               std::string(1, uint8_t{0x7F}) +
181                               " in the middle"));
182   for (uint8_t bad_char = 0x0; bad_char <= 0x1F; bad_char++) {
183     EXPECT_FALSE(IsSubtypeValid(std::string(1, bad_char)));
184     EXPECT_FALSE(IsSubtypeValid(std::string("name with ") +
185                                 std::string(1, bad_char) + " in the middle"));
186   }
187 }
188 
TEST(DnsSdInstanceTests,SubtypeUTF8)189 TEST(DnsSdInstanceTests, SubtypeUTF8) {
190   // Sets of bytes which do not form valid UTF8 encoded chars.
191   std::vector<uint8_t> char_sets[] = {
192       {0x80},
193       {0xC0},
194       {0xC0, 0xFF},
195       {0xE0},
196       {0xE0, 0xFF},
197       {0xE0, 0x80, 0x00},
198       {0xF0},
199       {0xF0, 0x00},
200       {0xF0, 0x80, 0xFF},
201       {0xF0, 0x80, 0x80, 0x0A},
202   };
203 
204   for (const auto& set : char_sets) {
205     std::string test_string = "start";
206     for (uint8_t ch : set) {
207       test_string.append(std::string(1, ch));
208     }
209 
210     EXPECT_FALSE(IsSubtypeValid(test_string));
211   }
212 }
213 
TEST(DnsSdInstanceTests,SubtypeLength)214 TEST(DnsSdInstanceTests, SubtypeLength) {
215   std::string kCharsAlmostMaxLength =
216       "123456989012345678901234567890123456789012345678901234567890123";
217 
218   ASSERT_EQ(kCharsAlmostMaxLength.size(), size_t{63});
219   EXPECT_TRUE(IsSubtypeValid(kCharsAlmostMaxLength));
220   EXPECT_FALSE(IsSubtypeValid(kCharsAlmostMaxLength + "4"));
221 }
222 
TEST(DnsSdInstanceTests,ComparisonTests)223 TEST(DnsSdInstanceTests, ComparisonTests) {
224   DnsSdTxtRecord set_record;
225   set_record.SetValue("foo", "bar");
226 
227   DnsSdInstance kIn1("instance", "_service._tcp", "local", {}, 80);
228   DnsSdInstance kIn2("instance", "_service._tcp", "local", {}, 80);
229   DnsSdInstance kIn3("instance2", "_service._tcp", "local", {}, 80);
230   DnsSdInstance kIn4("instance", "_service2._tcp", "local", {}, 80);
231   DnsSdInstance kIn5("instance", "_service._tcp", "local2", {}, 80);
232   DnsSdInstance kIn6("instance", "_service._tcp", "local", set_record, 80);
233   DnsSdInstance kIn7("instance", "_service._tcp", "local", {}, 79);
234   DnsSdInstance kIn8("instance", "_service._tcp", "local", {}, 80, "foo");
235   DnsSdInstance kIn9("instance", "_service._tcp", "local", {}, 80, "foobar");
236   DnsSdInstance kIn10("instance", "_service._tcp", "local", {}, 80, "foo",
237                       "bar");
238 
239   EXPECT_EQ(kIn1, kIn2);
240   EXPECT_LT(kIn1, kIn3);
241   EXPECT_LT(kIn1, kIn4);
242   EXPECT_LT(kIn1, kIn5);
243   EXPECT_LT(kIn1, kIn6);
244   EXPECT_GT(kIn1, kIn7);
245   EXPECT_LT(kIn1, kIn8);
246   EXPECT_LT(kIn1, kIn9);
247   EXPECT_LT(kIn1, kIn10);
248 
249   EXPECT_LT(kIn8, kIn9);
250   EXPECT_LT(kIn8, kIn10);
251   EXPECT_LT(kIn9, kIn10);
252 }
253 
254 }  // namespace discovery
255 }  // namespace openscreen
256