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:
commit
5f494e8fa6
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user