Commit Graph

1414 Commits

Author SHA1 Message Date
Andrey Semashev
2896908264 Trim spaces. 2022-05-10 14:54:31 +03:00
Andrey Semashev
a187a9f10f Added symlink_status test for a system directory. 2022-05-09 20:04:23 +03:00
Andrey Semashev
4bdac43bd9 Use GetFileAttributesW in symlink_status if CreateFileW fails.
For some system files and folders like "System Volume Information"
CreateFileW fails with ERROR_ACCESS_DENIED while GetFileAttributesW
succeeds. GetFileAttributesW doesn't allow to discover whether the
file is a symlink or some other kind of a reparse point, so this
fallback will only work for files that are not reparse points,
symlinks or not. For reparse points continue to report error.

Closes https://github.com/boostorg/filesystem/issues/234.
2022-05-09 20:00:50 +03:00
Andrey Semashev
d732ab006a Explicitly specify FILE_READ_ATTRIBUTES when optning files to read attributes. 2022-05-09 19:13:32 +03:00
Andrey Semashev
88b0be807e Corrected a typo in a comment. 2022-04-06 23:15:27 +03:00
Andrey Semashev
aeb5318cd0 Silenced gcc warnings about non-virtual destructor in codecvt_error_cat.
Closes https://github.com/boostorg/filesystem/issues/232.
2022-04-06 20:12:08 +03:00
Andrey Semashev
123fe5faa6 Disable statx syscall usage on Android prior to 11.0.
Even though the syscall number is defined in kernel headers, the syscall
is blacklisted by seccomp in runtime.

Note that Android 11 also introduces the libc wrapper for statx, so
effectively the library will always use the libc wrapper on Android.

Reported in https://github.com/boostorg/filesystem/issues/229.
2022-03-02 14:19:25 +03:00
Andrey Semashev
7403ffca00 Added support for POSIX semantics for file removal on Windows.
Windows 10 1709 and later support POSIX semantics for removing files,
which means the file name is removed from the filesystem namespace as
soon as the file is marked for deletion. This makes opening the file
afterwards impossible, and allows creating a new file with the same
name, even if the deleted file is still open and in use.

The implementation uses runtime detection of the feature in the OS.
We are also using two more implementations for file removal: one that
employs the more recent FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE
flag (available since Windows 10 1809), and FILE_DISPOSITION_INFO
structure (supported since Windows Vista). The former allows to optimize
removal of read-only files, and the latter allows to make file deletion
atomic (i.e. not prone to failure if the file is replaced on the filesystem
while the operation is executing). The implementation is chosen in
runtime, depending on which one succeeds removing a file.

Also, added support for deleting read-only directories, in addition
to non-directory files, and simplified code a little.

Closes https://github.com/boostorg/filesystem/issues/216.
2022-03-01 11:09:08 +03:00
Andrey Semashev
97722a3107 Reimplemented status() and symlink_status() in terms of handles on Windows.
Using handles allows to reduce the number of system calls and avoids requesting
reparse point info, if the file is one. This should improve performance.
2022-02-21 19:18:49 +03:00
Andrey Semashev
f7930053c8 Corrected error handling and aded checks for exceptions. 2022-02-21 14:38:20 +03:00
Andrey Semashev
f2b09fc0a3 Make path::replace_extension version-dependent.
We have changed v4 path::extension() to not return the filename if
it starts with a dot, but we have not made path::replace_extension
version-dependent, which made v3 behave like v4. Fixing this,
and optimizing v4 path::replace_extension in the process.
2022-02-21 01:06:47 +03:00
Andrey Semashev
733eacfd59 Put Boost.Atomic dependency on a separate line in CMakeLists.txt.
Works around https://github.com/boostorg/cmake/issues/17.
2022-02-20 23:51:14 +03:00
Andrey Semashev
826edcc3e5 Fixed compilation. 2022-02-15 04:19:53 +03:00
Andrey Semashev
2b35bc8f11 Check if the handle refers to a directory in dir_itr_create on Windows.
Also, make a more robust check whether the handle refers to a symlink
in case if GetFileInformationByHandleEx is not available. If it is
not a symlink, but some other type of a reparse point, continue
processing it as if it is a regular directory.

Also, in remove_all_impl, check whether creating a directory iterator
fails due to the file not being a directory. Interpret this the same
way as with ELOOP - the error indicates that the directory was replaced
with some other kind of file between querying its type and creating
the directory iterator. Retry the operation.
2022-02-15 03:57:01 +03:00
Andrey Semashev
f803579e53 Reworked directory_iterator on Windows to add support for O_NOFOLLOW.
directory_iterator implementation now explicitly opens a directory
handle and relies on GetFileInformationByHandleEx or NtQueryDirectoryFile
to query information of the files in the directory. With
GetFileInformationByHandleEx, there are at least three ways to request
the information, each supported on different Windows versions and
different filesystems and providing different sets of information.
We support all three (FILE_ID_BOTH_DIR_INFO, FILE_FULL_DIR_INFO and
FILE_ID_EXTD_DIR_INFO), and we fall back to older ones if the newer
ones are not supported. GetFileInformationByHandleEx is available
since Windows Vista.

NtQueryDirectoryFile is an NT API that provides similar information to
GetFileInformationByHandleEx, but exists since at least Windows XP,
but some sources state it has existed since NT 4.0. This API is now
used when GetFileInformationByHandleEx is not available and it replaces
FindFirstFileW/FindNextFileW/FindClose based implementation (which
supposedly uses NtQueryDirectoryFile internally). Being an NT API,
we have to handle NTSTATUS error codes returned from it, so we had to
refactor unique path code that also used NTSTATUS previously.

Opening a directory handle explicitly allows to support O_NOFOLLOW
semantics on Windows, as we are able to prevent CreateFile from
following to the reparse point target. This is needed for remove_all
implementation to fix CVE-2022-21658. Similar to POSIX, remove_all_impl
on Windows now requests the directory iterator to not follow symlinks
when it is used to dive into a directory.

FindFirstFileW/FindNextFileW/FindClose based implementation is still
preserved for now for Windows CE, as it is unlikely to support neither
GetFileInformationByHandleEx nor NtQueryDirectoryFile. Given that
Windows CE has been untested for many years and is probably broken
anyway, its support is now declared deprecated. The related code,
including Find*-based directory iterator, will be removed in a
future release.

Closes https://github.com/boostorg/filesystem/issues/224.

And a couple cleanup changes:

 - Since we now may use GetFileInformationByHandleEx, we are now using
   it to query FILE_ATTRIBUTE_TAG_INFO for testing whether a reparse
   point is a symlink.

 - In resize_file_impl, we now specify all sharing flags to allow the
   operation to succeed if the file is already opened by someone.
2022-02-14 15:49:59 +03:00
Andrey Semashev
0346889a48 Added a cast to suppress MSVC warning of a possible truncation. 2022-02-14 04:50:52 +03:00
Andrey Semashev
47a4e69c79 Added a deprecated tag in release notes. 2022-02-08 23:31:28 +03:00
Andrey Semashev
266e1ac892 Moved string_file.hpp tests to deprecated tests.
Turns out string_file.hpp was tested in operations_unit_test, though not
included directly. Since string_file.hpp contents are disabled when the
test is compiled (as any other deprecated functionality), the test failed
to compile.

Moved the string_file.hpp test to deprecated_test, which explicitly enables
deprecated functionality. Also, include string_file.hpp in filesystem.hpp
if explicitly requested by defining BOOST_FILESYSTEM_DEPRECATED.
2022-02-08 22:45:52 +03:00
Andrey Semashev
f37d1f0db6 Deprecated string_file.hpp.
The header was not documented or tested, and the utilities it contains
are out of scope of the library.
2022-02-08 21:18:30 +03:00
Andrey Semashev
f6444522d7 Added checks against read/write size overflows and casts to silence warnings.
Closes https://github.com/boostorg/filesystem/issues/228.
2022-02-08 21:04:55 +03:00
Andrey Semashev
43f213fbd8 Removed unified initializers for global initializer objects.
This was supposed to be a workaround for clang bug that required an
initializer for global constant objects without a user-defined constructor,
but the initializer classes do have user-defined constructors, so this
workaround should not be needed. Removing it simplifies code a bit.
2022-02-08 15:30:27 +03:00
Andrey Semashev
edc2d8e4da Added early initialization of codecvt error category.
Marked codecvt error category constructor constexpr and defined
it unconditionally to work around clang bug in XCode 8: the compiler
requires a user-defined constructor to initialize the static const object
of the category.

When constexpr is not available (more precisely, when it is not enabled
by Boost.System), try to dynamic-initialize the category instance early.
For MSVC, invoke codecvt_error_category() from the early global initialization
routine in path.cpp. For other compilers, use a global initializer, possibly
augmented with init_priority attribute.

Closes https://github.com/boostorg/filesystem/issues/227.
2022-02-08 15:13:43 +03:00
Andrey Semashev
0ab2d5d309 Extracted Boost library include paths collection to a CMake module.
Also, save the collected paths to a global property to avoid potentially
scanning the filesystem in every library that needs these paths.
2022-02-04 14:41:47 +03:00
Andrey Semashev
dbec3baaad Use O_NONBLOCK instead of O_NDELAY as it is the flag defined by POSIX. 2022-02-03 20:58:42 +03:00
Andrey Semashev
41d076ace5 Added protection for CVE-2022-21658 in remove_all on POSIX systems.
Another process could replace the directory being processed by remove_all
with a symlink after remove_all called symlink_status but before
it creates a directory iterator. As a result, remove_all would remove
the linked directory contents instead of removing the symlink.

On POSIX systems that support fdopendir and O_NOFOLLOW flag for open(2),
this can be prevented by opening the directory with O_NOFOLLOW before
iterating. This will fail if the directory was replaced with a symlink.

No protection on other systems.

Reported in https://github.com/boostorg/filesystem/issues/224.
2022-01-30 23:41:06 +03:00
Andrey Semashev
e8ab4f8a4d Select readdir implementation early.
This optimizes readdir invokation on systems where readdir_r is used.
2022-01-30 19:17:38 +03:00
Andrey Semashev
f8024b245c Initialize WinAPI function pointers early, if possible. 2022-01-16 19:19:38 +03:00
Andrey Semashev
e3cebe1e3a Enabled testing with GNU extensions in GitHub Actions. 2022-01-16 18:26:55 +03:00
Andrey Semashev
a1067a33d6 Added clang-13 CI jobs. 2021-12-23 14:24:20 +03:00
Andrey Semashev
7edd9eb612 Use explicit operator+= and operator/= overloads for path and string types.
This is necessary to allow to pass arguments convertible to path and
compatible string types to these operators.

Fixes https://github.com/boostorg/filesystem/issues/223.
2021-12-23 14:06:43 +03:00
Andrey Semashev
fb3992a7df Added path concatenation tests. 2021-12-23 13:38:26 +03:00
Andrey Semashev
04c6e582be Use volatile to make sure globals_retainer is not optimized away.
By using volatile qualifier for the internal member of the globals_retainer
class we ensure the constructor formally has observable behavior, which means
it cannot be optimized away.

Related to https://github.com/boostorg/filesystem/issues/217.
2021-11-23 02:01:37 +03:00
Andrey Semashev
fa53749ac7 Added a workaround for MSVC linker eliminating path globals cleanup.
MSVC and possibly some other compilers that don't support __attribute__((used))
may remove the global p_init_path_globals pointer in a special data section
because it is not referenced anywhere. Add a dummy global object that
references the pointer in its constructor as a workaround.

Fixes https://github.com/boostorg/filesystem/issues/217.
2021-11-22 15:50:05 +03:00
Andrey Semashev
7de22d2dc1 Escape angle brackets in release notes. 2021-11-19 18:07:30 +03:00
Andrey Semashev
0f695acdf9 Replaced magic constant with INVALID_FILE_ATTRIBUTES. 2021-11-18 14:54:39 +03:00
Andrey Semashev
3ccf3d8afd Return -1 from remove_all() on error.
This matches C++17 behavior.
2021-11-18 14:54:39 +03:00
Andrey Semashev
18a8a3430d Added support for removing read-only files on Windows.
Reworked remove() operation to separate POSIX and Windows implementations.
On Windows, if the file to be removed is read-only, try to reset the read-only
attribute before deleting the file. If deleting fails (other than because the
file is already deleted), try to restore the read-only attribute.

As a side effect, we were able to remove an implementation detail value from
the file_type enum that was used by the old remove() implementation.

Added a test for remove() on a read-only file on Windows. Also added tests
for remove_all(), including for cases with symlinks, hardlinks and read-only
files.

Also, corrected mklink /J argument in tests. The command accepts /j (lowercase)
to the same effect, but the formal help lists /J (uppercase) to create junctions.

Reported in https://github.com/boostorg/filesystem/issues/216.
2021-11-18 14:54:17 +03:00
Andrey Semashev
46c74a2e16 Updated check for apt-add-repository capabilities.
In Ubuntu 20.04 there appeared an updated version of the
software-properties-common package in focal-updates, which ships a newer
apt-add-repository version that doesn't support -P/-S/-U command line arguments.

Since we cannot rely on package version checks to determine apt-add-repository
capabilities, we have to parse its --help output instead.

Also, made source list processing more protected against spaces.
2021-11-16 00:42:18 +03:00
Andrey Semashev
7fc42097cf Make hash_value a template to delay binding with Boost.ContainerHash functions.
This should fix linking errors when the compiler is set to preserve unused
inline functions (-fkeep-inline).

Closes https://github.com/boostorg/filesystem/issues/215.
2021-11-11 18:21:29 +03:00
Andrey Semashev
0307f58a8b Don't append trailing dot in lexically_normal, convert separators in root name.
In v4 path::lexically_normal, don't generate a trailing dot element if the
original path ends with a directory separator or dot. Also omit the trailing
directory separator the normalized path ends with a dot-dot element.

Additionally, convert directory separators to preferred separators in
root name on Windows (in v3 and v4). This may be significant for UNC paths.
2021-11-06 03:57:50 +03:00
Andrey Semashev
0aee13c162 Append a trailing directory separator when appending an empty path in v4.
If the source path ends with a non-empty filename, and the appended path
is empty, C++17 std::filesystem requires to add a trailing directory
separator.
2021-11-06 00:31:19 +03:00
Andrey Semashev
37bfbbb376 Updated appending root directory in canonical/weakly_canonical.
Similar to absolute(), canonical/weakly_canonical needed to be updated
to avoid discarding the root name of the path when appending a root
directory during path composition.
2021-11-06 00:23:30 +03:00
Andrey Semashev
cc763cb48e Reworked absolute() to fix appending root directory.
Because of the changed semantics of appending operations in v4, path
composition in absolute() would produce incorrect results because at some
point it would append root directory and therefore discard root name
that was potentially added before. The updated implementation fixes that,
and also fixes the case when the input path is already absolute and
starts with a root directory, and the base path has a root name.
Previously, the returned path would contain the root name from the
base path, while the correct thing to do is to return the input path
as is.
2021-11-05 23:41:31 +03:00
Andrey Semashev
0d413a5e4f Changed v4 path appends for absolute appended paths to match C++17.
Appending an absolute path now results in assigning the path, as
specified in C++17. This change is made for consistency with C++
and other languages that implement path manipulation (e.g. Python).
2021-11-05 23:40:57 +03:00
Andrey Semashev
ecbab750b2 Construct paths in BOOST_TEST_EQ macros from string literals.
This works around lightweight_test bug that it doesn't print C strings
in case of test failures.

Related to https://github.com/boostorg/core/issues/91.
2021-11-05 19:08:38 +03:00
Andrey Semashev
d13461be0f Implemented root-aware path appending in v4.
In Boost.Filesystem v3 path appending mostly worked as a slight upgrade
of concatenation, where appending would only add directory separators
when necessary, but not consider semantics of the root name and root
directory of the appended paths. This would work well for relative paths,
but produce unexpected results for paths with root names.

In v4, we now implement appending that is aware of root name and directory
of the appendedn paths. This means that appending a path with a root name
and/or directory no longer concatenates the paths, but rather rebases the
appended path on top of the source path. In particular, if the appended path
has a root name different from the source path, the append operation will
act as assignment.

This is closer to C++20 std::filesystem but not exactly the same. The
difference is for the case when the appended path is absolute. The C++20
spec requires assignment in this case, Boost.Filesystem v4 deliberately
omits this check. This is to ensure the correct result for UNC paths on
POSIX systems, where "//net/foo" / "/bar" is expected to produce "//net/bar",
not "/bar".

As part of this work, refactored path constructors and operators for more
optimal implementation and reducing the number of overloads.

Closes https://github.com/boostorg/filesystem/issues/214.
2021-11-05 02:21:55 +03:00
Andrey Semashev
049e9aad94 Check that linking with bcrypt works in has_bcrypt config test.
This allows to succeed library compilation if BCrypt API is
available in headers but the library is not.
2021-10-26 20:23:04 +03:00
Andrey Semashev
667f785e93 Disable deprecated CRT warnings on Windows also in tests. 2021-10-26 20:06:48 +03:00
Andrey Semashev
ac821cd53a Marked global constants with unused/used attributes to suppress clang warnings.
The "unused" attribute suppresses warnings emitted by clang for global
constants that are used to hook into early initialization of globals. The
"used" attribute is a precaution to ensure these hooks are not eliminated
by compiler or linker.
2021-10-26 19:49:58 +03:00
Andrey Semashev
df972e9a5d Remove unused constants on Windows to silence clang warnings. 2021-10-26 19:10:01 +03:00