Skip to content

Commit 799b815

Browse files
authored
Fix regressions (#133)
* Added check for case sensitive percent encoded double path segment * Use strings * Removed magic numbers in domain name parsing
1 parent 0f33d2a commit 799b815

File tree

3 files changed

+16
-18
lines changed

3 files changed

+16
-18
lines changed

src/v1/core/url_parser_context.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,13 @@ inline auto is_windows_drive_letter(std::string_view segment) noexcept {
7575
}
7676

7777
inline auto is_single_dot_path_segment(std::string_view segment) noexcept {
78-
return (segment == ".") || (segment == "%2E");
78+
return (segment == ".") || (segment == "%2e") || (segment == "%2E");
7979
}
8080

8181
auto is_double_dot_path_segment(std::string_view segment) noexcept {
82-
return (segment == "..") || (segment == "%2E.") || (segment == ".%2E") || (segment == "%2E%2E");
82+
return (segment == "..") || (segment == "%2e.") || (segment == ".%2e") || (segment == "%2e%2e") ||
83+
(segment == "%2E.") || (segment == ".%2E") || (segment == "%2E%2E") || (segment == "%2E%2e") ||
84+
(segment == "%%2E");
8385
}
8486

8587
void shorten_path(std::string_view scheme, std::vector<std::string> &path) {

src/v1/domain/domain.cpp

+10-15
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,6 @@
1919
#include "idna_code_point_map_iterator.hpp"
2020
#include "punycode.hpp"
2121

22-
#if !defined(SKYR_DOMAIN_MAX_DOMAIN_LENGTH)
23-
#define SKYR_DOMAIN_MAX_DOMAIN_LENGTH 253
24-
#endif // !defined(SKYR_DOMAIN_MAX_DOMAIN_LENGTH)
25-
26-
#if !defined(SKYR_DOMAIN_MAX_LABEL_LENGTH)
27-
#define SKYR_DOMAIN_MAX_LABEL_LENGTH 63
28-
#endif // !defined(SKYR_LABEL_MAX_DOMAIN_LENGTH)
2922

3023
/// How many labels can be in a domain?
3124
/// https://www.farsightsecurity.com/blog/txt-record/rrlabel-20171013/
@@ -41,7 +34,7 @@ auto map_code_points(
4134
U32Range &&domain_name,
4235
bool use_std3_ascii_rules,
4336
bool transitional_processing,
44-
static_vector<char32_t, SKYR_DOMAIN_MAX_DOMAIN_LENGTH> *result)
37+
std::u32string *result)
4538
-> tl::expected<void, domain_errc> {
4639
auto range = views::map_code_points(domain_name, use_std3_ascii_rules, transitional_processing);
4740
auto first = std::cbegin(range);
@@ -50,7 +43,7 @@ auto map_code_points(
5043
if (!*it) {
5144
return tl::make_unexpected((*it).error());
5245
}
53-
result->emplace_back((*it).value());
46+
result->push_back((*it).value());
5447
if (result->size() == result->max_size()) {
5548
return tl::make_unexpected(domain_errc::invalid_length);
5649
}
@@ -113,7 +106,7 @@ auto domain_to_ascii(
113106
using namespace std::string_view_literals;
114107

115108
auto u32domain_name = unicode::views::as_u8(domain_name) | unicode::transforms::to_u32;
116-
auto mapped_domain_name = static_vector<char32_t, SKYR_DOMAIN_MAX_DOMAIN_LENGTH>{};
109+
auto mapped_domain_name = std::u32string{};
117110
auto result = map_code_points(u32domain_name, use_std3_ascii_rules, transitional_processing, &mapped_domain_name);
118111
if (!result) {
119112
return tl::make_unexpected(result.error());
@@ -123,8 +116,7 @@ auto domain_to_ascii(
123116
return std::u32string_view(std::addressof(*std::begin(label)), ranges::distance(label));
124117
};
125118

126-
/// TODO: try this without allocating strings (e.g. for large strings that don't use SBO)
127-
auto labels = static_vector<static_vector<char32_t, SKYR_DOMAIN_MAX_LABEL_LENGTH>, SKYR_DOMAIN_MAX_NUM_LABELS>{};
119+
auto labels = static_vector<std::u32string, SKYR_DOMAIN_MAX_NUM_LABELS>{};
128120
for (auto &&label : mapped_domain_name | ranges::views::split(U'.') | ranges::views::transform(to_string_view)) {
129121
if (labels.size() == labels.max_size()) {
130122
return tl::make_unexpected(domain_errc::too_many_labels);
@@ -174,15 +166,18 @@ auto domain_to_ascii(
174166
labels.emplace_back();
175167
}
176168

169+
constexpr auto max_domain_length = 253;
170+
constexpr auto max_label_length = 63;
171+
177172
if (verify_dns_length) {
178173
auto length = mapped_domain_name.size();
179-
if ((length < 1) || (length > 253)) {
174+
if ((length < 1) || (length > max_domain_length)) {
180175
return tl::make_unexpected(domain_errc::invalid_length);
181176
}
182177

183178
for (const auto &label : labels) {
184179
auto label_length = label.size();
185-
if ((label_length < 1) || (label_length > 63)) {
180+
if ((label_length < 1) || (label_length > max_label_length)) {
186181
return tl::make_unexpected(domain_errc::invalid_length);
187182
}
188183
}
@@ -213,7 +208,7 @@ auto domain_to_u8(std::string_view domain_name, [[maybe_unused]] bool *validatio
213208
return std::string_view(std::addressof(*std::begin(label)), ranges::distance(label));
214209
};
215210

216-
auto labels = static_vector<static_vector<char, SKYR_DOMAIN_MAX_LABEL_LENGTH>, SKYR_DOMAIN_MAX_NUM_LABELS>{};
211+
auto labels = static_vector<std::string, SKYR_DOMAIN_MAX_NUM_LABELS>{};
217212
for (auto &&label : domain_name | ranges::views::split('.') | ranges::views::transform(to_string_view)) {
218213
if (labels.size() == labels.max_size()) {
219214
return tl::make_unexpected(domain_errc::too_many_labels);

tests/allocations/host_parsing_tests.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ int main() {
1818
"[2001:0db8:0:0::1428:57ab]"sv,
1919
"localhost"sv,
2020
"a.b.c.d.e.f.g.h.i.j.k.l.example.com"sv,
21-
"sub.llanfairpwllgwyngyllgogerychwndrwbwllllantysiliogogogoch.com"sv
21+
"sub.llanfairpwllgwyngyllgogerychwndrwbwllllantysiliogogogoch.com"sv,
22+
"i am a terrible host name and n\0t in any way.valid.but. i am useful to validate @llocation"sv
2223
};
2324

2425
for (auto &&host_string : host_strings) {

0 commit comments

Comments
 (0)