Skip to content

Commit dafe2e4

Browse files
authored
Merge pull request #13889 from rouault/fix_ossfuzz_471096341
VSIMkdirRecursive(): fix perf issue on very long /vsimem/ filenames
2 parents df99744 + 1fc62d7 commit dafe2e4

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

autotest/gcore/vsifile.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,3 +1908,12 @@ def test_vsifile_buffering(tmp_path):
19081908
assert f.tell() == BUFFER_SIZE - 2 + 3 + 3 + BUFFER_SIZE + 3
19091909
f.seek(-5, os.SEEK_CUR)
19101910
assert f.read() == b"xxghi"
1911+
1912+
1913+
###############################################################################
1914+
def test_vsifile_mkdir_recursive_huge_filename(tmp_vsimem):
1915+
1916+
filename = str(tmp_vsimem)
1917+
filename += "a/" * ((4096 - len(filename)) // len("a/"))
1918+
assert gdal.MkdirRecursive(filename, 0o755) == 0
1919+
assert gdal.MkdirRecursive(filename + "a/", 0o755) < 0

port/cpl_vsi_mem.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,12 @@ class VSIMemFilesystemHandler final : public VSIFilesystemHandler
216216

217217
static CPLString NormalizePath(const std::string &in);
218218

219+
std::string
220+
GetCanonicalFilename(const std::string &osFilename) const override
221+
{
222+
return NormalizePath(osFilename);
223+
}
224+
219225
int Unlink_unlocked(const char *pszFilename);
220226

221227
VSIFilesystemHandler *Duplicate(const char *pszPrefix) override

port/cpl_vsil.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -647,8 +647,13 @@ int VSIMkdirRecursive(const char *pszPathname, long mode)
647647
if (!pszPathname)
648648
return -1;
649649

650-
const std::string osPathnameOri(pszPathname);
651-
if (osPathnameOri.empty() || osPathnameOri == "/")
650+
const std::string osPathnameOri(VSIFileManager::GetHandler(pszPathname)
651+
->GetCanonicalFilename(pszPathname));
652+
// Limit to avoid performance issues such as in
653+
// https://issues.oss-fuzz.com/issues/471096341
654+
constexpr size_t CPL_MAX_PATH = 4096;
655+
if (osPathnameOri.empty() || osPathnameOri == "/" ||
656+
osPathnameOri.size() > CPL_MAX_PATH)
652657
return -1;
653658

654659
VSIStatBufL sStat;

0 commit comments

Comments
 (0)