cginternals / cppfs

Cross-platform C++ file system library supporting multiple backends

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Incorrect path resolving for concatenated path separators.

kuepe-sl opened this issue · comments

FilePath::resolved() goes wrong when you have multiple concatenated path separators, combined with path traversal paths.

a/b//../c should be resolved to a/c. cppfs instead resolves it to a/b/c

Windows 10 and Ubuntu 20.04 both treat concatenated path separators as "one" path separator.
a/b//c////../../d is treated as a/b/c/../../d and thus is resolved to a/d.

Here is a small program to illustrate the behaviour:

#include <string>
#include <iostream>
#include <cppfs/FilePath.h>

int main(int argc, char* argv[])
{
    std::string p1 = "/usr/bin/bash";
    std::string p2 = "/usr/bin/../bin/bash";
    std::string p3 = "/usr/bin//../bin/bash";
    std::cout << "p1: " << p1 << " -> FilePath::resolved: " << cppfs::FilePath{p1}.resolved() << "\n";
    std::cout << "p2: " << p2 << " -> FilePath::resolved: " << cppfs::FilePath{p2}.resolved() << "\n";
    std::cout << "p3: " << p3 << " -> FilePath::resolved: " << cppfs::FilePath{p3}.resolved() << "\n";
    return 0;
}

Building the program against the current cppfs master results in the following output:

p1: /usr/bin/bash -> FilePath::resolved: /usr/bin/bash
p2: /usr/bin/../bin/bash -> FilePath::resolved: /usr/bin/bash
p3: /usr/bin//../bin/bash -> FilePath::resolved: /usr/bin/bin/bash

I then gave all of the paths to file:

$ file /usr/bin/bash /usr/bin/../bin/bash /usr/bin//../bin/bash /usr/bin/bin/bash
/usr/bin/bash:         ELF 64-bit LSB shared object, [...]
/usr/bin/../bin/bash:  ELF 64-bit LSB shared object, [...]
/usr/bin//../bin/bash: ELF 64-bit LSB shared object, [...]
/usr/bin/bin/bash: cannot open `/usr/bin/bin/bash' (No such file or directory)

As seen, the last path (p3 resolved by cppfs) results in a "file not found" when it should not.

Thanks for reporting.