1c87c5fbaSopenharmony_ci/* libcoap unit tests
2c87c5fbaSopenharmony_ci *
3c87c5fbaSopenharmony_ci * Copyright (C) 2012,2015,2022-2023 Olaf Bergmann <bergmann@tzi.org>
4c87c5fbaSopenharmony_ci *
5c87c5fbaSopenharmony_ci * SPDX-License-Identifier: BSD-2-Clause
6c87c5fbaSopenharmony_ci *
7c87c5fbaSopenharmony_ci * This file is part of the CoAP library libcoap. Please see
8c87c5fbaSopenharmony_ci * README for terms of use.
9c87c5fbaSopenharmony_ci */
10c87c5fbaSopenharmony_ci
11c87c5fbaSopenharmony_ci#include "test_common.h"
12c87c5fbaSopenharmony_ci#include "test_uri.h"
13c87c5fbaSopenharmony_ci
14c87c5fbaSopenharmony_ci#include <stdio.h>
15c87c5fbaSopenharmony_ci
16c87c5fbaSopenharmony_cistatic void
17c87c5fbaSopenharmony_cit_parse_uri1(void) {
18c87c5fbaSopenharmony_ci  char teststr[] = "coap://[::1]/.well-known/core";
19c87c5fbaSopenharmony_ci
20c87c5fbaSopenharmony_ci  int result;
21c87c5fbaSopenharmony_ci  coap_uri_t uri;
22c87c5fbaSopenharmony_ci
23c87c5fbaSopenharmony_ci  result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
24c87c5fbaSopenharmony_ci  if (result == 0) {
25c87c5fbaSopenharmony_ci    CU_ASSERT(uri.host.length == 3);
26c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.host.s, "::1", 3);
27c87c5fbaSopenharmony_ci
28c87c5fbaSopenharmony_ci    CU_ASSERT(uri.port == COAP_DEFAULT_PORT);
29c87c5fbaSopenharmony_ci
30c87c5fbaSopenharmony_ci    CU_ASSERT(uri.path.length == 16);
31c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.path.s, ".well-known/core", 16);
32c87c5fbaSopenharmony_ci
33c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.length == 0);
34c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.s == NULL);
35c87c5fbaSopenharmony_ci  } else {
36c87c5fbaSopenharmony_ci    CU_FAIL("uri parser error");
37c87c5fbaSopenharmony_ci  }
38c87c5fbaSopenharmony_ci}
39c87c5fbaSopenharmony_ci
40c87c5fbaSopenharmony_cistatic void
41c87c5fbaSopenharmony_cit_parse_uri2(void) {
42c87c5fbaSopenharmony_ci  char teststr[] = "coap://[::1]:8000/.well-known/core";
43c87c5fbaSopenharmony_ci  int result;
44c87c5fbaSopenharmony_ci  coap_uri_t uri;
45c87c5fbaSopenharmony_ci
46c87c5fbaSopenharmony_ci  result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
47c87c5fbaSopenharmony_ci  if (result == 0) {
48c87c5fbaSopenharmony_ci    CU_ASSERT(uri.host.length == 3);
49c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.host.s, "::1", 3);
50c87c5fbaSopenharmony_ci
51c87c5fbaSopenharmony_ci    CU_ASSERT(uri.port == 8000);
52c87c5fbaSopenharmony_ci
53c87c5fbaSopenharmony_ci    CU_ASSERT(uri.path.length == 16);
54c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.path.s, ".well-known/core", 16);
55c87c5fbaSopenharmony_ci
56c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.length == 0);
57c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.s == NULL);
58c87c5fbaSopenharmony_ci  } else {
59c87c5fbaSopenharmony_ci    CU_FAIL("uri parser error");
60c87c5fbaSopenharmony_ci  }
61c87c5fbaSopenharmony_ci}
62c87c5fbaSopenharmony_ci
63c87c5fbaSopenharmony_cistatic void
64c87c5fbaSopenharmony_cit_parse_uri3(void) {
65c87c5fbaSopenharmony_ci  char teststr[] = "coap://localhost/?foo&bla=fasel";
66c87c5fbaSopenharmony_ci  int result;
67c87c5fbaSopenharmony_ci  coap_uri_t uri;
68c87c5fbaSopenharmony_ci
69c87c5fbaSopenharmony_ci  result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
70c87c5fbaSopenharmony_ci  if (result == 0) {
71c87c5fbaSopenharmony_ci    CU_ASSERT(uri.host.length == 9);
72c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.host.s, "localhost", 9);
73c87c5fbaSopenharmony_ci
74c87c5fbaSopenharmony_ci    CU_ASSERT(uri.port == COAP_DEFAULT_PORT);
75c87c5fbaSopenharmony_ci
76c87c5fbaSopenharmony_ci    CU_ASSERT(uri.path.length == 0);
77c87c5fbaSopenharmony_ci
78c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.length == 13);
79c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.query.s, "foo&bla=fasel", 13);
80c87c5fbaSopenharmony_ci  } else {
81c87c5fbaSopenharmony_ci    CU_FAIL("uri parser error");
82c87c5fbaSopenharmony_ci  }
83c87c5fbaSopenharmony_ci}
84c87c5fbaSopenharmony_ci
85c87c5fbaSopenharmony_cistatic void
86c87c5fbaSopenharmony_cit_parse_uri4(void) {
87c87c5fbaSopenharmony_ci  char teststr[] = "coap://:100000";
88c87c5fbaSopenharmony_ci  int result;
89c87c5fbaSopenharmony_ci  coap_uri_t uri;
90c87c5fbaSopenharmony_ci
91c87c5fbaSopenharmony_ci  result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
92c87c5fbaSopenharmony_ci  CU_ASSERT(result < 0);
93c87c5fbaSopenharmony_ci}
94c87c5fbaSopenharmony_ci
95c87c5fbaSopenharmony_cistatic void
96c87c5fbaSopenharmony_cit_parse_uri5(void) {
97c87c5fbaSopenharmony_ci  char teststr[] = "coap://foo:100000";
98c87c5fbaSopenharmony_ci  int result;
99c87c5fbaSopenharmony_ci  coap_uri_t uri;
100c87c5fbaSopenharmony_ci
101c87c5fbaSopenharmony_ci  result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
102c87c5fbaSopenharmony_ci  if (result == 0) {
103c87c5fbaSopenharmony_ci    CU_ASSERT(uri.host.length == 3);
104c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.host.s, "foo", 3);
105c87c5fbaSopenharmony_ci
106c87c5fbaSopenharmony_ci    CU_ASSERT(uri.path.length == 0);
107c87c5fbaSopenharmony_ci    CU_ASSERT(uri.path.s == NULL);
108c87c5fbaSopenharmony_ci
109c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.length == 0);
110c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.s == NULL);
111c87c5fbaSopenharmony_ci
112c87c5fbaSopenharmony_ci    CU_FAIL("invalid port not detected");
113c87c5fbaSopenharmony_ci  } else {
114c87c5fbaSopenharmony_ci    CU_PASS("detected invalid port");
115c87c5fbaSopenharmony_ci  }
116c87c5fbaSopenharmony_ci}
117c87c5fbaSopenharmony_ci
118c87c5fbaSopenharmony_cistatic void
119c87c5fbaSopenharmony_cit_parse_uri6(void) {
120c87c5fbaSopenharmony_ci  char teststr[] = "coap://134.102.218.2/.well-known/core";
121c87c5fbaSopenharmony_ci  int result;
122c87c5fbaSopenharmony_ci  coap_uri_t uri;
123c87c5fbaSopenharmony_ci
124c87c5fbaSopenharmony_ci  result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
125c87c5fbaSopenharmony_ci  if (result == 0) {
126c87c5fbaSopenharmony_ci    CU_ASSERT(uri.host.length == 13);
127c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.host.s, "134.102.218.2", 13);
128c87c5fbaSopenharmony_ci
129c87c5fbaSopenharmony_ci    CU_ASSERT(uri.port == COAP_DEFAULT_PORT);
130c87c5fbaSopenharmony_ci
131c87c5fbaSopenharmony_ci    CU_ASSERT(uri.path.length == 16);
132c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.path.s, ".well-known/core", 16);
133c87c5fbaSopenharmony_ci
134c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.length == 0);
135c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.s == NULL);
136c87c5fbaSopenharmony_ci  } else {
137c87c5fbaSopenharmony_ci    CU_FAIL("uri parser error");
138c87c5fbaSopenharmony_ci  }
139c87c5fbaSopenharmony_ci}
140c87c5fbaSopenharmony_ci
141c87c5fbaSopenharmony_cistatic void
142c87c5fbaSopenharmony_cit_parse_uri7(void) {
143c87c5fbaSopenharmony_ci  char teststr[] = "coap://foo.bar:5683/some_resource/with/multiple/segments";
144c87c5fbaSopenharmony_ci  int result;
145c87c5fbaSopenharmony_ci  coap_uri_t uri;
146c87c5fbaSopenharmony_ci  unsigned char buf[40];
147c87c5fbaSopenharmony_ci  size_t buflen = sizeof(buf);
148c87c5fbaSopenharmony_ci
149c87c5fbaSopenharmony_ci  /* The list of path segments to check against. Each segment is
150c87c5fbaSopenharmony_ci     preceded by a dummy option indicating that holds the (dummy)
151c87c5fbaSopenharmony_ci     delta value 0 and the actual segment length. */
152c87c5fbaSopenharmony_ci  const uint8_t checkbuf[] = {
153c87c5fbaSopenharmony_ci    0x0d, 0x00, 's', 'o', 'm', 'e', '_', 'r', 'e', 's', 'o', 'u', 'r', 'c', 'e',
154c87c5fbaSopenharmony_ci    0x04, 'w', 'i', 't', 'h',
155c87c5fbaSopenharmony_ci    0x08, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e',
156c87c5fbaSopenharmony_ci    0x08, 's', 'e', 'g', 'm', 'e', 'n', 't', 's'
157c87c5fbaSopenharmony_ci  };
158c87c5fbaSopenharmony_ci
159c87c5fbaSopenharmony_ci  result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
160c87c5fbaSopenharmony_ci  if (result == 0) {
161c87c5fbaSopenharmony_ci    CU_ASSERT(uri.host.length == 7);
162c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.host.s, "foo.bar", 7);
163c87c5fbaSopenharmony_ci
164c87c5fbaSopenharmony_ci    CU_ASSERT(uri.port == 5683);
165c87c5fbaSopenharmony_ci
166c87c5fbaSopenharmony_ci    CU_ASSERT(uri.path.length == 36);
167c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.path.s, "some_resource/with/multiple/segments", 36);
168c87c5fbaSopenharmony_ci
169c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.length == 0);
170c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.s == NULL);
171c87c5fbaSopenharmony_ci
172c87c5fbaSopenharmony_ci    /* check path segments */
173c87c5fbaSopenharmony_ci    result = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);
174c87c5fbaSopenharmony_ci    CU_ASSERT(result == 4);
175c87c5fbaSopenharmony_ci    CU_ASSERT(buflen == sizeof(checkbuf));
176c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(buf, checkbuf, buflen);
177c87c5fbaSopenharmony_ci  } else {
178c87c5fbaSopenharmony_ci    CU_FAIL("uri parser error");
179c87c5fbaSopenharmony_ci  }
180c87c5fbaSopenharmony_ci}
181c87c5fbaSopenharmony_ci
182c87c5fbaSopenharmony_cistatic void
183c87c5fbaSopenharmony_cit_parse_uri8(void) {
184c87c5fbaSopenharmony_ci  coap_log_t level = coap_get_log_level();
185c87c5fbaSopenharmony_ci  char teststr[] = "http://example.com/%7E%AB%13";
186c87c5fbaSopenharmony_ci  int result;
187c87c5fbaSopenharmony_ci  coap_uri_t uri;
188c87c5fbaSopenharmony_ci
189c87c5fbaSopenharmony_ci  coap_set_log_level(COAP_LOG_CRIT);
190c87c5fbaSopenharmony_ci  result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
191c87c5fbaSopenharmony_ci  coap_set_log_level(level);
192c87c5fbaSopenharmony_ci  if (result < 0) {
193c87c5fbaSopenharmony_ci    CU_PASS("detected non-coap URI");
194c87c5fbaSopenharmony_ci  } else {
195c87c5fbaSopenharmony_ci    CU_FAIL("non-coap URI not recognized");
196c87c5fbaSopenharmony_ci  }
197c87c5fbaSopenharmony_ci}
198c87c5fbaSopenharmony_ci
199c87c5fbaSopenharmony_cistatic void
200c87c5fbaSopenharmony_cit_parse_uri9(void) {
201c87c5fbaSopenharmony_ci  coap_log_t level = coap_get_log_level();
202c87c5fbaSopenharmony_ci  char teststr[] = "http://example.com/%x";
203c87c5fbaSopenharmony_ci  int result;
204c87c5fbaSopenharmony_ci  coap_uri_t uri;
205c87c5fbaSopenharmony_ci
206c87c5fbaSopenharmony_ci  coap_set_log_level(COAP_LOG_CRIT);
207c87c5fbaSopenharmony_ci  result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
208c87c5fbaSopenharmony_ci  coap_set_log_level(level);
209c87c5fbaSopenharmony_ci  if (result < 0) {
210c87c5fbaSopenharmony_ci    CU_PASS("detected non-coap URI");
211c87c5fbaSopenharmony_ci  } else {
212c87c5fbaSopenharmony_ci    CU_FAIL("non-coap URI not recognized");
213c87c5fbaSopenharmony_ci  }
214c87c5fbaSopenharmony_ci}
215c87c5fbaSopenharmony_ci
216c87c5fbaSopenharmony_cistatic void
217c87c5fbaSopenharmony_cit_parse_uri10(void) {
218c87c5fbaSopenharmony_ci  char teststr[] = "/absolute/path";
219c87c5fbaSopenharmony_ci  int result;
220c87c5fbaSopenharmony_ci  coap_uri_t uri;
221c87c5fbaSopenharmony_ci
222c87c5fbaSopenharmony_ci  result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
223c87c5fbaSopenharmony_ci  if (result == 0) {
224c87c5fbaSopenharmony_ci    CU_ASSERT(uri.host.length == 0);
225c87c5fbaSopenharmony_ci    CU_ASSERT(uri.host.s == NULL);
226c87c5fbaSopenharmony_ci
227c87c5fbaSopenharmony_ci    CU_ASSERT(uri.port == COAP_DEFAULT_PORT);
228c87c5fbaSopenharmony_ci
229c87c5fbaSopenharmony_ci    CU_ASSERT(uri.path.length == 13);
230c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.path.s, "absolute/path", 13);
231c87c5fbaSopenharmony_ci
232c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.length == 0);
233c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.s == NULL);
234c87c5fbaSopenharmony_ci  } else {
235c87c5fbaSopenharmony_ci    CU_FAIL("uri parser error");
236c87c5fbaSopenharmony_ci  }
237c87c5fbaSopenharmony_ci}
238c87c5fbaSopenharmony_ci
239c87c5fbaSopenharmony_cistatic void
240c87c5fbaSopenharmony_cit_parse_uri11(void) {
241c87c5fbaSopenharmony_ci  char teststr[] =
242c87c5fbaSopenharmony_ci      "coap://xn--18j4d.example/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF";
243c87c5fbaSopenharmony_ci  int result;
244c87c5fbaSopenharmony_ci  coap_uri_t uri;
245c87c5fbaSopenharmony_ci  unsigned char buf[40];
246c87c5fbaSopenharmony_ci  size_t buflen = sizeof(buf);
247c87c5fbaSopenharmony_ci
248c87c5fbaSopenharmony_ci  /* The list of path segments to check against. Each segment is
249c87c5fbaSopenharmony_ci     preceded by a dummy option indicating that holds the (dummy)
250c87c5fbaSopenharmony_ci     delta value 0 and the actual segment length. */
251c87c5fbaSopenharmony_ci  const uint8_t checkbuf[] = {
252c87c5fbaSopenharmony_ci    0x0d, 0x02, 0xE3, 0x81, 0x93, 0xE3, 0x82, 0x93,
253c87c5fbaSopenharmony_ci    0xE3, 0x81, 0xAB, 0xE3, 0x81, 0xA1, 0xE3, 0x81,
254c87c5fbaSopenharmony_ci    0xAF
255c87c5fbaSopenharmony_ci  };
256c87c5fbaSopenharmony_ci
257c87c5fbaSopenharmony_ci  result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
258c87c5fbaSopenharmony_ci  if (result == 0) {
259c87c5fbaSopenharmony_ci    CU_ASSERT(uri.host.length == 17);
260c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.host.s, "xn--18j4d.example", 17);
261c87c5fbaSopenharmony_ci
262c87c5fbaSopenharmony_ci    CU_ASSERT(uri.port == COAP_DEFAULT_PORT);
263c87c5fbaSopenharmony_ci
264c87c5fbaSopenharmony_ci    CU_ASSERT(uri.path.length == 45);
265c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.path.s,
266c87c5fbaSopenharmony_ci                            "%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF", 45);
267c87c5fbaSopenharmony_ci
268c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.length == 0);
269c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.s == NULL);
270c87c5fbaSopenharmony_ci
271c87c5fbaSopenharmony_ci    /* check path segments */
272c87c5fbaSopenharmony_ci    result = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);
273c87c5fbaSopenharmony_ci    CU_ASSERT(result == 1);
274c87c5fbaSopenharmony_ci    CU_ASSERT(buflen == sizeof(checkbuf));
275c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(buf, checkbuf, buflen);
276c87c5fbaSopenharmony_ci  } else {
277c87c5fbaSopenharmony_ci    CU_FAIL("uri parser error");
278c87c5fbaSopenharmony_ci  }
279c87c5fbaSopenharmony_ci}
280c87c5fbaSopenharmony_ci
281c87c5fbaSopenharmony_cistatic void
282c87c5fbaSopenharmony_cit_parse_uri12(void) {
283c87c5fbaSopenharmony_ci  char teststr[] = "coap://198.51.100.1:61616//%2F//?%2F%2F&?%26";
284c87c5fbaSopenharmony_ci  int result;
285c87c5fbaSopenharmony_ci  coap_uri_t uri;
286c87c5fbaSopenharmony_ci  unsigned char buf[40];
287c87c5fbaSopenharmony_ci  size_t buflen = sizeof(buf);
288c87c5fbaSopenharmony_ci
289c87c5fbaSopenharmony_ci  /* The list of path segments to check against. Each segment is
290c87c5fbaSopenharmony_ci     preceded by a dummy option indicating that holds the (dummy)
291c87c5fbaSopenharmony_ci     delta value 0 and the actual segment length. */
292c87c5fbaSopenharmony_ci  const uint8_t uricheckbuf[] = { 0x00, 0x01, 0x2f, 0x00, 0x00 };
293c87c5fbaSopenharmony_ci  const uint8_t querycheckbuf[] = { 0x02, 0x2f, 0x2f, 0x02, 0x3f, 0x26 };
294c87c5fbaSopenharmony_ci
295c87c5fbaSopenharmony_ci  result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
296c87c5fbaSopenharmony_ci  if (result == 0) {
297c87c5fbaSopenharmony_ci    CU_ASSERT(uri.host.length == 12);
298c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.host.s, "198.51.100.1", 12);
299c87c5fbaSopenharmony_ci
300c87c5fbaSopenharmony_ci    CU_ASSERT(uri.port == 61616);
301c87c5fbaSopenharmony_ci
302c87c5fbaSopenharmony_ci    CU_ASSERT(uri.path.length == 6);
303c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.path.s, "/%2F//", 6);
304c87c5fbaSopenharmony_ci
305c87c5fbaSopenharmony_ci    CU_ASSERT(uri.query.length == 11);
306c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(uri.query.s, "%2F%2F&?%26", 11);
307c87c5fbaSopenharmony_ci
308c87c5fbaSopenharmony_ci    /* check path segments */
309c87c5fbaSopenharmony_ci    result = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);
310c87c5fbaSopenharmony_ci    CU_ASSERT(result == 4);
311c87c5fbaSopenharmony_ci    CU_ASSERT(buflen == sizeof(uricheckbuf));
312c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(buf, uricheckbuf, buflen);
313c87c5fbaSopenharmony_ci
314c87c5fbaSopenharmony_ci    /* check query segments */
315c87c5fbaSopenharmony_ci    buflen = sizeof(buf);
316c87c5fbaSopenharmony_ci    result = coap_split_query(uri.query.s, uri.query.length, buf, &buflen);
317c87c5fbaSopenharmony_ci    CU_ASSERT(result == 2);
318c87c5fbaSopenharmony_ci    CU_ASSERT(buflen == sizeof(querycheckbuf));
319c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(buf, querycheckbuf, buflen);
320c87c5fbaSopenharmony_ci  } else {
321c87c5fbaSopenharmony_ci    CU_FAIL("uri parser error");
322c87c5fbaSopenharmony_ci  }
323c87c5fbaSopenharmony_ci}
324c87c5fbaSopenharmony_ci
325c87c5fbaSopenharmony_ci#ifdef _MSC_VER
326c87c5fbaSopenharmony_ci#  define ALIGNED(x)
327c87c5fbaSopenharmony_ci#else
328c87c5fbaSopenharmony_ci#  define ALIGNED(x) __attribute__ ((aligned (x)))
329c87c5fbaSopenharmony_ci#endif
330c87c5fbaSopenharmony_ci
331c87c5fbaSopenharmony_cistatic void
332c87c5fbaSopenharmony_cit_parse_uri13(void) {
333c87c5fbaSopenharmony_ci  uint8_t teststr[] ALIGNED(8) = {
334c87c5fbaSopenharmony_ci    0x80, 0x03, 'f',  'o',
335c87c5fbaSopenharmony_ci    'o',  0x3b, '.',  'w',  'e',  'l',  'l',  '-',
336c87c5fbaSopenharmony_ci    'k',  'n',  'o',  'w',  'n',  0x04,  'c', 'o',
337c87c5fbaSopenharmony_ci    'r',  'e'
338c87c5fbaSopenharmony_ci  };
339c87c5fbaSopenharmony_ci
340c87c5fbaSopenharmony_ci  coap_pdu_t pdu = {
341c87c5fbaSopenharmony_ci    .max_size = sizeof(teststr),
342c87c5fbaSopenharmony_ci    .e_token_length = 0,
343c87c5fbaSopenharmony_ci    .token = teststr,
344c87c5fbaSopenharmony_ci    .used_size = sizeof(teststr)
345c87c5fbaSopenharmony_ci  };
346c87c5fbaSopenharmony_ci
347c87c5fbaSopenharmony_ci  coap_string_t *uri_path = coap_get_uri_path(&pdu);
348c87c5fbaSopenharmony_ci
349c87c5fbaSopenharmony_ci  CU_ASSERT(uri_path->length == sizeof(COAP_DEFAULT_URI_WELLKNOWN)-1);
350c87c5fbaSopenharmony_ci  CU_ASSERT_NSTRING_EQUAL(uri_path->s, COAP_DEFAULT_URI_WELLKNOWN,
351c87c5fbaSopenharmony_ci                          sizeof(COAP_DEFAULT_URI_WELLKNOWN)-1);
352c87c5fbaSopenharmony_ci  coap_delete_string(uri_path);
353c87c5fbaSopenharmony_ci}
354c87c5fbaSopenharmony_ci
355c87c5fbaSopenharmony_cistatic void
356c87c5fbaSopenharmony_cit_parse_uri14(void) {
357c87c5fbaSopenharmony_ci  char teststr[] =
358c87c5fbaSopenharmony_ci      "longerthan13lessthan270=0123456789012345678901234567890123456789";
359c87c5fbaSopenharmony_ci  int result;
360c87c5fbaSopenharmony_ci
361c87c5fbaSopenharmony_ci  /* buf is large enough to hold sizeof(teststr) - 1 bytes content and
362c87c5fbaSopenharmony_ci   * 2 bytes for the option header. */
363c87c5fbaSopenharmony_ci  unsigned char buf[sizeof(teststr) + 1];
364c87c5fbaSopenharmony_ci  size_t buflen = sizeof(buf);
365c87c5fbaSopenharmony_ci
366c87c5fbaSopenharmony_ci  result = coap_split_query((unsigned char *)teststr, strlen(teststr),
367c87c5fbaSopenharmony_ci                            buf, &buflen);
368c87c5fbaSopenharmony_ci  if (result >= 0) {
369c87c5fbaSopenharmony_ci    CU_ASSERT(buf[0] == 0x0d);
370c87c5fbaSopenharmony_ci    CU_ASSERT(buf[1] == strlen(teststr) - 13);
371c87c5fbaSopenharmony_ci
372c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(buf+2, teststr, strlen(teststr));
373c87c5fbaSopenharmony_ci  } else {
374c87c5fbaSopenharmony_ci    CU_FAIL("uri parser error");
375c87c5fbaSopenharmony_ci  }
376c87c5fbaSopenharmony_ci}
377c87c5fbaSopenharmony_ci
378c87c5fbaSopenharmony_cistatic void
379c87c5fbaSopenharmony_cit_parse_uri15(void) {
380c87c5fbaSopenharmony_ci  char teststr[] =
381c87c5fbaSopenharmony_ci      "longerthan13lessthan270=0123456789012345678901234567890123456789";
382c87c5fbaSopenharmony_ci  int result;
383c87c5fbaSopenharmony_ci
384c87c5fbaSopenharmony_ci  /* buf is too small to hold sizeof(teststr) - 1 bytes content and 2
385c87c5fbaSopenharmony_ci   * bytes for the option header. */
386c87c5fbaSopenharmony_ci  unsigned char buf[sizeof(teststr) - 1];
387c87c5fbaSopenharmony_ci  size_t buflen = sizeof(buf);
388c87c5fbaSopenharmony_ci
389c87c5fbaSopenharmony_ci  result = coap_split_query((unsigned char *)teststr, strlen(teststr),
390c87c5fbaSopenharmony_ci                            buf, &buflen);
391c87c5fbaSopenharmony_ci  CU_ASSERT(result == 0);
392c87c5fbaSopenharmony_ci}
393c87c5fbaSopenharmony_ci
394c87c5fbaSopenharmony_cistatic void
395c87c5fbaSopenharmony_cit_parse_uri16(void) {
396c87c5fbaSopenharmony_ci  char teststr[] =
397c87c5fbaSopenharmony_ci      "longerthan13lessthan270=0123456789012345678901234567890123456789";
398c87c5fbaSopenharmony_ci  int result;
399c87c5fbaSopenharmony_ci
400c87c5fbaSopenharmony_ci  /* buf is too small to hold the option header. */
401c87c5fbaSopenharmony_ci  unsigned char buf[1];
402c87c5fbaSopenharmony_ci  size_t buflen = sizeof(buf);
403c87c5fbaSopenharmony_ci
404c87c5fbaSopenharmony_ci  result = coap_split_query((unsigned char *)teststr, strlen(teststr),
405c87c5fbaSopenharmony_ci                            buf, &buflen);
406c87c5fbaSopenharmony_ci  CU_ASSERT(result == 0);
407c87c5fbaSopenharmony_ci}
408c87c5fbaSopenharmony_ci
409c87c5fbaSopenharmony_cistatic void
410c87c5fbaSopenharmony_cit_parse_uri17(void) {
411c87c5fbaSopenharmony_ci  char teststr[] =
412c87c5fbaSopenharmony_ci      "thisislongerthan269="
413c87c5fbaSopenharmony_ci      "01234567890123456789012345678901234567890123456789"
414c87c5fbaSopenharmony_ci      "01234567890123456789012345678901234567890123456789"
415c87c5fbaSopenharmony_ci      "01234567890123456789012345678901234567890123456789"
416c87c5fbaSopenharmony_ci      "01234567890123456789012345678901234567890123456789"
417c87c5fbaSopenharmony_ci      "01234567890123456789012345678901234567890123456789";
418c87c5fbaSopenharmony_ci  int result;
419c87c5fbaSopenharmony_ci
420c87c5fbaSopenharmony_ci  /* buf is large enough to hold sizeof(teststr) - 1 bytes content and
421c87c5fbaSopenharmony_ci   * 3 bytes for the option header. */
422c87c5fbaSopenharmony_ci  unsigned char buf[sizeof(teststr) + 2];
423c87c5fbaSopenharmony_ci  size_t buflen = sizeof(buf);
424c87c5fbaSopenharmony_ci
425c87c5fbaSopenharmony_ci  result = coap_split_query((unsigned char *)teststr, strlen(teststr),
426c87c5fbaSopenharmony_ci                            buf, &buflen);
427c87c5fbaSopenharmony_ci  if (result >= 0) {
428c87c5fbaSopenharmony_ci    CU_ASSERT(buf[0] == 0x0e);
429c87c5fbaSopenharmony_ci    CU_ASSERT(buf[1] == (((strlen(teststr) - 269) >> 8) & 0xff));
430c87c5fbaSopenharmony_ci    CU_ASSERT(buf[2] == ((strlen(teststr) - 269) & 0xff));
431c87c5fbaSopenharmony_ci
432c87c5fbaSopenharmony_ci    CU_ASSERT_NSTRING_EQUAL(buf+3, teststr, strlen(teststr));
433c87c5fbaSopenharmony_ci  } else {
434c87c5fbaSopenharmony_ci    CU_FAIL("uri parser error");
435c87c5fbaSopenharmony_ci  }
436c87c5fbaSopenharmony_ci}
437c87c5fbaSopenharmony_ci
438c87c5fbaSopenharmony_cistatic void
439c87c5fbaSopenharmony_cit_parse_uri18(void) {
440c87c5fbaSopenharmony_ci  uint8_t token[1] = "";
441c87c5fbaSopenharmony_ci  coap_pdu_t pdu = {
442c87c5fbaSopenharmony_ci    .max_size = 0,
443c87c5fbaSopenharmony_ci    .e_token_length = 0,
444c87c5fbaSopenharmony_ci    .token = token,
445c87c5fbaSopenharmony_ci    .used_size = 0
446c87c5fbaSopenharmony_ci  };
447c87c5fbaSopenharmony_ci
448c87c5fbaSopenharmony_ci  coap_string_t *uri_path = coap_get_uri_path(&pdu);
449c87c5fbaSopenharmony_ci
450c87c5fbaSopenharmony_ci  CU_ASSERT(uri_path->length == 0);
451c87c5fbaSopenharmony_ci#if 0
452c87c5fbaSopenharmony_ci  /* Currently this is not the case - Issue #167 */
453c87c5fbaSopenharmony_ci  /* strings are stored with terminating zero */
454c87c5fbaSopenharmony_ci  CU_ASSERT_NSTRING_EQUAL(uri_path->s, "", 1);
455c87c5fbaSopenharmony_ci#endif
456c87c5fbaSopenharmony_ci  coap_delete_string(uri_path);
457c87c5fbaSopenharmony_ci}
458c87c5fbaSopenharmony_ci
459c87c5fbaSopenharmony_cistatic void
460c87c5fbaSopenharmony_cit_parse_uri19(void) {
461c87c5fbaSopenharmony_ci  uint8_t teststr[] ALIGNED(8) = {
462c87c5fbaSopenharmony_ci    0xb3, 'f', 'o', 'o',
463c87c5fbaSopenharmony_ci    0x00                  /* "foo/" as Uri-Path options */
464c87c5fbaSopenharmony_ci  };
465c87c5fbaSopenharmony_ci
466c87c5fbaSopenharmony_ci  coap_pdu_t pdu = {
467c87c5fbaSopenharmony_ci    .max_size = sizeof(teststr),
468c87c5fbaSopenharmony_ci    .e_token_length = 0,
469c87c5fbaSopenharmony_ci    .token = teststr,
470c87c5fbaSopenharmony_ci    .used_size = sizeof(teststr)
471c87c5fbaSopenharmony_ci  };
472c87c5fbaSopenharmony_ci
473c87c5fbaSopenharmony_ci  coap_string_t *uri_path = coap_get_uri_path(&pdu);
474c87c5fbaSopenharmony_ci
475c87c5fbaSopenharmony_ci  CU_ASSERT(uri_path->length == 4);
476c87c5fbaSopenharmony_ci  CU_ASSERT_NSTRING_EQUAL(uri_path->s, "foo/", 4);
477c87c5fbaSopenharmony_ci  coap_delete_string(uri_path);
478c87c5fbaSopenharmony_ci}
479c87c5fbaSopenharmony_ci
480c87c5fbaSopenharmony_cistatic void
481c87c5fbaSopenharmony_cit_parse_uri20(void) {
482c87c5fbaSopenharmony_ci  uint8_t teststr[] ALIGNED(8) = {
483c87c5fbaSopenharmony_ci    0xb0, 0x00                  /* "//" as Uri-Path options */
484c87c5fbaSopenharmony_ci  };
485c87c5fbaSopenharmony_ci
486c87c5fbaSopenharmony_ci  coap_pdu_t pdu = {
487c87c5fbaSopenharmony_ci    .max_size = sizeof(teststr),
488c87c5fbaSopenharmony_ci    .e_token_length = 0,
489c87c5fbaSopenharmony_ci    .token = teststr,
490c87c5fbaSopenharmony_ci    .used_size = sizeof(teststr)
491c87c5fbaSopenharmony_ci  };
492c87c5fbaSopenharmony_ci
493c87c5fbaSopenharmony_ci  coap_string_t *uri_path = coap_get_uri_path(&pdu);
494c87c5fbaSopenharmony_ci
495c87c5fbaSopenharmony_ci  /* The leading '/' is stripped hence only one '/' remains. */
496c87c5fbaSopenharmony_ci  CU_ASSERT(uri_path->length == 1);
497c87c5fbaSopenharmony_ci  CU_ASSERT_NSTRING_EQUAL(uri_path->s, "/", 1);
498c87c5fbaSopenharmony_ci  coap_delete_string(uri_path);
499c87c5fbaSopenharmony_ci}
500c87c5fbaSopenharmony_ci
501c87c5fbaSopenharmony_cistatic void
502c87c5fbaSopenharmony_cit_parse_uri21(void) {
503c87c5fbaSopenharmony_ci  uint8_t teststr[] ALIGNED(8) = {
504c87c5fbaSopenharmony_ci    0xb0, 0x03, 'f', 'o', 'o'   /* "//foo" as Uri-Path options */
505c87c5fbaSopenharmony_ci  };
506c87c5fbaSopenharmony_ci
507c87c5fbaSopenharmony_ci  coap_pdu_t pdu = {
508c87c5fbaSopenharmony_ci    .max_size = sizeof(teststr),
509c87c5fbaSopenharmony_ci    .e_token_length = 0,
510c87c5fbaSopenharmony_ci    .token = teststr,
511c87c5fbaSopenharmony_ci    .used_size = sizeof(teststr)
512c87c5fbaSopenharmony_ci  };
513c87c5fbaSopenharmony_ci
514c87c5fbaSopenharmony_ci  coap_string_t *uri_path = coap_get_uri_path(&pdu);
515c87c5fbaSopenharmony_ci
516c87c5fbaSopenharmony_ci  /* The leading '/' is stripped hence only one '/' remains. */
517c87c5fbaSopenharmony_ci  CU_ASSERT(uri_path->length == 4);
518c87c5fbaSopenharmony_ci  CU_ASSERT_NSTRING_EQUAL(uri_path->s, "/foo", 4);
519c87c5fbaSopenharmony_ci  coap_delete_string(uri_path);
520c87c5fbaSopenharmony_ci}
521c87c5fbaSopenharmony_ci
522c87c5fbaSopenharmony_cistatic void
523c87c5fbaSopenharmony_cit_parse_uri22(void) {
524c87c5fbaSopenharmony_ci  uint8_t teststr[] ALIGNED(8) = {
525c87c5fbaSopenharmony_ci    /* characters that are not percent-encoded in a path segment */
526c87c5fbaSopenharmony_ci    0xba, '-', '.', '_', '~', '!', '$', '&', '\'', '(', ')',
527c87c5fbaSopenharmony_ci    0x05, '*', '+', ',', ';', '='
528c87c5fbaSopenharmony_ci  };
529c87c5fbaSopenharmony_ci
530c87c5fbaSopenharmony_ci  coap_pdu_t pdu = {
531c87c5fbaSopenharmony_ci    .max_size = sizeof(teststr),
532c87c5fbaSopenharmony_ci    .e_token_length = 0,
533c87c5fbaSopenharmony_ci    .token = teststr,
534c87c5fbaSopenharmony_ci    .used_size = sizeof(teststr)
535c87c5fbaSopenharmony_ci  };
536c87c5fbaSopenharmony_ci
537c87c5fbaSopenharmony_ci  coap_string_t *uri_path = coap_get_uri_path(&pdu);
538c87c5fbaSopenharmony_ci
539c87c5fbaSopenharmony_ci  CU_ASSERT(uri_path->length == 16);
540c87c5fbaSopenharmony_ci  CU_ASSERT_NSTRING_EQUAL(uri_path->s, "-._~!$&'()/*+,;=", 16);
541c87c5fbaSopenharmony_ci  coap_delete_string(uri_path);
542c87c5fbaSopenharmony_ci}
543c87c5fbaSopenharmony_ci
544c87c5fbaSopenharmony_cistatic void
545c87c5fbaSopenharmony_cit_parse_uri23(void) {
546c87c5fbaSopenharmony_ci  uint8_t teststr[] ALIGNED(8) = {
547c87c5fbaSopenharmony_ci    /* characters that must be percent-encoded in a path segment */
548c87c5fbaSopenharmony_ci    0xb5, '%', ' ', '#', '[', ']'
549c87c5fbaSopenharmony_ci  };
550c87c5fbaSopenharmony_ci
551c87c5fbaSopenharmony_ci  coap_pdu_t pdu = {
552c87c5fbaSopenharmony_ci    .max_size = sizeof(teststr),
553c87c5fbaSopenharmony_ci    .e_token_length = 0,
554c87c5fbaSopenharmony_ci    .token = teststr,
555c87c5fbaSopenharmony_ci    .used_size = sizeof(teststr)
556c87c5fbaSopenharmony_ci  };
557c87c5fbaSopenharmony_ci
558c87c5fbaSopenharmony_ci  coap_string_t *uri_path = coap_get_uri_path(&pdu);
559c87c5fbaSopenharmony_ci
560c87c5fbaSopenharmony_ci  CU_ASSERT(uri_path->length == 15);
561c87c5fbaSopenharmony_ci  CU_ASSERT_NSTRING_EQUAL(uri_path->s, "%25%20%23%5B%5D", 15);
562c87c5fbaSopenharmony_ci  coap_delete_string(uri_path);
563c87c5fbaSopenharmony_ci}
564c87c5fbaSopenharmony_ci
565c87c5fbaSopenharmony_ci/*
566c87c5fbaSopenharmony_ci * To test Issue #212 which reads off the end of the input buffer when looking
567c87c5fbaSopenharmony_ci * for . or .. in the path.
568c87c5fbaSopenharmony_ci * Credit to OSS-Fuzz for finding this, work done by Bhargava Shastry
569c87c5fbaSopenharmony_ci */
570c87c5fbaSopenharmony_cistatic void
571c87c5fbaSopenharmony_cit_parse_uri24(void) {
572c87c5fbaSopenharmony_ci  /* coap://\206cap:// */
573c87c5fbaSopenharmony_ci  uint8_t teststr[] = { 0x63, 0x6f, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x86, 0x63, 0x6f, 0x61, 0x70, 0x3a, 0x2f, 0x2f };
574c87c5fbaSopenharmony_ci  int result;
575c87c5fbaSopenharmony_ci  unsigned char buf[40];
576c87c5fbaSopenharmony_ci  size_t buflen = sizeof(buf);
577c87c5fbaSopenharmony_ci
578c87c5fbaSopenharmony_ci  result = coap_split_path(teststr, sizeof(teststr), buf, &buflen);
579c87c5fbaSopenharmony_ci  CU_ASSERT(result == 5);
580c87c5fbaSopenharmony_ci  CU_ASSERT(buflen == 16);
581c87c5fbaSopenharmony_ci}
582c87c5fbaSopenharmony_ci
583c87c5fbaSopenharmony_ci
584c87c5fbaSopenharmony_ciCU_pSuite
585c87c5fbaSopenharmony_cit_init_uri_tests(void) {
586c87c5fbaSopenharmony_ci  CU_pSuite suite;
587c87c5fbaSopenharmony_ci
588c87c5fbaSopenharmony_ci  suite = CU_add_suite("uri parser", NULL, NULL);
589c87c5fbaSopenharmony_ci  if (!suite) {                        /* signal error */
590c87c5fbaSopenharmony_ci    fprintf(stderr, "W: cannot add uri parser test suite (%s)\n",
591c87c5fbaSopenharmony_ci            CU_get_error_msg());
592c87c5fbaSopenharmony_ci
593c87c5fbaSopenharmony_ci    return NULL;
594c87c5fbaSopenharmony_ci  }
595c87c5fbaSopenharmony_ci
596c87c5fbaSopenharmony_ci#define URI_TEST(s,t)                                                      \
597c87c5fbaSopenharmony_ci  if (!CU_ADD_TEST(s,t)) {                                              \
598c87c5fbaSopenharmony_ci    fprintf(stderr, "W: cannot add uri parser test (%s)\n",              \
599c87c5fbaSopenharmony_ci            CU_get_error_msg());                                      \
600c87c5fbaSopenharmony_ci  }
601c87c5fbaSopenharmony_ci
602c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri1);
603c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri2);
604c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri3);
605c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri4);
606c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri5);
607c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri6);
608c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri7);
609c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri8);
610c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri9);
611c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri10);
612c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri11);
613c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri12);
614c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri13);
615c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri14);
616c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri15);
617c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri16);
618c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri17);
619c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri18);
620c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri19);
621c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri20);
622c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri21);
623c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri22);
624c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri23);
625c87c5fbaSopenharmony_ci  URI_TEST(suite, t_parse_uri24);
626c87c5fbaSopenharmony_ci
627c87c5fbaSopenharmony_ci  return suite;
628c87c5fbaSopenharmony_ci}
629