1 // Copyright 2018 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 "gtest/gtest.h"
6 #include "osp/msgs/osp_messages.h"
7
8 using openscreen::msgs::CborEncodeBuffer;
9 using openscreen::msgs::HttpHeader;
10 using openscreen::msgs::PresentationConnectionMessage;
11 using openscreen::msgs::PresentationStartRequest;
12 using openscreen::msgs::PresentationUrlAvailabilityRequest;
13
14 namespace openscreen {
15 namespace osp {
16
17 // TODO(btolsch): This is in the current (draft) spec, but should we actually
18 // allow this?
TEST(PresentationMessagesTest,EncodeRequestZeroUrls)19 TEST(PresentationMessagesTest, EncodeRequestZeroUrls) {
20 uint8_t buffer[256];
21 std::vector<std::string> urls;
22 ssize_t bytes_out = EncodePresentationUrlAvailabilityRequest(
23 PresentationUrlAvailabilityRequest{3, urls}, buffer, sizeof(buffer));
24 ASSERT_LE(bytes_out, static_cast<ssize_t>(sizeof(buffer)));
25 ASSERT_GT(bytes_out, 0);
26
27 PresentationUrlAvailabilityRequest decoded_request;
28 ssize_t bytes_read = DecodePresentationUrlAvailabilityRequest(
29 buffer, bytes_out, &decoded_request);
30 ASSERT_EQ(bytes_read, bytes_out);
31 EXPECT_EQ(3u, decoded_request.request_id);
32 EXPECT_EQ(urls, decoded_request.urls);
33 }
34
TEST(PresentationMessagesTest,EncodeRequestOneUrl)35 TEST(PresentationMessagesTest, EncodeRequestOneUrl) {
36 uint8_t buffer[256];
37 std::vector<std::string> urls{"https://example.com/receiver.html"};
38 ssize_t bytes_out = EncodePresentationUrlAvailabilityRequest(
39 PresentationUrlAvailabilityRequest{7, urls}, buffer, sizeof(buffer));
40 ASSERT_LE(bytes_out, static_cast<ssize_t>(sizeof(buffer)));
41 ASSERT_GT(bytes_out, 0);
42
43 PresentationUrlAvailabilityRequest decoded_request;
44 ssize_t bytes_read = DecodePresentationUrlAvailabilityRequest(
45 buffer, bytes_out, &decoded_request);
46 ASSERT_EQ(bytes_read, bytes_out);
47 EXPECT_EQ(7u, decoded_request.request_id);
48 EXPECT_EQ(urls, decoded_request.urls);
49 }
50
TEST(PresentationMessagesTest,EncodeRequestMultipleUrls)51 TEST(PresentationMessagesTest, EncodeRequestMultipleUrls) {
52 uint8_t buffer[256];
53 std::vector<std::string> urls{"https://example.com/receiver.html",
54 "https://openscreen.org/demo_receiver.html",
55 "https://turt.le/asdfXCV"};
56 ssize_t bytes_out = EncodePresentationUrlAvailabilityRequest(
57 PresentationUrlAvailabilityRequest{7, urls}, buffer, sizeof(buffer));
58 ASSERT_LE(bytes_out, static_cast<ssize_t>(sizeof(buffer)));
59 ASSERT_GT(bytes_out, 0);
60
61 PresentationUrlAvailabilityRequest decoded_request;
62 ssize_t bytes_read = DecodePresentationUrlAvailabilityRequest(
63 buffer, bytes_out, &decoded_request);
64 ASSERT_EQ(bytes_read, bytes_out);
65 EXPECT_EQ(7u, decoded_request.request_id);
66 EXPECT_EQ(urls, decoded_request.urls);
67 }
68
TEST(PresentationMessagesTest,EncodeWouldOverflow)69 TEST(PresentationMessagesTest, EncodeWouldOverflow) {
70 uint8_t buffer[40];
71 std::vector<std::string> urls{"https://example.com/receiver.html"};
72 ssize_t bytes_out = EncodePresentationUrlAvailabilityRequest(
73 PresentationUrlAvailabilityRequest{7, urls}, buffer, sizeof(buffer));
74 ASSERT_GT(bytes_out, static_cast<ssize_t>(sizeof(buffer)));
75 }
76
77 // TODO(btolsch): Expand invalid utf8 testing to good/bad files and fuzzing.
TEST(PresentationMessagesTest,EncodeInvalidUtf8)78 TEST(PresentationMessagesTest, EncodeInvalidUtf8) {
79 uint8_t buffer[256];
80 std::vector<std::string> urls{"\xc0"};
81 ssize_t bytes_out = EncodePresentationUrlAvailabilityRequest(
82 PresentationUrlAvailabilityRequest{7, urls}, buffer, sizeof(buffer));
83 ASSERT_GT(0, bytes_out);
84 }
85
TEST(PresentationMessagesTest,DecodeInvalidUtf8)86 TEST(PresentationMessagesTest, DecodeInvalidUtf8) {
87 uint8_t buffer[256];
88 std::vector<std::string> urls{"https://example.com/receiver.html"};
89 ssize_t bytes_out = EncodePresentationUrlAvailabilityRequest(
90 PresentationUrlAvailabilityRequest{7, urls}, buffer, sizeof(buffer));
91 ASSERT_LE(bytes_out, static_cast<ssize_t>(sizeof(buffer)));
92 ASSERT_GT(bytes_out, 0);
93 // Manually change a character in the url string to be non-utf8.
94 buffer[30] = 0xc0;
95
96 PresentationUrlAvailabilityRequest decoded_request;
97 ssize_t bytes_read = DecodePresentationUrlAvailabilityRequest(
98 buffer, bytes_out, &decoded_request);
99 ASSERT_GT(0, bytes_read);
100 }
101
TEST(PresentationMessagesTest,InitiationRequest)102 TEST(PresentationMessagesTest, InitiationRequest) {
103 uint8_t buffer[256];
104 const std::string kPresentationId = "lksdjfloiqwerlkjasdlfq";
105 const std::string kPresentationUrl = "https://example.com/receiver.html";
106 std::vector<HttpHeader> headers;
107 ssize_t bytes_out = EncodePresentationStartRequest(
108 PresentationStartRequest{13, kPresentationId, kPresentationUrl, headers},
109 buffer, sizeof(buffer));
110 ASSERT_LE(bytes_out, static_cast<ssize_t>(sizeof(buffer)));
111 ASSERT_GT(bytes_out, 0);
112
113 PresentationStartRequest decoded_request;
114 ssize_t bytes_read =
115 DecodePresentationStartRequest(buffer, bytes_out, &decoded_request);
116 ASSERT_EQ(bytes_read, bytes_out);
117 EXPECT_EQ(13u, decoded_request.request_id);
118 EXPECT_EQ(kPresentationId, decoded_request.presentation_id);
119 EXPECT_EQ(kPresentationUrl, decoded_request.url);
120 EXPECT_EQ(0, (int)decoded_request.headers.size());
121 }
122
TEST(PresentationMessagesTest,InitiationRequestWithoutOptional)123 TEST(PresentationMessagesTest, InitiationRequestWithoutOptional) {
124 uint8_t buffer[256];
125 const std::string kPresentationId = "lksdjfloiqwerlkjasdlfq";
126 const std::string kPresentationUrl = "https://example.com/receiver.html";
127 std::vector<HttpHeader> headers;
128 ssize_t bytes_out = EncodePresentationStartRequest(
129 PresentationStartRequest{13, kPresentationId, kPresentationUrl, headers},
130 buffer, sizeof(buffer));
131 ASSERT_LE(bytes_out, static_cast<ssize_t>(sizeof(buffer)));
132 ASSERT_GT(bytes_out, 0);
133
134 PresentationStartRequest decoded_request;
135 ssize_t bytes_read =
136 DecodePresentationStartRequest(buffer, bytes_out, &decoded_request);
137 ASSERT_EQ(bytes_read, bytes_out);
138 EXPECT_EQ(13u, decoded_request.request_id);
139 EXPECT_EQ(kPresentationId, decoded_request.presentation_id);
140 EXPECT_EQ(kPresentationUrl, decoded_request.url);
141 EXPECT_EQ(0, (int)decoded_request.headers.size());
142 }
143
TEST(PresentationMessagesTest,EncodeConnectionMessageString)144 TEST(PresentationMessagesTest, EncodeConnectionMessageString) {
145 uint8_t buffer[256];
146 PresentationConnectionMessage message;
147 message.connection_id = 1234;
148 message.message.which =
149 PresentationConnectionMessage::Message::Which::kString;
150 new (&message.message.str) std::string("test message as a string");
151 ssize_t bytes_out =
152 EncodePresentationConnectionMessage(message, buffer, sizeof(buffer));
153 ASSERT_LE(bytes_out, static_cast<ssize_t>(sizeof(buffer)));
154 ASSERT_GT(bytes_out, 0);
155
156 PresentationConnectionMessage decoded_message;
157 ssize_t bytes_read =
158 DecodePresentationConnectionMessage(buffer, bytes_out, &decoded_message);
159 ASSERT_GT(bytes_read, 0);
160 EXPECT_EQ(bytes_read, bytes_out);
161 EXPECT_EQ(message.connection_id, decoded_message.connection_id);
162 ASSERT_EQ(message.message.which, decoded_message.message.which);
163 EXPECT_EQ(message.message.str, decoded_message.message.str);
164 }
165
TEST(PresentationMessagesTest,EncodeConnectionMessageBytes)166 TEST(PresentationMessagesTest, EncodeConnectionMessageBytes) {
167 uint8_t buffer[256];
168 PresentationConnectionMessage message;
169 message.connection_id = 1234;
170 message.message.which = PresentationConnectionMessage::Message::Which::kBytes;
171 new (&message.message.bytes)
172 std::vector<uint8_t>{0, 1, 2, 3, 255, 254, 253, 86, 71, 0, 0, 1, 0, 2};
173 ssize_t bytes_out =
174 EncodePresentationConnectionMessage(message, buffer, sizeof(buffer));
175 ASSERT_LE(bytes_out, static_cast<ssize_t>(sizeof(buffer)));
176 ASSERT_GT(bytes_out, 0);
177
178 PresentationConnectionMessage decoded_message;
179 ssize_t bytes_read =
180 DecodePresentationConnectionMessage(buffer, bytes_out, &decoded_message);
181 ASSERT_GT(bytes_read, 0);
182 EXPECT_EQ(bytes_read, bytes_out);
183 EXPECT_EQ(message.connection_id, decoded_message.connection_id);
184 ASSERT_EQ(message.message.which, decoded_message.message.which);
185 EXPECT_EQ(message.message.bytes, decoded_message.message.bytes);
186 }
187
TEST(PresentationMessagesTest,CborEncodeBufferSmall)188 TEST(PresentationMessagesTest, CborEncodeBufferSmall) {
189 std::vector<std::string> urls{"https://example.com/receiver.html"};
190 PresentationUrlAvailabilityRequest request{7, urls};
191 CborEncodeBuffer buffer;
192 ASSERT_TRUE(EncodePresentationUrlAvailabilityRequest(request, &buffer));
193 EXPECT_LT(buffer.size(), CborEncodeBuffer::kDefaultInitialEncodeBufferSize);
194
195 PresentationUrlAvailabilityRequest decoded_request;
196 size_t bytes_read = DecodePresentationUrlAvailabilityRequest(
197 buffer.data() + 1, buffer.size() - 1, &decoded_request);
198 EXPECT_EQ(bytes_read, buffer.size() - 1);
199 EXPECT_EQ(request.request_id, decoded_request.request_id);
200 EXPECT_EQ(request.urls, decoded_request.urls);
201 }
202
TEST(PresentationMessagesTest,CborEncodeBufferMedium)203 TEST(PresentationMessagesTest, CborEncodeBufferMedium) {
204 std::string url = "https://example.com/receiver.html";
205 std::vector<std::string> urls{};
206 for (int i = 0; i < 100; ++i) {
207 urls.push_back(url);
208 }
209 PresentationUrlAvailabilityRequest request{7, urls};
210 CborEncodeBuffer buffer;
211 ASSERT_TRUE(EncodePresentationUrlAvailabilityRequest(request, &buffer));
212 EXPECT_GT(buffer.size(), CborEncodeBuffer::kDefaultInitialEncodeBufferSize);
213
214 PresentationUrlAvailabilityRequest decoded_request;
215 ssize_t bytes_read = DecodePresentationUrlAvailabilityRequest(
216 buffer.data() + 1, buffer.size() - 1, &decoded_request);
217 ASSERT_GT(bytes_read, 0);
218 EXPECT_EQ(static_cast<size_t>(bytes_read), buffer.size() - 1);
219 EXPECT_EQ(request.request_id, decoded_request.request_id);
220 EXPECT_EQ(request.urls, decoded_request.urls);
221 }
222
TEST(PresentationMessagesTest,CborEncodeBufferTooLarge)223 TEST(PresentationMessagesTest, CborEncodeBufferTooLarge) {
224 std::vector<std::string> urls{"https://example.com/receiver.html"};
225 PresentationUrlAvailabilityRequest request{7, urls};
226 CborEncodeBuffer buffer{10, 30};
227 ASSERT_FALSE(EncodePresentationUrlAvailabilityRequest(request, &buffer));
228 }
229
230 } // namespace osp
231 } // namespace openscreen
232