Skip to content
File

Blob: src/workerd/api/util-test.c++

6.2 KB
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5#include "util.h"
6 
7#include <kj/test.h>
8 
9namespace workerd::api {
10namespace {
11 
12void expectRedacted(kj::StringPtr input, kj::StringPtr expected) {
13 KJ_EXPECT(redactUrl(input) == expected, redactUrl(input), expected);
14}
15void expectUnredacted(kj::StringPtr input) {
16 KJ_EXPECT(redactUrl(input) == input, redactUrl(input), input);
17}
18 
19void expectContentTypeParameter(kj::StringPtr input, kj::StringPtr param, kj::StringPtr expected) {
20 auto value = KJ_ASSERT_NONNULL(readContentTypeParameter(input, param));
21 KJ_EXPECT(value == expected);
22}
23 
24KJ_TEST("redactUrl can detect hex ids") {
25 // no id:
26 expectUnredacted(""_kj);
27 expectUnredacted("https://domain/path?a=1&b=2"_kj);
28 
29 expectRedacted(
30 "https://domain/0123456789abcdef0123456789abcdef/x"_kj, "https://domain/REDACTED/x"_kj);
31 expectRedacted(
32 "https://domain/0123456789abcdef-0123456789abcdef/x"_kj, "https://domain/REDACTED/x"_kj);
33 
34 // not long enough:
35 expectUnredacted("https://domain/0123456789abcdef0123456789abcde/x"_kj);
36 expectUnredacted("https://domain/0123456789-abcdef-0123456789-abcde/x"_kj);
37 expectUnredacted("https://domain/0123456789ABCDEF0123456789ABCDE/x"_kj);
38 expectUnredacted("https://domain/0123456789_ABCDEF_0123456789_ABCDE/x"_kj);
39 
40 // contains non-hex character:
41 expectUnredacted("https://domain/0123456789abcdef0123456789abcdefg/x"_kj);
42}
43 
44KJ_TEST("redactUrl can detect base64 ids") {
45 expectRedacted("https://domain/01234567890123456azAZ/x"_kj, "https://domain/REDACTED/x"_kj);
46 
47 // not long enough:
48 expectUnredacted("https://domain/0123456789012345azAZ/x"_kj);
49 
50 // not enough lowercase:
51 expectUnredacted("https://domain/012345678901234567zAZ/x"_kj);
52 
53 // not enough uppercase:
54 expectUnredacted("https://domain/012345678901234567azZ/x"_kj);
55 
56 // not enough digits:
57 expectUnredacted("https://domain/IThinkIShallNeverSee0/x"_kj);
58}
59 
60KJ_TEST("readContentTypeParameter can fetch boundary parameter") {
61 
62 // normal
63 expectContentTypeParameter(
64 "multipart/form-data; boundary=\"__boundary__\""_kj, "boundary"_kj, "__boundary__"_kj);
65 
66 // multiple params
67 expectContentTypeParameter("multipart/form-data; charset=utf-8; boundary=\"__boundary__\""_kj,
68 "boundary"_kj, "__boundary__"_kj);
69 
70 // param name inside value of other param
71 expectContentTypeParameter(
72 "multipart/form-data; charset=\"boundary=;\"; boundary=\"__boundary__\""_kj, "boundary"_kj,
73 "__boundary__"_kj);
74 
75 // ensure param is not found
76 KJ_ASSERT(readContentTypeParameter(
77 "multipart/form-data; charset=\"boundary=;\"; boundary=\"__boundary__\""_kj,
78 "boundary1"_kj) == kj::none);
79 
80 // no quotes
81 expectContentTypeParameter(
82 "multipart/form-data; charset=\"boundary=;\"; boundary=__boundary__"_kj, "boundary"_kj,
83 "__boundary__"_kj);
84 
85 // attribute names are case-insensitive, but values are not
86 expectContentTypeParameter(
87 "multipart/form-data; charset=\"boundary=;\"; boundary=__Boundary__"_kj, "Boundary"_kj,
88 "__Boundary__"_kj);
89 
90 // different order
91 expectContentTypeParameter("multipart/form-data; boundary=\"__boundary__\"; charset=utf-8"_kj,
92 "boundary"_kj, "__boundary__"_kj);
93 
94 // bogus parameter
95 expectContentTypeParameter("multipart/form-data; foo=123; boundary=\"__boundary__\""_kj,
96 "boundary"_kj, "__boundary__"_kj);
97 
98 // quoted-string
99 expectContentTypeParameter(
100 R"(multipart/form-data; foo="\"boundary=bar\""; boundary="realboundary")", "boundary"_kj,
101 "realboundary"_kj);
102 
103 // Per the "collect an HTTP quoted string" algorithm (Fetch spec §2.6), the \"
104 // in charset="boundary=;\" is an escaped quote, so the charset value consumes
105 // everything through the next real closing quote. The boundary parameter is not
106 // separately parsed.
107 KJ_ASSERT(readContentTypeParameter(
108 R"(multipart/form-data; charset="boundary=;\"; boundary="__boundary__")",
109 "boundary"_kj) == kj::none);
110 
111 // The trailing \" in boundary="__boundary__\" is an escaped quote, so
112 // the value includes a literal quote character.
113 expectContentTypeParameter(
114 R"(multipart/form-data; charset="boundary=;"; boundary="__boundary__\")", "boundary"_kj,
115 R"(__boundary__")"_kj);
116 
117 expectContentTypeParameter(
118 R"(multipart/form-data; charset=\"boundary=;\"; boundary=\"__boundary__\")", "boundary"_kj,
119 R"(\"__boundary__\")");
120 
121 // spurious whitespace before ;
122 expectContentTypeParameter(
123 "multipart/form-data; boundary=asdf ;foo=bar"_kj, "boundary"_kj, "asdf"_kj);
124 
125 // spurious whitespace before ; with quotes
126 expectContentTypeParameter(
127 "multipart/form-data; boundary=\"asdf\" ;foo=bar"_kj, "boundary"_kj, "asdf"_kj);
128 
129 // all whitespace
130 KJ_ASSERT(readContentTypeParameter("multipart/form-data; boundary= ;foo=bar"_kj, "boundary"_kj) ==
131 kj::none);
132 
133 // all whitespace with quotes
134 KJ_ASSERT(readContentTypeParameter("multipart/form-data; boundary="
135 " ;foo=bar"_kj,
136 "boundary"_kj) == kj::none);
137 
138 // terminal escape character after quote
139 KJ_ASSERT(readContentTypeParameter(R"(multipart/form-data; foo="\)", "boundary"_kj) == kj::none);
140 
141 // space before value
142 expectContentTypeParameter("multipart/form-data; boundary= a"_kj, "boundary"_kj, " a"_kj);
143 
144 // space before value with quotes
145 expectContentTypeParameter("multipart/form-data; boundary=\" a\""_kj, "boundary"_kj, " a"_kj);
146 
147 // space before ; on another param
148 expectContentTypeParameter(
149 "multipart/form-data; foo=\"bar\" ;boundary=asdf"_kj, "boundary"_kj, "asdf"_kj);
150 
151 // space before ; on another param with quotes
152 expectContentTypeParameter(
153 "multipart/form-data; foo=\"bar\" ;boundary=\"asdf\""_kj, "boundary"_kj, "asdf"_kj);
154 
155 // space before ; on another param no quotes
156 expectContentTypeParameter(
157 "multipart/form-data; foo=bar ;boundary=asdf"_kj, "boundary"_kj, "asdf"_kj);
158 
159 // space before ; on another param quotes on wanted param
160 expectContentTypeParameter(
161 "multipart/form-data; foo=bar ;boundary=\"asdf\""_kj, "boundary"_kj, "asdf"_kj);
162}
163 
164} // namespace
165} // namespace workerd::api