+2019-12-09 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/92853
+ * src/c++17/fs_path.cc (filesystem::path::operator+=(const path&)):
+ Do not process a trailing directory separator twice.
+ * testsuite/27_io/filesystem/path/concat/92853.cc: New test.
+ * testsuite/27_io/filesystem/path/concat/path.cc: Test more cases.
+
2019-12-09 François Dumont <fdumont@gcc.gnu.org>
* testsuite/23_containers/array/tuple_interface/get_debug_neg.cc:
}
if (it != last && it->_M_type() == _Type::_Root_dir)
- {
- ++it;
- if (it == last)
- {
- // This root-dir becomes a trailing slash
- auto pos = _M_pathname.length() + p._M_pathname.length();
- ::new(output++) _Cmpt({}, _Type::_Filename, pos);
- ++_M_cmpts._M_impl->_M_size;
- }
- }
+ ++it;
while (it != last)
{
--- /dev/null
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++17 } }
+
+#include <filesystem>
+#include <testsuite_fs.h>
+
+void
+test01()
+{
+ // PR libstdc++/92853
+ using std::filesystem::path;
+ path p1{ "." }, p2{ "/" };
+ p1 += p2; // corrupts heap
+ path p3{ p1 }; // CRASH!
+ __gnu_test::compare_paths( p3, "./" );
+}
+
+void
+test02()
+{
+ using std::filesystem::path;
+ path p1{ "." }, p2{ "////" };
+ p1 += p2;
+ path p3{ p1 };
+ __gnu_test::compare_paths( p3, ".////" );
+}
+
+void
+test03()
+{
+ using std::filesystem::path;
+ path p1{ "./" }, p2{ "/" };
+ p1 += p2;
+ path p3{ p1 };
+ __gnu_test::compare_paths( p3, ".//" );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
path x("//blah/di/blah");
p += x;
VERIFY( p.native() == prior_native + x.native() );
+ path copy(p);
+ compare_paths( copy, p );
}
}
compare_paths(p, "a//b");
}
+void
+test04()
+{
+ // Concat every test path onto every test path.
+ for (path p : __gnu_test::test_paths)
+ {
+ for (path x : __gnu_test::test_paths)
+ {
+ auto prior_native = p.native();
+ p += x;
+ VERIFY( p.native() == prior_native + x.native() );
+ path copy(p); // PR libstdc++/98523
+ compare_paths( copy, p );
+ }
+ }
+}
+
int
main()
{
test01();
test02();
test03();
+ test04();
}