src: Fix path component resolution

Fix path component resolution when '.' is involved.
This commit is contained in:
Tatsuhiro Tsujikawa 2023-01-29 16:20:05 +09:00
parent 05b7929019
commit c78aebf68f
2 changed files with 169 additions and 0 deletions

View File

@ -1744,9 +1744,15 @@ StringRef path_join(BlockAllocator &balloc, const StringRef &base_path,
for (; first != last;) {
if (*first == '.') {
if (first + 1 == last) {
if (*(p - 1) != '/') {
p = eat_file(res.base, p);
}
break;
}
if (*(first + 1) == '/') {
if (*(p - 1) != '/') {
p = eat_file(res.base, p);
}
first += 2;
continue;
}

View File

@ -873,6 +873,169 @@ void test_http2_path_join(void) {
CU_ASSERT("/alpha/bravo?charlie" ==
http2::path_join(base, baseq, rel, relq));
}
// Test cases from RFC 3986, section 5.4.
constexpr auto base = StringRef::from_lit("/b/c/d;p");
constexpr auto baseq = StringRef::from_lit("q");
{
auto rel = StringRef::from_lit("g");
auto relq = StringRef{};
CU_ASSERT("/b/c/g" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("./g");
auto relq = StringRef{};
CU_ASSERT("/b/c/g" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g/");
auto relq = StringRef{};
CU_ASSERT("/b/c/g/" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("/g");
auto relq = StringRef{};
CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef{};
auto relq = StringRef::from_lit("y");
CU_ASSERT("/b/c/d;p?y" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g");
auto relq = StringRef::from_lit("y");
CU_ASSERT("/b/c/g?y" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit(";x");
auto relq = StringRef{};
CU_ASSERT("/b/c/;x" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g;x");
auto relq = StringRef{};
CU_ASSERT("/b/c/g;x" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g;x");
auto relq = StringRef::from_lit("y");
CU_ASSERT("/b/c/g;x?y" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef{};
auto relq = StringRef{};
CU_ASSERT("/b/c/d;p?q" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit(".");
auto relq = StringRef{};
CU_ASSERT("/b/c/" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("./");
auto relq = StringRef{};
CU_ASSERT("/b/c/" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("..");
auto relq = StringRef{};
CU_ASSERT("/b/" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../");
auto relq = StringRef{};
CU_ASSERT("/b/" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../g");
auto relq = StringRef{};
CU_ASSERT("/b/g" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../..");
auto relq = StringRef{};
CU_ASSERT("/" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../../");
auto relq = StringRef{};
CU_ASSERT("/" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../../g");
auto relq = StringRef{};
CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../../../g");
auto relq = StringRef{};
CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../../../../g");
auto relq = StringRef{};
CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("/./g");
auto relq = StringRef{};
CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("/../g");
auto relq = StringRef{};
CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g.");
auto relq = StringRef{};
CU_ASSERT("/b/c/g." == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit(".g");
auto relq = StringRef{};
CU_ASSERT("/b/c/.g" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g..");
auto relq = StringRef{};
CU_ASSERT("/b/c/g.." == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("..g");
auto relq = StringRef{};
CU_ASSERT("/b/c/..g" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("./../g");
auto relq = StringRef{};
CU_ASSERT("/b/g" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("./g/.");
auto relq = StringRef{};
CU_ASSERT("/b/c/g/" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g/./h");
auto relq = StringRef{};
CU_ASSERT("/b/c/g/h" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g/../h");
auto relq = StringRef{};
CU_ASSERT("/b/c/h" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g;x=1/./y");
auto relq = StringRef{};
CU_ASSERT("/b/c/g;x=1/y" == http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g;x=1/../y");
auto relq = StringRef{};
CU_ASSERT("/b/c/y" == http2::path_join(base, baseq, rel, relq));
}
}
void test_http2_normalize_path(void) {