urlapi: avoid dedotdotify() if possible

The dedotdotify() function that removes ./ and ../ sequences from paths
juggles memory and is slow. Now needs_dedotdot() is called first to
determine if the removal process is necessary and otherwise avoids doing
it. Avoids unnecessary memory operations.

Adjusted unit test 1395 accordingly because now a lot of input strings
return NULL for "no change necessary".

Suggested-by: Max Dymond

Closes #22557
This commit is contained in:
Daniel Stenberg 2026-08-12 12:11:37 +02:00
parent da04aa96ab
commit eae88a7473
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
2 changed files with 56 additions and 33 deletions

View file

@ -39,33 +39,33 @@ static CURLcode test_unit1395(const char *arg)
{ "/%2f%2e%2e%2f/../a", "/a" },
{ "/%2f%2e%2e%2f/../", "/" },
{ "/%2f%2e%2e%2f/.", "/%2f%2e%2e%2f/" },
{ "/%2f%2e%2e%2f/", "/%2f%2e%2e%2f/" },
{ "/%2f%2e%2e%2f", "/%2f%2e%2e%2f" },
{ "/%2f%2e%2e%2", "/%2f%2e%2e%2" },
{ "/%2f%2e%2e%", "/%2f%2e%2e%" },
{ "/%2f%2e%2e%2f/", NULL },
{ "/%2f%2e%2e%2f", NULL },
{ "/%2f%2e%2e%2", NULL },
{ "/%2f%2e%2e%", NULL },
{ "/%2f%2e%2e", "/%2f%2e%2e" },
{ "/%2f%2e%2", "/%2f%2e%2" },
{ "/%2f%2e%", "/%2f%2e%" },
{ "/%2f%2e%2", NULL },
{ "/%2f%2e%", NULL },
{ "/%2f%2e", "/%2f%2e" },
{ "/%2f%2", "/%2f%2" },
{ "/%2f%", "/%2f%" },
{ "/%2f", "/%2f" },
{ "/%2", "/%2" },
{ "/%2f%2", NULL },
{ "/%2f%", NULL },
{ "/%2f", NULL },
{ "/%2", NULL },
{ "%2f%2e%2e%2f/../a", "%2f%2e%2e%2f/a" },
{ "%2f%2e%2e%2f/../", "%2f%2e%2e%2f/" },
{ "%2f%2e%2e%2f/.", "%2f%2e%2e%2f/" },
{ "%2f%2e%2e%2f/", "%2f%2e%2e%2f/" },
{ "%2f%2e%2e%2f", "%2f%2e%2e%2f" },
{ "%2f%2e%2e%2", "%2f%2e%2e%2" },
{ "%2f%2e%2e%", "%2f%2e%2e%" },
{ "%2f%2e%2e%2f/", NULL },
{ "%2f%2e%2e%2f", NULL },
{ "%2f%2e%2e%2", NULL },
{ "%2f%2e%2e%", NULL },
{ "%2f%2e%2e", "%2f%2e%2e" },
{ "%2f%2e%2", "%2f%2e%2" },
{ "%2f%2e%", "%2f%2e%" },
{ "%2f%2e%2", NULL },
{ "%2f%2e%", NULL },
{ "%2f%2e", "%2f%2e" },
{ "%2f%2", "%2f%2" },
{ "%2f%", "%2f%" },
{ "%2f", "%2f" },
{ "%2", "%2" },
{ "%2f%2", NULL },
{ "%2f%", NULL },
{ "%2f", NULL },
{ "%2", NULL },
{ "%", NULL },
{ "2", NULL },
{ "e", NULL },
@ -108,12 +108,12 @@ static CURLcode test_unit1395(const char *arg)
{ "/1/./%2e.", "/" },
{ "/1/./../2", "/2" },
{ "/hello/1/./../2", "/hello/2" },
{ "test/this", "test/this" },
{ "test/this", NULL },
{ "test/this/../now", "test/now" },
{ "/1../moo../foo", "/1../moo../foo" },
{ "/../../moo", "/moo" },
{ "/../../moo?", "/moo?" },
{ "/123?", "/123?" },
{ "/123?", NULL },
{ "/", NULL },
{ "", NULL },
{ "/.../", "/.../" },
@ -131,16 +131,16 @@ static CURLcode test_unit1395(const char *arg)
{ "/a/%2E%2e/b", "/b" },
{ "/a/%2e./b", "/b" },
{ "/a/.%2e/b", "/b" },
{ "/%2f..%2f", "/%2f..%2f" },
{ "/%2f..%2f", NULL },
{ "/a/b/.", "/a/b/" },
{ "/a/b/..", "/a/" },
{ "well-known", "well-known" },
{ ".well-known", ".well-known" },
{ "..well-known", "..well-known" },
{ "...well-known", "...well-known" },
{ "....well-known", "....well-known" },
{ "%2ewell-known", "%2ewell-known" },
{ "%2Ewell-known", "%2Ewell-known" },
{ "well-known", NULL },
{ ".well-known", NULL },
{ "..well-known", NULL },
{ "...well-known", NULL },
{ "....well-known", NULL },
{ "%2ewell-known", NULL },
{ "%2Ewell-known", NULL },
{ "../.well-known", ".well-known" },
};