summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-contrib <[email protected]>2024-12-17 07:25:06 +0300
committerrobot-contrib <[email protected]>2024-12-17 07:47:50 +0300
commitea02bc3d382abec44b915e46fc1180d422ec6a7b (patch)
treed99855e0dcad2e617739468f541cb0176dbfb441
parentf441f2b31a6b0ffc68514b7423f0611f84ae51cd (diff)
Update contrib/restricted/boost/filesystem to 1.87.0
commit_hash:4ae470ee0a64c2c69b2319fd92c4178fa8790ab2
-rw-r--r--contrib/restricted/boost/filesystem/include/boost/filesystem/detail/path_traits.hpp49
-rw-r--r--contrib/restricted/boost/filesystem/src/directory.cpp13
-rw-r--r--contrib/restricted/boost/filesystem/src/error_handling.hpp9
-rw-r--r--contrib/restricted/boost/filesystem/src/operations.cpp247
-rw-r--r--contrib/restricted/boost/filesystem/ya.make4
5 files changed, 176 insertions, 146 deletions
diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/path_traits.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/path_traits.hpp
index 416c0737881..4cd81a2e733 100644
--- a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/path_traits.hpp
+++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/path_traits.hpp
@@ -25,6 +25,7 @@
#include <boost/assert.hpp>
#include <boost/system/error_category.hpp>
#include <boost/iterator/is_iterator.hpp>
+#include <boost/filesystem/detail/type_traits/negation.hpp>
#include <boost/filesystem/detail/type_traits/conjunction.hpp>
#if defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR)
#include <boost/filesystem/detail/type_traits/disjunction.hpp>
@@ -48,6 +49,7 @@ namespace filesystem {
BOOST_FILESYSTEM_DECL system::error_category const& codecvt_error_category() noexcept;
+class path;
class directory_entry;
namespace detail {
@@ -501,9 +503,8 @@ no_type check_convertible(...);
} // namespace is_convertible_to_path_source_impl
-//! The type trait indicates whether the type has a conversion path to one of the path source types
template< typename T >
-struct is_convertible_to_path_source :
+struct check_is_convertible_to_path_source :
public std::integral_constant<
bool,
sizeof(is_convertible_to_path_source_impl::check_convertible(std::declval< T const& >())) == sizeof(yes_type)
@@ -511,6 +512,25 @@ struct is_convertible_to_path_source :
{
};
+/*!
+ * \brief The type trait indicates whether the type has a conversion path to one of the path source types.
+ *
+ * \note The type trait returns `false` if the type is convertible to `path`. This prevents testing other
+ * conversion paths and forces the conversion to `path` to be chosen instead, to invoke a non-template
+ * member of `path` accepting a `path` argument.
+ */
+template< typename T >
+struct is_convertible_to_path_source :
+ public std::integral_constant<
+ bool,
+ detail::conjunction<
+ detail::negation< std::is_convertible< T, path > >,
+ check_is_convertible_to_path_source< T >
+ >::value
+ >
+{
+};
+
#else // !defined(BOOST_FILESYSTEM_DETAIL_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR)
// Note: We use separate checks for convertibility to std::string_view and other types to avoid ambiguity with an implicit range constructor
@@ -529,7 +549,7 @@ no_type check_convertible(...);
} // namespace is_convertible_to_std_string_view_impl
template< typename T >
-struct is_convertible_to_std_string_view :
+struct check_is_convertible_to_std_string_view :
public std::integral_constant<
bool,
sizeof(is_convertible_to_std_string_view_impl::check_convertible(std::declval< T const& >())) == sizeof(yes_type)
@@ -553,7 +573,7 @@ no_type check_convertible(...);
} // namespace is_convertible_to_path_source_non_std_string_view_impl
template< typename T >
-struct is_convertible_to_path_source_non_std_string_view :
+struct check_is_convertible_to_path_source_non_std_string_view :
public std::integral_constant<
bool,
sizeof(is_convertible_to_path_source_non_std_string_view_impl::check_convertible(std::declval< T const& >())) == sizeof(yes_type)
@@ -561,14 +581,23 @@ struct is_convertible_to_path_source_non_std_string_view :
{
};
-//! The type trait indicates whether the type has a conversion path to one of the path source types
+/*!
+ * \brief The type trait indicates whether the type has a conversion path to one of the path source types.
+ *
+ * \note The type trait returns `false` if the type is convertible to `path`. This prevents testing other
+ * conversion paths and forces the conversion to `path` to be chosen instead, to invoke a non-template
+ * member of `path` accepting a `path` argument.
+ */
template< typename T >
struct is_convertible_to_path_source :
public std::integral_constant<
bool,
- detail::disjunction<
- is_convertible_to_std_string_view< T >,
- is_convertible_to_path_source_non_std_string_view< T >
+ detail::conjunction<
+ detail::negation< std::is_convertible< T, path > >,
+ detail::disjunction<
+ check_is_convertible_to_std_string_view< T >,
+ check_is_convertible_to_path_source_non_std_string_view< T >
+ >
>::value
>
{
@@ -704,7 +733,7 @@ BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_sv_impl(st
template< typename Source, typename Callback >
BOOST_FORCEINLINE typename std::enable_if<
- !is_convertible_to_std_string_view< typename std::remove_cv< Source >::type >::value,
+ !check_is_convertible_to_std_string_view< typename std::remove_cv< Source >::type >::value,
typename Callback::result_type
>::type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = nullptr)
{
@@ -714,7 +743,7 @@ BOOST_FORCEINLINE typename std::enable_if<
template< typename Source, typename Callback >
BOOST_FORCEINLINE typename std::enable_if<
- is_convertible_to_std_string_view< typename std::remove_cv< Source >::type >::value,
+ check_is_convertible_to_std_string_view< typename std::remove_cv< Source >::type >::value,
typename Callback::result_type
>::type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = nullptr)
{
diff --git a/contrib/restricted/boost/filesystem/src/directory.cpp b/contrib/restricted/boost/filesystem/src/directory.cpp
index 576a460dd3d..113fef893bf 100644
--- a/contrib/restricted/boost/filesystem/src/directory.cpp
+++ b/contrib/restricted/boost/filesystem/src/directory.cpp
@@ -270,7 +270,8 @@ inline system::error_code dir_itr_close(dir_itr_imp& imp) noexcept
// Obtains a file descriptor from the directory iterator
inline int dir_itr_fd(dir_itr_imp const& imp, system::error_code& ec)
{
- int fd = ::dirfd(static_cast< DIR* >(imp.handle));
+ // Note: dirfd is a macro on FreeBSD 9 and older
+ const int fd = dirfd(static_cast< DIR* >(imp.handle));
if (BOOST_UNLIKELY(fd < 0))
{
int err = errno;
@@ -362,7 +363,7 @@ int readdir_select_impl(dir_itr_imp& imp, struct dirent** result);
typedef int readdir_impl_t(dir_itr_imp& imp, struct dirent** result);
-//! Pointer to the actual implementation of the copy_file_data implementation
+//! Pointer to the actual implementation of readdir
readdir_impl_t* readdir_impl_ptr = &readdir_select_impl;
void init_readdir_impl()
@@ -799,7 +800,7 @@ system::error_code dir_itr_increment(dir_itr_imp& imp, fs::path& filename, fs::f
if (!NT_SUCCESS(status))
{
dir_itr_close(imp);
- if (status == STATUS_NO_MORE_FILES)
+ if (BOOST_NTSTATUS_EQ(status, STATUS_NO_MORE_FILES))
goto done;
return system::error_code(translate_ntstatus(status), system::system_category());
@@ -1047,7 +1048,7 @@ system::error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& i
// causes a ERROR_FILE_NOT_FOUND error returned from FindFirstFileW
// (which is presumably equivalent to STATUS_NO_SUCH_FILE) which we
// do not consider an error. It is treated as eof instead.
- if (status == STATUS_NO_MORE_FILES || status == STATUS_NO_SUCH_FILE)
+ if (BOOST_NTSTATUS_EQ(status, STATUS_NO_MORE_FILES) || BOOST_NTSTATUS_EQ(status, STATUS_NO_SUCH_FILE))
goto done;
return error_code(translate_ntstatus(status), system_category());
@@ -1520,7 +1521,7 @@ void recursive_directory_iterator_increment(recursive_directory_iterator& it, sy
{
symlink_ft = detail::status_by_handle(direntry_handle.get(), dir_it->path(), &ec).type();
}
- else if (status == STATUS_NOT_IMPLEMENTED)
+ else if (BOOST_NTSTATUS_EQ(status, STATUS_NOT_IMPLEMENTED))
{
symlink_ft = dir_it->symlink_file_type(ec);
}
@@ -1615,7 +1616,7 @@ void recursive_directory_iterator_increment(recursive_directory_iterator& it, sy
{
goto get_file_type_by_handle;
}
- else if (status == STATUS_NOT_IMPLEMENTED)
+ else if (BOOST_NTSTATUS_EQ(status, STATUS_NOT_IMPLEMENTED))
{
ft = dir_it->file_type(ec);
}
diff --git a/contrib/restricted/boost/filesystem/src/error_handling.hpp b/contrib/restricted/boost/filesystem/src/error_handling.hpp
index a83d92e9762..a335756d140 100644
--- a/contrib/restricted/boost/filesystem/src/error_handling.hpp
+++ b/contrib/restricted/boost/filesystem/src/error_handling.hpp
@@ -51,6 +51,10 @@ typedef boost::winapi::DWORD_ err_t;
#define BOOST_ERROR_ALREADY_EXISTS boost::winapi::ERROR_ALREADY_EXISTS_
#define BOOST_ERROR_NOT_SUPPORTED boost::winapi::ERROR_NOT_SUPPORTED_
+// STATUS_* constants defined in ntstatus.h in some SDKs are defined as DWORDs, and NTSTATUS is LONG.
+// This results in signed/unsigned mismatch warnings emitted by gcc and clang. Consider that a platform bug.
+#define BOOST_NTSTATUS_EQ(x, y) static_cast< boost::winapi::ULONG_ >(x) == static_cast< boost::winapi::ULONG_ >(y)
+
// Note: Legacy MinGW doesn't have ntstatus.h and doesn't define NTSTATUS error codes other than STATUS_SUCCESS.
#if !defined(NT_SUCCESS)
#define NT_SUCCESS(Status) (((boost::winapi::NTSTATUS_)(Status)) >= 0)
@@ -171,8 +175,9 @@ inline boost::winapi::DWORD_ translate_ntstatus(boost::winapi::NTSTATUS_ status)
//! Tests if the NTSTATUS indicates that the file is not found
inline bool not_found_ntstatus(boost::winapi::NTSTATUS_ status) noexcept
{
- return status == STATUS_NO_SUCH_FILE || status == STATUS_OBJECT_NAME_NOT_FOUND || status == STATUS_OBJECT_PATH_NOT_FOUND ||
- status == STATUS_BAD_NETWORK_PATH || status == STATUS_BAD_NETWORK_NAME;
+ return BOOST_NTSTATUS_EQ(status, STATUS_NO_SUCH_FILE) || BOOST_NTSTATUS_EQ(status, STATUS_OBJECT_NAME_NOT_FOUND) ||
+ BOOST_NTSTATUS_EQ(status, STATUS_OBJECT_PATH_NOT_FOUND) || BOOST_NTSTATUS_EQ(status, STATUS_BAD_NETWORK_PATH) ||
+ BOOST_NTSTATUS_EQ(status, STATUS_BAD_NETWORK_NAME);
}
#endif
diff --git a/contrib/restricted/boost/filesystem/src/operations.cpp b/contrib/restricted/boost/filesystem/src/operations.cpp
index e2fa2354516..cb31c50c68c 100644
--- a/contrib/restricted/boost/filesystem/src/operations.cpp
+++ b/contrib/restricted/boost/filesystem/src/operations.cpp
@@ -263,11 +263,11 @@ namespace {
// The number of retries remove_all should make if it detects that the directory it is about to enter has been replaced with a symlink or a regular file
BOOST_CONSTEXPR_OR_CONST unsigned int remove_all_directory_replaced_retry_count = 5u;
-#if defined(BOOST_POSIX_API)
-
// Size of a small buffer for a path that can be placed on stack, in character code units
BOOST_CONSTEXPR_OR_CONST std::size_t small_path_size = 1024u;
+#if defined(BOOST_POSIX_API)
+
// Absolute maximum path length, in character code units, that we're willing to accept from various system calls.
// This value is arbitrary, it is supposed to be a hard limit to avoid memory exhaustion
// in some of the algorithms below in case of some corrupted or maliciously broken filesystem.
@@ -805,7 +805,7 @@ int copy_file_data_read_write(int infile, int outfile, uintmax_t size, std::size
typedef int copy_file_data_t(int infile, int outfile, uintmax_t size, std::size_t blksize);
-//! Pointer to the actual implementation of the copy_file_data implementation
+//! Pointer to the actual implementation of copy_file_data
copy_file_data_t* copy_file_data = &copy_file_data_read_write;
#if defined(BOOST_FILESYSTEM_USE_SENDFILE) || defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE)
@@ -1401,12 +1401,12 @@ BOOST_FILESYSTEM_INIT_FUNC init_winapi_func_ptrs()
boost::winapi::HMODULE_ h = boost::winapi::GetModuleHandleW(L"kernel32.dll");
if (BOOST_LIKELY(!!h))
{
- GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = (GetFileInformationByHandleEx_t*)boost::winapi::get_proc_address(h, "GetFileInformationByHandleEx");
+ GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = boost::winapi::get_proc_address<GetFileInformationByHandleEx_t*>(h, "GetFileInformationByHandleEx");
filesystem::detail::atomic_store_relaxed(get_file_information_by_handle_ex_api, get_file_information_by_handle_ex);
- SetFileInformationByHandle_t* set_file_information_by_handle = (SetFileInformationByHandle_t*)boost::winapi::get_proc_address(h, "SetFileInformationByHandle");
+ SetFileInformationByHandle_t* set_file_information_by_handle = boost::winapi::get_proc_address<SetFileInformationByHandle_t*>(h, "SetFileInformationByHandle");
filesystem::detail::atomic_store_relaxed(set_file_information_by_handle_api, set_file_information_by_handle);
- filesystem::detail::atomic_store_relaxed(create_hard_link_api, (CreateHardLinkW_t*)boost::winapi::get_proc_address(h, "CreateHardLinkW"));
- filesystem::detail::atomic_store_relaxed(create_symbolic_link_api, (CreateSymbolicLinkW_t*)boost::winapi::get_proc_address(h, "CreateSymbolicLinkW"));
+ filesystem::detail::atomic_store_relaxed(create_hard_link_api, boost::winapi::get_proc_address<CreateHardLinkW_t*>(h, "CreateHardLinkW"));
+ filesystem::detail::atomic_store_relaxed(create_symbolic_link_api, boost::winapi::get_proc_address<CreateSymbolicLinkW_t*>(h, "CreateSymbolicLinkW"));
if (get_file_information_by_handle_ex && set_file_information_by_handle)
{
@@ -1419,8 +1419,8 @@ BOOST_FILESYSTEM_INIT_FUNC init_winapi_func_ptrs()
h = boost::winapi::GetModuleHandleW(L"ntdll.dll");
if (BOOST_LIKELY(!!h))
{
- filesystem::detail::atomic_store_relaxed(nt_create_file_api, (NtCreateFile_t*)boost::winapi::get_proc_address(h, "NtCreateFile"));
- filesystem::detail::atomic_store_relaxed(nt_query_directory_file_api, (NtQueryDirectoryFile_t*)boost::winapi::get_proc_address(h, "NtQueryDirectoryFile"));
+ filesystem::detail::atomic_store_relaxed(nt_create_file_api, boost::winapi::get_proc_address<NtCreateFile_t*>(h, "NtCreateFile"));
+ filesystem::detail::atomic_store_relaxed(nt_query_directory_file_api, boost::winapi::get_proc_address<NtQueryDirectoryFile_t*>(h, "NtQueryDirectoryFile"));
}
init_directory_iterator_impl();
@@ -1559,7 +1559,7 @@ boost::winapi::NTSTATUS_ nt_create_file_handle_at
{
NtCreateFile_t* nt_create_file = filesystem::detail::atomic_load_relaxed(nt_create_file_api);
if (BOOST_UNLIKELY(!nt_create_file))
- return STATUS_NOT_IMPLEMENTED;
+ return static_cast< boost::winapi::NTSTATUS_ >(STATUS_NOT_IMPLEMENTED);
unicode_string obj_name = {};
obj_name.Buffer = const_cast< wchar_t* >(p.c_str());
@@ -1591,7 +1591,7 @@ boost::winapi::NTSTATUS_ nt_create_file_handle_at
0u // EaLength
);
- if (BOOST_UNLIKELY(status == STATUS_INVALID_PARAMETER && (obj_attrs.Attributes & OBJ_DONT_REPARSE) != 0u))
+ if (BOOST_UNLIKELY(BOOST_NTSTATUS_EQ(status, STATUS_INVALID_PARAMETER) && (obj_attrs.Attributes & OBJ_DONT_REPARSE) != 0u))
{
// OBJ_DONT_REPARSE is supported since Windows 10, retry without it
filesystem::detail::atomic_store_relaxed(g_no_obj_dont_reparse, true);
@@ -2383,7 +2383,7 @@ inline path convert_nt_path_to_win32_path(const wchar_t* nt_path, std::size_t si
(
// Check if the following is a drive letter
(
- detail::is_letter(nt_path[pos]) && nt_path[pos + 1u] == colon &&
+ nt_path[pos + 1u] == colon && detail::is_letter(nt_path[pos]) &&
((size - pos) == 2u || detail::is_directory_separator(nt_path[pos + 2u]))
) ||
// Check for an "incorrect" syntax for UNC path junction points
@@ -2565,15 +2565,11 @@ path absolute_v4(path const& p, path const& base, system::error_code* ec)
return res;
}
-BOOST_FILESYSTEM_DECL
-path canonical_v3(path const& p, path const& base, system::error_code* ec)
+namespace {
+
+inline path canonical_common(path& source, system::error_code* ec)
{
- path source(detail::absolute_v3(p, base, ec));
- if (ec && *ec)
- {
- return_empty_path:
- return path();
- }
+#if defined(BOOST_POSIX_API)
system::error_code local_ec;
file_status st(detail::status_impl(source, &local_ec));
@@ -2590,7 +2586,9 @@ path canonical_v3(path const& p, path const& base, system::error_code* ec)
BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::canonical", source, local_ec));
*ec = local_ec;
- goto return_empty_path;
+
+ return_empty_path:
+ return path();
}
path root(source.root_path());
@@ -2602,6 +2600,8 @@ path canonical_v3(path const& p, path const& base, system::error_code* ec)
{
for (path::iterator itr(source.begin()), end(source.end()); itr != end; path_algorithms::increment_v4(itr))
{
+ if (itr->empty())
+ continue;
if (path_algorithms::compare_v4(*itr, dot_p) == 0)
continue;
if (path_algorithms::compare_v4(*itr, dot_dot_p) == 0)
@@ -2624,12 +2624,6 @@ path canonical_v3(path const& p, path const& base, system::error_code* ec)
path_algorithms::append_v4(result, *itr);
- // If we don't have an absolute path yet then don't check symlink status.
- // This avoids checking "C:" which is "the current directory on drive C"
- // and hence not what we want to check/resolve here.
- if (!result.is_absolute())
- continue;
-
st = detail::symlink_status_impl(result, ec);
if (ec && *ec)
goto return_empty_path;
@@ -2656,7 +2650,7 @@ path canonical_v3(path const& p, path const& base, system::error_code* ec)
if (path_algorithms::compare_v4(*itr, dot_p) != 0)
path_algorithms::append_v4(link, *itr);
}
- source = link;
+ source = std::move(link);
root = source.root_path();
}
else // link is relative
@@ -2672,7 +2666,7 @@ path canonical_v3(path const& p, path const& base, system::error_code* ec)
if (path_algorithms::compare_v4(*itr, dot_p) != 0)
path_algorithms::append_v4(new_source, *itr);
}
- source = new_source;
+ source = std::move(new_source);
}
// symlink causes scan to be restarted
@@ -2688,131 +2682,132 @@ path canonical_v3(path const& p, path const& base, system::error_code* ec)
BOOST_ASSERT_MSG(result.is_absolute(), "canonical() implementation error; please report");
return result;
-}
-BOOST_FILESYSTEM_DECL
-path canonical_v4(path const& p, path const& base, system::error_code* ec)
-{
- path source(detail::absolute_v4(p, base, ec));
- if (ec && *ec)
- {
- return_empty_path:
- return path();
- }
+#else // defined(BOOST_POSIX_API)
- system::error_code local_ec;
- file_status st(detail::status_impl(source, &local_ec));
+ unique_handle h(create_file_handle(
+ source.c_str(),
+ FILE_READ_ATTRIBUTES | FILE_READ_EA,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ nullptr, // lpSecurityAttributes
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS));
- if (st.type() == fs::file_not_found)
- {
- local_ec = system::errc::make_error_code(system::errc::no_such_file_or_directory);
- goto fail_local_ec;
- }
- else if (local_ec)
+ DWORD err;
+ if (!h)
{
- fail_local_ec:
- if (!ec)
- BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::canonical", source, local_ec));
+ err = ::GetLastError();
- *ec = local_ec;
- goto return_empty_path;
+ fail_err:
+ emit_error(err, source, ec, "boost::filesystem::canonical");
+ return path();
}
- path root(source.root_path());
- path const& dot_p = dot_path();
- path const& dot_dot_p = dot_dot_path();
- unsigned int symlinks_allowed = symloop_max;
- path result;
+ WCHAR path_small_buf[small_path_size];
+ std::unique_ptr< WCHAR[] > path_large_buf;
+ WCHAR* path_buf = path_small_buf;
+ DWORD path_buf_size = sizeof(path_small_buf) / sizeof(*path_small_buf);
+ DWORD flags = FILE_NAME_NORMALIZED;
+ DWORD path_len;
+
while (true)
{
- for (path::iterator itr(source.begin()), end(source.end()); itr != end; path_algorithms::increment_v4(itr))
+ path_len = ::GetFinalPathNameByHandleW(h.get(), path_buf, path_buf_size, flags);
+ if (path_len > 0)
{
- if (path_algorithms::compare_v4(*itr, dot_p) == 0)
- continue;
- if (path_algorithms::compare_v4(*itr, dot_dot_p) == 0)
- {
- if (path_algorithms::compare_v4(result, root) != 0)
- result.remove_filename_and_trailing_separators();
- continue;
- }
+ if (path_len < path_buf_size)
+ break;
- if (itr->size() == 1u && detail::is_directory_separator(itr->native()[0]))
+ // The buffer is not large enough, path_len is the required buffer size, including the terminating zero
+ path_large_buf.reset(new WCHAR[path_len]);
+ path_buf = path_large_buf.get();
+ path_buf_size = path_len;
+ }
+ else
+ {
+ err = ::GetLastError();
+ if (BOOST_UNLIKELY(err == ERROR_PATH_NOT_FOUND && (flags & VOLUME_NAME_NT) == 0u))
{
- // Convert generic separator returned by the iterator for the root directory to
- // the preferred separator. This is important on Windows, as in some cases,
- // like paths for network shares and cloud storage mount points GetFileAttributesW
- // will return "file not found" if the path contains forward slashes.
- result += path::preferred_separator;
- // We don't need to check for a symlink after adding a separator.
+ // Drive letter does not exist for the file, obtain an NT path for it
+ flags |= VOLUME_NAME_NT;
continue;
}
- path_algorithms::append_v4(result, *itr);
-
- // If we don't have an absolute path yet then don't check symlink status.
- // This avoids checking "C:" which is "the current directory on drive C"
- // and hence not what we want to check/resolve here.
- if (!result.is_absolute())
- continue;
-
- st = detail::symlink_status_impl(result, ec);
- if (ec && *ec)
- goto return_empty_path;
+ goto fail_err;
+ }
+ }
- if (is_symlink(st))
+ path result;
+ if ((flags & VOLUME_NAME_NT) == 0u)
+ {
+ // If the input path did not contain a long path prefix, convert
+ // "\\?\X:" to "X:" and "\\?\UNC\" to "\\". Otherwise, preserve the prefix.
+ const path::value_type* source_str = source.c_str();
+ if (source.size() < 4u ||
+ source_str[0] != path::preferred_separator ||
+ source_str[1] != path::preferred_separator ||
+ source_str[2] != questionmark ||
+ source_str[3] != path::preferred_separator)
+ {
+ if (path_len >= 6u &&
+ path_buf[0] == path::preferred_separator &&
+ path_buf[1] == path::preferred_separator &&
+ path_buf[2] == questionmark &&
+ path_buf[3] == path::preferred_separator)
{
- if (symlinks_allowed == 0)
- {
- local_ec = system::errc::make_error_code(system::errc::too_many_symbolic_link_levels);
- goto fail_local_ec;
- }
-
- --symlinks_allowed;
-
- path link(detail::read_symlink(result, ec));
- if (ec && *ec)
- goto return_empty_path;
- result.remove_filename_and_trailing_separators();
-
- if (link.is_absolute())
+ if (path_buf[5] == colon && detail::is_letter(path_buf[4]))
{
- for (path_algorithms::increment_v4(itr); itr != end; path_algorithms::increment_v4(itr))
- {
- if (path_algorithms::compare_v4(*itr, dot_p) != 0)
- path_algorithms::append_v4(link, *itr);
- }
- source = link;
- root = source.root_path();
+ path_buf += 4;
+ path_len -= 4u;
}
- else // link is relative
+ else if (path_len >= 8u &&
+ (path_buf[4] == L'U' || path_buf[4] == L'u') &&
+ (path_buf[5] == L'N' || path_buf[5] == L'n') &&
+ (path_buf[6] == L'C' || path_buf[6] == L'c') &&
+ path_buf[7] == path::preferred_separator)
{
- link.remove_trailing_separator();
- if (path_algorithms::compare_v4(link, dot_p) == 0)
- continue;
-
- path new_source(result);
- path_algorithms::append_v4(new_source, link);
- for (path_algorithms::increment_v4(itr); itr != end; path_algorithms::increment_v4(itr))
- {
- if (path_algorithms::compare_v4(*itr, dot_p) != 0)
- path_algorithms::append_v4(new_source, *itr);
- }
- source = new_source;
+ path_buf += 6;
+ path_len -= 6u;
+ path_buf[0] = path::preferred_separator;
}
-
- // symlink causes scan to be restarted
- goto restart_scan;
}
}
- break;
-
- restart_scan:
- result.clear();
+ result.assign(path_buf, path_buf + path_len);
+ }
+ else
+ {
+ // Convert NT path to a Win32 path
+ result.assign(L"\\\\?\\GLOBALROOT");
+ result.concat(path_buf, path_buf + path_len);
}
BOOST_ASSERT_MSG(result.is_absolute(), "canonical() implementation error; please report");
return result;
+
+#endif // defined(BOOST_POSIX_API)
+}
+
+} // unnamed namespace
+
+BOOST_FILESYSTEM_DECL
+path canonical_v3(path const& p, path const& base, system::error_code* ec)
+{
+ path source(detail::absolute_v3(p, base, ec));
+ if (ec && *ec)
+ return path();
+
+ return detail::canonical_common(source, ec);
+}
+
+BOOST_FILESYSTEM_DECL
+path canonical_v4(path const& p, path const& base, system::error_code* ec)
+{
+ path source(detail::absolute_v4(p, base, ec));
+ if (ec && *ec)
+ return path();
+
+ return detail::canonical_common(source, ec);
}
BOOST_FILESYSTEM_DECL
diff --git a/contrib/restricted/boost/filesystem/ya.make b/contrib/restricted/boost/filesystem/ya.make
index f468ba49800..b576f8c67f4 100644
--- a/contrib/restricted/boost/filesystem/ya.make
+++ b/contrib/restricted/boost/filesystem/ya.make
@@ -6,9 +6,9 @@ LICENSE(BSL-1.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(1.86.0)
+VERSION(1.87.0)
-ORIGINAL_SOURCE(https://github.com/boostorg/filesystem/archive/boost-1.86.0.tar.gz)
+ORIGINAL_SOURCE(https://github.com/boostorg/filesystem/archive/boost-1.87.0.tar.gz)
PEERDIR(
contrib/restricted/boost/assert