1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-28 02:50:16 +03:00

macro-fundamental: add _nonnull_if_nonzero_ and use it in basic/ (#36395)

This commit is contained in:
Yu Watanabe 2025-02-16 20:21:08 +09:00 committed by GitHub
commit 5f494e8fa6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 60 additions and 43 deletions

View File

@ -46,7 +46,7 @@
int efi_get_variable(const char *variable, uint32_t *attribute, void **ret_value, size_t *ret_size);
int efi_get_variable_string(const char *variable, char **ret);
int efi_get_variable_path(const char *variable, char **ret);
int efi_set_variable(const char *variable, const void *value, size_t size);
int efi_set_variable(const char *variable, const void *value, size_t size) _nonnull_if_nonzero_(2, 3);
int efi_set_variable_string(const char *variable, const char *p);
bool is_efi_boot(void);

View File

@ -80,10 +80,15 @@ char* cescape_length(const char *s, size_t n) {
const char *f;
char *r, *t;
/* Does C style string escaping. May be reversed with cunescape(). */
assert(s || n == 0);
/* Does C style string escaping. May be reversed with
* cunescape(). */
if (n == SIZE_MAX)
n = strlen(s);
if (n > (SIZE_MAX - 1) / 4)
return NULL;
r = new(char, n*4 + 1);
if (!r)
@ -97,12 +102,6 @@ char* cescape_length(const char *s, size_t n) {
return r;
}
char* cescape(const char *s) {
assert(s);
return cescape_length(s, strlen(s));
}
int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit, bool accept_nul) {
int r = 1;
@ -449,7 +448,7 @@ char* escape_non_printable_full(const char *str, size_t console_width, XEscapeFl
char* octescape(const char *s, size_t len) {
char *buf, *t;
/* Escapes all chars in bad, in addition to \ and " chars, in \nnn style escaping. */
/* Escapes \ and " chars, in \nnn style escaping. */
assert(s || len == 0);
@ -479,13 +478,19 @@ char* octescape(const char *s, size_t len) {
return buf;
}
char* decescape(const char *s, const char *bad, size_t len) {
char* decescape(const char *s, size_t len, const char *bad) {
char *buf, *t;
/* Escapes all chars in bad, in addition to \ and " chars, in \nnn decimal style escaping. */
assert(s || len == 0);
if (len == SIZE_MAX)
len = strlen(s);
if (len > (SIZE_MAX - 1) / 4)
return NULL;
t = buf = new(char, len * 4 + 1);
if (!buf)
return NULL;

View File

@ -41,9 +41,11 @@ typedef enum ShellEscapeFlags {
SHELL_ESCAPE_EMPTY = 1 << 2, /* Format empty arguments as "". */
} ShellEscapeFlags;
char* cescape(const char *s);
char* cescape_length(const char *s, size_t n);
int cescape_char(char c, char *buf);
char* cescape_length(const char *s, size_t n) _nonnull_if_nonzero_(1, 2);
static inline char* cescape(const char *s) {
return cescape_length(s, SIZE_MAX);
}
int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit, bool accept_nul);
@ -65,7 +67,7 @@ static inline char* xescape(const char *s, const char *bad) {
return xescape_full(s, bad, SIZE_MAX, 0);
}
char* octescape(const char *s, size_t len);
char* decescape(const char *s, const char *bad, size_t len);
char* decescape(const char *s, size_t len, const char *bad) _nonnull_if_nonzero_(1, 2);
char* escape_non_printable_full(const char *str, size_t console_width, XEscapeFlags flags);
char* shell_escape(const char *s, const char *bad);

View File

@ -17,8 +17,8 @@ int undecchar(char c) _const_;
char hexchar(int x) _const_;
int unhexchar(char c) _const_;
char* hexmem(const void *p, size_t l);
int unhexmem_full(const char *p, size_t l, bool secure, void **ret_data, size_t *ret_size);
char* hexmem(const void *p, size_t l) _nonnull_if_nonzero_(1, 2);
int unhexmem_full(const char *p, size_t l, bool secure, void **ret_data, size_t *ret_size) _nonnull_if_nonzero_(1, 2);
static inline int unhexmem(const char *p, void **ret_data, size_t *ret_size) {
return unhexmem_full(p, SIZE_MAX, false, ret_data, ret_size);
}
@ -30,10 +30,10 @@ char base64char(int x) _const_;
char urlsafe_base64char(int x) _const_;
int unbase64char(char c) _const_;
char* base32hexmem(const void *p, size_t l, bool padding);
int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *len);
char* base32hexmem(const void *p, size_t l, bool padding) _nonnull_if_nonzero_(1, 2);
int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *len) _nonnull_if_nonzero_(1, 2);
ssize_t base64mem_full(const void *p, size_t l, size_t line_break, char **ret);
ssize_t base64mem_full(const void *p, size_t l, size_t line_break, char **ret) _nonnull_if_nonzero_(1, 2);
static inline ssize_t base64mem(const void *p, size_t l, char **ret) {
return base64mem_full(p, l, SIZE_MAX, ret);
}
@ -45,9 +45,9 @@ ssize_t base64_append(
size_t l,
size_t margin,
size_t width);
int unbase64mem_full(const char *p, size_t l, bool secure, void **ret_data, size_t *ret_size);
int unbase64mem_full(const char *p, size_t l, bool secure, void **ret_data, size_t *ret_size) _nonnull_if_nonzero_(1, 2);
static inline int unbase64mem(const char *p, void **ret_data, size_t *ret_size) {
return unbase64mem_full(p, SIZE_MAX, false, ret_data, ret_size);
}
void hexdump(FILE *f, const void *p, size_t s);
void hexdump(FILE *f, const void *p, size_t s) _nonnull_if_nonzero_(2, 3);

View File

@ -15,14 +15,14 @@ int flush_fd(int fd);
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
int loop_write_full(int fd, const void *buf, size_t nbytes, usec_t timeout);
int loop_write_full(int fd, const void *buf, size_t nbytes, usec_t timeout) _nonnull_if_nonzero_(2, 3);
static inline int loop_write(int fd, const void *buf, size_t nbytes) {
return loop_write_full(fd, buf, nbytes, 0);
}
int pipe_eof(int fd);
int ppoll_usec(struct pollfd *fds, size_t nfds, usec_t timeout);
int ppoll_usec(struct pollfd *fds, size_t nfds, usec_t timeout) _nonnull_if_nonzero_(1, 2);
int fd_wait_for_event(int fd, int event, usec_t timeout);
ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length);

View File

@ -12,9 +12,9 @@
extern const struct iovec iovec_nul_byte; /* Points to a single NUL byte */
extern const struct iovec iovec_empty; /* Points to an empty, but valid (i.e. non-NULL) pointer */
size_t iovec_total_size(const struct iovec *iovec, size_t n);
size_t iovec_total_size(const struct iovec *iovec, size_t n) _nonnull_if_nonzero_(1, 2);
bool iovec_increment(struct iovec *iovec, size_t n, size_t k);
bool iovec_increment(struct iovec *iovec, size_t n, size_t k) _nonnull_if_nonzero_(1, 2);
static inline struct iovec* iovec_make_string(struct iovec *iovec, const char *s) {
assert(iovec);
@ -42,7 +42,7 @@ static inline void iovec_done_erase(struct iovec *iovec) {
char* set_iovec_string_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value);
char* set_iovec_string_field_free(struct iovec *iovec, size_t *n_iovec, const char *field, char *value);
void iovec_array_free(struct iovec *iovec, size_t n_iovec);
void iovec_array_free(struct iovec *iovec, size_t n_iovec) _nonnull_if_nonzero_(1, 2);
static inline int iovec_memcmp(const struct iovec *a, const struct iovec *b) {
@ -55,7 +55,7 @@ static inline int iovec_memcmp(const struct iovec *a, const struct iovec *b) {
b ? b->iov_len : 0);
}
static inline struct iovec *iovec_memdup(const struct iovec *source, struct iovec *ret) {
static inline struct iovec* iovec_memdup(const struct iovec *source, struct iovec *ret) {
assert(ret);
if (!iovec_is_set(source))

View File

@ -6,6 +6,8 @@
#include <stdint.h>
#include <sys/types.h>
#include "macro.h"
int memfd_create_wrapper(const char *name, unsigned mode);
int memfd_new_full(const char *name, unsigned extra_flags);
@ -13,7 +15,7 @@ static inline int memfd_new(const char *name) {
return memfd_new_full(name, 0);
}
int memfd_new_and_seal(const char *name, const void *data, size_t sz);
int memfd_new_and_seal(const char *name, const void *data, size_t sz) _nonnull_if_nonzero_(2, 3);
static inline int memfd_new_and_seal_string(const char *name, const char *s) {
return memfd_new_and_seal(name, s, SIZE_MAX);
}

View File

@ -40,7 +40,7 @@ bool memeqbyte(uint8_t byte, const void *data, size_t length) {
return memcmp(data, p + 16, length) == 0;
}
void *memdup_reverse(const void *mem, size_t size) {
void* memdup_reverse(const void *mem, size_t size) {
assert(mem);
assert(size != 0);

View File

@ -59,19 +59,19 @@ static inline int memcmp_nn(const void *s1, size_t n1, const void *s2, size_t n2
#define zero(x) (memzero(&(x), sizeof(x)))
bool memeqbyte(uint8_t byte, const void *data, size_t length);
bool memeqbyte(uint8_t byte, const void *data, size_t length) _nonnull_if_nonzero_(2, 3);
#define memeqzero(data, length) memeqbyte(0x00, data, length)
#define eqzero(x) memeqzero(x, sizeof(x))
static inline void *mempset(void *s, int c, size_t n) {
static inline void* mempset(void *s, int c, size_t n) {
memset(s, c, n);
return (uint8_t*)s + n;
return (uint8_t*) s + n;
}
/* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */
static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
static inline void* memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
if (needlelen <= 0)
return (void*) haystack;
@ -85,7 +85,7 @@ static inline void *memmem_safe(const void *haystack, size_t haystacklen, const
return memmem(haystack, haystacklen, needle, needlelen);
}
static inline void *mempmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
static inline void* mempmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
const uint8_t *p;
p = memmem_safe(haystack, haystacklen, needle, needlelen);
@ -116,4 +116,4 @@ static inline void erase_char(char *p) {
}
/* Makes a copy of the buffer with reversed order of bytes */
void *memdup_reverse(const void *mem, size_t size);
void* memdup_reverse(const void *mem, size_t size);

View File

@ -6,8 +6,10 @@
#include <stdint.h>
#include <sys/uio.h>
void random_bytes(void *p, size_t n); /* Returns random bytes suitable for most uses, but may be insecure sometimes. */
int crypto_random_bytes(void *p, size_t n); /* Returns secure random bytes after waiting for the RNG to initialize. */
#include "macro.h"
void random_bytes(void *p, size_t n) _nonnull_if_nonzero_(1, 2); /* Returns random bytes suitable for most uses, but may be insecure sometimes. */
int crypto_random_bytes(void *p, size_t n) _nonnull_if_nonzero_(1, 2); /* Returns secure random bytes after waiting for the RNG to initialize. */
int crypto_random_bytes_allocate_iovec(size_t n, struct iovec *ret);
static inline uint64_t random_u64(void) {
@ -29,6 +31,6 @@ static inline uint32_t random_u32(void) {
size_t random_pool_size(void);
int random_write_entropy(int fd, const void *seed, size_t size, bool credit);
int random_write_entropy(int fd, const void *seed, size_t size, bool credit) _nonnull_if_nonzero_(2, 3);
uint64_t random_u64_range(uint64_t max);

View File

@ -107,7 +107,7 @@ static inline const char* empty_or_dash_to_null(const char *p) {
char* first_word(const char *s, const char *word) _pure_;
char* strprepend(char **x, const char *s);
char* strextendn(char **x, const char *s, size_t l);
char* strextendn(char **x, const char *s, size_t l) _nonnull_if_nonzero_(2, 3);
#define strjoin(a, ...) strextend_with_separator_internal(NULL, NULL, a, __VA_ARGS__, NULL)
@ -223,7 +223,7 @@ static inline int free_and_strdup_warn(char **p, const char *s) {
return log_oom();
return r;
}
int free_and_strndup(char **p, const char *s, size_t l);
int free_and_strndup(char **p, const char *s, size_t l) _nonnull_if_nonzero_(2, 3);
int strdup_to_full(char **ret, const char *src);
static inline int strdup_to(char **ret, const char *src) {

View File

@ -33,7 +33,7 @@ char** strv_free_erase(char **l);
DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free_erase);
#define _cleanup_strv_free_erase_ _cleanup_(strv_free_erasep)
void strv_free_many(char ***strvs, size_t n);
void strv_free_many(char ***strvs, size_t n) _nonnull_if_nonzero_(1, 2);
char** strv_copy_n(char * const *l, size_t n);
static inline char** strv_copy(char * const *l) {

View File

@ -112,6 +112,12 @@
# define _fallthrough_ __attribute__((__fallthrough__))
#endif
#if __GNUC__ >= 15
# define _nonnull_if_nonzero_(p, n) __attribute__((nonnull_if_nonzero(p, n)))
#else
# define _nonnull_if_nonzero_(p, n)
#endif
#define XSTRINGIFY(x) #x
#define STRINGIFY(x) XSTRINGIFY(x)

View File

@ -931,7 +931,7 @@ static char *format_svc_param_value(DnsSvcParam *i) {
return strv_join(values_strv, ",");
}
default: {
value = decescape((char *)&i->value, " ,", i->length);
value = decescape((char*) &i->value, i->length, " ,");
if (!value)
return NULL;
break;

View File

@ -242,7 +242,7 @@ TEST(octescape) {
static void test_decescape_one(const char *s, const char *bad, const char *expected) {
_cleanup_free_ char *ret = NULL;
assert_se(ret = decescape(s, bad, strlen_ptr(s)));
assert_se(ret = decescape(s, s ? SIZE_MAX : 0, bad));
log_debug("decescape(\"%s\") → \"%s\" (expected: \"%s\")", strnull(s), ret, expected);
ASSERT_STREQ(ret, expected);
}