-
Notifications
You must be signed in to change notification settings - Fork 665
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stop using PATH_MAX #744
base: master
Are you sure you want to change the base?
Stop using PATH_MAX #744
Conversation
67eb652
to
d3e57ec
Compare
This patch is currently being deployed in the howardhinnant-date Debian package, and allows tests to pass on 20 different architectures, including GNU Hurd which doesn't define |
d3e57ec
to
f2cc75e
Compare
@Tachi107 wow, you packaged the libdate! Wonder how could I miss it! I did package it in 2020 but I decided not to upload it because seemingly only Kodi used it. |
@basilgello nice to hear! Please let me know if you find any issues with it :) |
f2cc75e
to
509ccf4
Compare
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
509ccf4
to
e762d92
Compare
@Tachi107 Can you please upload the package to bullseye-bpo? |
I don't have the permission to do it yet, but while trying to check if doable I've discovered a small issue (see #754 (comment)). Once the issue is fixed and I'm allowed to backport packages, the package will be in bullseye-backports :) |
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:realpath()
was used, I've changed the code to use its POSIX.1-2008's new behaviour, where passing a null pointer as theresolved_name
buffer results inrealpath()
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.readlink()
was used, the size of the buffer was already determined when callinglstat()
; the returnedstruct stat
contains ast_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 acalloc()
'd buffer instead of a static one, of sizest_size + 1
asst_size
doesn't account for the null terminator of C strings.To make sure that memory is always freed, I've wrapped the new dynamic allocations in an
std::unique_ptr
with a deleter that callsfree()
on destruction.To read more about why
PATH_MAX
leads to buggy code I'd suggest reading something like this: eklitzke.org/path-max-is-tricky