mirror of
https://github.com/libgit2/libgit2.git
synced 2026-06-22 06:26:26 +00:00
futils: fix undefined behavior in O_FSYNC fallback definition
The fallback definition of O_FSYNC uses `(1 << 31)`, which is undefined
behavior in C. The literal `1` is a signed int, and left-shifting into
the sign bit of a signed integer is undefined per the C standard.
This causes crashes on arm64 Linux with musl libc (which doesn't define
O_FSYNC), manifesting as:
thread panic: left shift of 1 by 31 places cannot be represented
in type 'int'
Fall back to O_SYNC when available, since it is the POSIX standard name
for the same flag. On platforms where neither is defined (e.g. Windows),
use (1 << 30) as a sentinel value that avoids the sign bit.
This commit is contained in:
committed by
Chris Hoffman (Claude)
parent
86c7738ca6
commit
46208be836
@@ -32,9 +32,17 @@ extern int git_futils_readbuffer_fd(git_str *obj, git_file fd, size_t len);
|
||||
|
||||
/* Additional constants for `git_futils_writebuffer`'s `open_flags`. We
|
||||
* support these internally and they will be removed before the `open` call.
|
||||
*
|
||||
* Not all platforms define O_FSYNC. Fall back to O_SYNC (the POSIX
|
||||
* standard name; O_FSYNC is a non-standard alias) when available,
|
||||
* otherwise use a sentinel value that won't collide with real open
|
||||
* flags. Avoid (1 << 31) since left-shifting into the sign bit of
|
||||
* a signed int is undefined behavior.
|
||||
*/
|
||||
#ifndef O_FSYNC
|
||||
# define O_FSYNC (1 << 31)
|
||||
#if !defined(O_FSYNC) && defined(O_SYNC)
|
||||
# define O_FSYNC O_SYNC
|
||||
#elif !defined(O_FSYNC)
|
||||
# define O_FSYNC (1 << 30)
|
||||
#endif
|
||||
|
||||
extern int git_futils_writebuffer(
|
||||
|
||||
Reference in New Issue
Block a user