From ea664722d413eca98c1f92d1b06fb06272283452 Mon Sep 17 00:00:00 2001 From: Corey Farrell Date: Wed, 28 Feb 2018 04:55:48 -0500 Subject: [PATCH] Build: Add JANSSON_ATTRS macro. This macro is used to conditionally generate GCC/CLANG __attribute__ declarations if supported. This allows the compiler to produce warnings on certain incorrect usages. json_sprintf and json_vsprintf will produce warnings on invalid format string. Many functions will produce a warning if the result is unused. Specifically functions which allocate new objects will warn if the result is ignored as this always results in a memory leak. --- src/hashtable.h | 2 +- src/jansson.h | 38 ++++++++++++++++++++++---------------- src/jansson_private.h | 8 ++++---- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/hashtable.h b/src/hashtable.h index d4c32ae..c112834 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -55,7 +55,7 @@ typedef struct hashtable { * * Returns 0 on success, -1 on error (out of memory). */ -int hashtable_init(hashtable_t *hashtable); +int hashtable_init(hashtable_t *hashtable) JANSSON_ATTRS(warn_unused_result); /** * hashtable_close - Release all resources used by a hashtable object diff --git a/src/jansson.h b/src/jansson.h index f8d57bd..430e8c7 100644 --- a/src/jansson.h +++ b/src/jansson.h @@ -39,6 +39,12 @@ extern "C" { #define JANSSON_THREAD_SAFE_REFCOUNT 1 #endif +#if defined(__GNUC__) || defined(__clang__) +#define JANSSON_ATTRS(...) __attribute__((__VA_ARGS__)) +#else +#define JANSSON_ATTRS(...) +#endif + /* types */ typedef enum { @@ -185,7 +191,7 @@ static JSON_INLINE enum json_error_code json_error_code(const json_error_t *e) { void json_object_seed(size_t seed); size_t json_object_size(const json_t *object); -json_t *json_object_get(const json_t *object, const char *key); +json_t *json_object_get(const json_t *object, const char *key) JANSSON_ATTRS(warn_unused_result); int json_object_set_new(json_t *object, const char *key, json_t *value); int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value); int json_object_del(json_t *object, const char *key); @@ -237,7 +243,7 @@ int json_object_iter_set(json_t *object, void *iter, json_t *value) } size_t json_array_size(const json_t *array); -json_t *json_array_get(const json_t *array, size_t index); +json_t *json_array_get(const json_t *array, size_t index) JANSSON_ATTRS(warn_unused_result); int json_array_set_new(json_t *array, size_t index, json_t *value); int json_array_append_new(json_t *array, json_t *value); int json_array_insert_new(json_t *array, size_t index, json_t *value); @@ -278,9 +284,9 @@ int json_real_set(json_t *real, double value); /* pack, unpack */ -json_t *json_pack(const char *fmt, ...); -json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...); -json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap); +json_t *json_pack(const char *fmt, ...) JANSSON_ATTRS(warn_unused_result); +json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...) JANSSON_ATTRS(warn_unused_result); +json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap) JANSSON_ATTRS(warn_unused_result); #define JSON_VALIDATE_ONLY 0x1 #define JSON_STRICT 0x2 @@ -291,8 +297,8 @@ int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, const char /* sprintf */ -json_t *json_sprintf(const char *fmt, ...); -json_t *json_vsprintf(const char *fmt, va_list ap); +json_t *json_sprintf(const char *fmt, ...) JANSSON_ATTRS(warn_unused_result, format(printf, 1, 2)); +json_t *json_vsprintf(const char *fmt, va_list ap) JANSSON_ATTRS(warn_unused_result, format(printf, 1, 0)); /* equality */ @@ -302,8 +308,8 @@ int json_equal(const json_t *value1, const json_t *value2); /* copying */ -json_t *json_copy(json_t *value); -json_t *json_deep_copy(const json_t *value); +json_t *json_copy(json_t *value) JANSSON_ATTRS(warn_unused_result); +json_t *json_deep_copy(const json_t *value) JANSSON_ATTRS(warn_unused_result); /* decoding */ @@ -316,12 +322,12 @@ json_t *json_deep_copy(const json_t *value); typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data); -json_t *json_loads(const char *input, size_t flags, json_error_t *error); -json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error); -json_t *json_loadf(FILE *input, size_t flags, json_error_t *error); -json_t *json_loadfd(int input, size_t flags, json_error_t *error); -json_t *json_load_file(const char *path, size_t flags, json_error_t *error); -json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error); +json_t *json_loads(const char *input, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result); +json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result); +json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result); +json_t *json_loadfd(int input, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result); +json_t *json_load_file(const char *path, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result); +json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result); /* encoding */ @@ -339,7 +345,7 @@ json_t *json_load_callback(json_load_callback_t callback, void *data, size_t fla typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data); -char *json_dumps(const json_t *json, size_t flags); +char *json_dumps(const json_t *json, size_t flags) JANSSON_ATTRS(warn_unused_result); size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags); int json_dumpf(const json_t *json, FILE *output, size_t flags); int json_dumpfd(const json_t *json, int output, size_t flags); diff --git a/src/jansson_private.h b/src/jansson_private.h index d19cf9c..bf86c57 100644 --- a/src/jansson_private.h +++ b/src/jansson_private.h @@ -84,11 +84,11 @@ int jsonp_strtod(strbuffer_t *strbuffer, double *out); int jsonp_dtostr(char *buffer, size_t size, double value, int prec); /* Wrappers for custom memory functions */ -void* jsonp_malloc(size_t size); +void* jsonp_malloc(size_t size) JANSSON_ATTRS(warn_unused_result); void jsonp_free(void *ptr); -char *jsonp_strndup(const char *str, size_t length); -char *jsonp_strdup(const char *str); -char *jsonp_strndup(const char *str, size_t len); +char *jsonp_strndup(const char *str, size_t length) JANSSON_ATTRS(warn_unused_result); +char *jsonp_strdup(const char *str) JANSSON_ATTRS(warn_unused_result); +char *jsonp_strndup(const char *str, size_t len) JANSSON_ATTRS(warn_unused_result); /* Windows compatibility */