diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-08-18 14:03:10 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-08-19 09:19:03 +0200 |
commit | 3832cb90ba1557d5fe0e24f0b280bfefe44a2406 (patch) | |
tree | d1f482858d63af7a7971c535f4321462171b5195 /src | |
parent | 12a7f04a2b9135a4751dba71e2f688525d7c93e7 (diff) | |
download | systemd-3832cb90ba1557d5fe0e24f0b280bfefe44a2406.tar.gz |
stdio-util: give snprintf_ok() some love
as per docs snprintf() can fail in which case it returns -1. The
snprintf_ok() macro so far unconditionally cast the return value of
snprintf() to size_t, which would turn -1 to (size_t) INT_MAX,
presumably, at least on 2 complements system.
Let's be more careful with types here, and first check if return value
is positive, before casting to size_t.
Also, while we are at it, let's return the input buffer as return value
or NULL instead of 1 or 0. It's marginally more useful, but more
importantly, is more inline with most of our other codebase that
typically doesn't use booleans to signal success.
All uses of snprintf_ok() don't care for the type of the return, hence
this change does not propagate anywhere else.
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/stdio-util.h | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/src/basic/stdio-util.h b/src/basic/stdio-util.h index 0ed48b3fd4..69d7062ec6 100644 --- a/src/basic/stdio-util.h +++ b/src/basic/stdio-util.h @@ -9,8 +9,13 @@ #include "macro.h" #include "memory-util.h" -#define snprintf_ok(buf, len, fmt, ...) \ - ((size_t) snprintf(buf, len, fmt, __VA_ARGS__) < (len)) +#define snprintf_ok(buf, len, fmt, ...) \ + ({ \ + char *_buf = (buf); \ + size_t _len = (len); \ + int _snpf = snprintf(_buf, _len, (fmt), __VA_ARGS__); \ + _snpf >= 0 && (size_t) _snpf < _len ? _buf : NULL; \ + }) #define xsprintf(buf, fmt, ...) \ assert_message_se(snprintf_ok(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__), "xsprintf: " #buf "[] must be big enough") |