PATH_MAX isn't guaranteed to be defined in Posix environments; it is
only on systems that have a path length limit, and even in environments
where it is defined its usage can lead to issues.
To avoid using PATH_MAX, I've made two main changes:
- Where realpath() was used, I've changed the code to use its
[POSIX.1-2008]'s new behaviour, where passing a null pointer as the
resolved_name buffer results in realpath() to automatically allocate
a buffer large enough to handle the given path, that is returned to
the caller. This has been supported for a long time as a GNU libc
extension before being standardized.
- Where readlink() was used, the size of the buffer was already
determined when calling lstat(); the returned struct stat contains a
st_size field, containing the number of bytes needed to store the
symbolic link contents. This meant that to avoid using the tricky
define I only needed to use a dynamically allocated buffer instead of
a static one, of size stat.st_size (+1 when a null terminator is
needed).
To make sure that memory is always freed, I've wrapped the new dynamic
allocations in an std::unique_ptr. The pointer returned by realpath()
must be freed with free(), so a unique_ptr with a custom deleter that
calls free() on destruction was used.
To read more about why PATH_MAX leads to buggy code I'd suggest reading
something like this: <https://eklitzke.org/path-max-is-tricky>.
[POSIX.1-2008]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html
date's internal init_tzdb function iterates through the files provided
by the tz database, and init_tzdb contains a list of files that should
not be interpreted as being in TZif format.
The 2023d release of the tz database added a new file that is not in
TZif format, zonenow.tab. However, this file had not been added to the
ignore list.
This caused date to intepret the zonenow.tab file as a TZif file,
which caused assertions to fire in debug mode if the user attempted to
load its associated time_zone, causing load_header() to be invoked
on the file, which would find that it did not contain a 'TZif' magic
number.
This commit addresses the issue by adding the file to the ignore list.
The announcement on the tz database mailing list which describes the
addition of zonenow.tab can be found at this link:
https://mm.icann.org/pipermail/tz-announce/2023-December/000080.html
In commit commit 0b72599bd43f72d8935e507e25e4f0063f9bb34e there
was a change to read "version" in addition to "+VERSION", so that
file shold also be ignored when scanning/reading zonefiles.
Also before the above mentioed commit get_version() would return
"unknown" if not on __APPLE__ and the version file was not found.
Put back that behaviour, for all USE_OS_TZDB users.
This last change changes the behaviour for __APPLE__ from throwing
an exception to returning "unknown".
Co-authored-by: Lars Gullik Bjønnes <lbjonnes@cisco.com>
Clang 9 (in Visual Studio) complains about a mixed signed-unsigned comparison and an unused function.
Replace the naked `int` constant -1 by `std::size_t(-1)` with the same codegen as before (no curlies to avoid narrowing).
Guard the definition of `get_download_folder()` by the same condition as its call-site.
Signed-off-by: Daniela Engert <dani@ngrt.de>
VS2019 correctly points out that a conversion from a wide NTCS to std::string requires narrowing. This may result in an undesired string value. Implement the string conversion properly.
Signed-off-by: Daniela Engert <dani@ngrt.de>