mirror of git://gcc.gnu.org/git/gcc.git
PR libstdc++/82777 fix path normalization for dot-dot
PR libstdc++/82777 * src/filesystem/std-path.cc (path::lexically_normal): Remove dot-dot elements correctly. * testsuite/27_io/filesystem/path/generation/normal.cc: Add testcase. * testsuite/util/testsuite_fs.h (compare_paths): Improve exception text. From-SVN: r254317
This commit is contained in:
parent
37a2c47525
commit
50e248f0c8
|
|
@ -1,3 +1,12 @@
|
||||||
|
2017-11-01 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
PR libstdc++/82777
|
||||||
|
* src/filesystem/std-path.cc (path::lexically_normal): Remove dot-dot
|
||||||
|
elements correctly.
|
||||||
|
* testsuite/27_io/filesystem/path/generation/normal.cc: Add testcase.
|
||||||
|
* testsuite/util/testsuite_fs.h (compare_paths): Improve exception
|
||||||
|
text.
|
||||||
|
|
||||||
2017-10-30 Jonathan Wakely <jwakely@redhat.com>
|
2017-10-30 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
* include/Makefile.am (stamp-bits-sup): Do not create broken symlink
|
* include/Makefile.am (stamp-bits-sup): Do not create broken symlink
|
||||||
|
|
|
||||||
|
|
@ -388,10 +388,35 @@ path::lexically_normal() const
|
||||||
#endif
|
#endif
|
||||||
if (is_dotdot(p))
|
if (is_dotdot(p))
|
||||||
{
|
{
|
||||||
if (ret.has_filename() && !is_dotdot(ret.filename()))
|
if (ret.has_filename())
|
||||||
ret.remove_filename();
|
{
|
||||||
else if (ret.has_filename() || !ret.has_root_directory())
|
// remove a non-dot-dot filename immediately followed by /..
|
||||||
ret /= p;
|
if (!is_dotdot(ret.filename()))
|
||||||
|
ret.remove_filename();
|
||||||
|
else
|
||||||
|
ret /= p;
|
||||||
|
}
|
||||||
|
else if (!ret.has_relative_path())
|
||||||
|
{
|
||||||
|
if (!ret.is_absolute())
|
||||||
|
ret /= p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Got a path with a relative path (i.e. at least one non-root
|
||||||
|
// element) and no filename at the end (i.e. empty last element),
|
||||||
|
// so must have a trailing slash. See what is before it.
|
||||||
|
auto elem = std::prev(ret.end(), 2);
|
||||||
|
if (elem->has_filename() && !is_dotdot(*elem))
|
||||||
|
{
|
||||||
|
// Remove the filename before the trailing slash
|
||||||
|
// (equiv. to ret = ret.parent_path().remove_filename())
|
||||||
|
ret._M_pathname.erase(elem._M_cur->_M_pos);
|
||||||
|
ret._M_cmpts.erase(elem._M_cur, ret._M_cmpts.end());
|
||||||
|
}
|
||||||
|
else // ???
|
||||||
|
ret /= p;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (is_dot(p))
|
else if (is_dot(p))
|
||||||
ret /= path();
|
ret /= path();
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,10 @@ test02()
|
||||||
compare_paths( path().lexically_normal(), "" );
|
compare_paths( path().lexically_normal(), "" );
|
||||||
|
|
||||||
compare_paths( path("/..").lexically_normal(), "/" );
|
compare_paths( path("/..").lexically_normal(), "/" );
|
||||||
|
|
||||||
|
// PR libstdc++/82777
|
||||||
|
compare_paths( path("./a/b/c/../.././b/c").lexically_normal(), "a/b/c" );
|
||||||
|
compare_paths( path("/a/b/c/../.././b/c").lexically_normal(), "/a/b/c" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ namespace __gnu_test
|
||||||
{
|
{
|
||||||
#define PATH_CHK(p1, p2, fn) \
|
#define PATH_CHK(p1, p2, fn) \
|
||||||
if ( p1.fn() != p2.fn() ) \
|
if ( p1.fn() != p2.fn() ) \
|
||||||
throw test_fs::filesystem_error( #fn, p1, p2, \
|
throw test_fs::filesystem_error("comparing '" #fn "' failed", p1, p2, \
|
||||||
std::make_error_code(std::errc::invalid_argument) )
|
std::make_error_code(std::errc::invalid_argument) )
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue