From 8de9593bb9dc05cb1be593a237682e8707e41aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Wed, 25 Apr 2018 16:19:35 +0200 Subject: [PATCH] json_print: Fix hidden 64-bit type promotion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit print_uint() will silently promote its variable type to uint64_t, but there is nothing that ensures that the format string specifier passed along with it fits (and the function name suggest to pass "%u"). Fix this by changing print_uint() to use a native 'unsigned int' type, and introduce a separate print_u64() function for printing 64-bit values. All call sites that were actually printing 64-bit values using print_uint() are converted to use print_u64() instead. Since print_int() was already using native int types, just add a print_s64() to match, but don't convert any call sites. Signed-off-by: Toke Høiland-Jørgensen Signed-off-by: Kevin Darbyshire-Bryant --- include/json_print.h | 4 +++- include/json_writer.h | 12 ++++++---- ip/ipaddress.c | 62 +++++++++++++++++++++++++-------------------------- ip/ipmacsec.c | 8 +++---- ip/ipmroute.c | 6 ++--- lib/json_print.c | 4 +++- lib/json_writer.c | 30 +++++++++++++++++++++---- 7 files changed, 78 insertions(+), 48 deletions(-) --- a/include/json_print.h +++ b/include/json_print.h @@ -56,10 +56,12 @@ void close_json_array(enum output_type t print_color_##type_name(t, COLOR_NONE, key, fmt, value); \ } _PRINT_FUNC(int, int); +_PRINT_FUNC(s64, int64_t); _PRINT_FUNC(bool, bool); _PRINT_FUNC(null, const char*); _PRINT_FUNC(string, const char*); -_PRINT_FUNC(uint, uint64_t); +_PRINT_FUNC(uint, unsigned int); +_PRINT_FUNC(u64, uint64_t); _PRINT_FUNC(hu, unsigned short); _PRINT_FUNC(hex, unsigned int); _PRINT_FUNC(0xhex, unsigned int); --- a/include/json_writer.h +++ b/include/json_writer.h @@ -34,9 +34,11 @@ void jsonw_string(json_writer_t *self, c void jsonw_bool(json_writer_t *self, bool value); void jsonw_float(json_writer_t *self, double number); void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num); -void jsonw_uint(json_writer_t *self, uint64_t number); +void jsonw_uint(json_writer_t *self, unsigned int number); +void jsonw_u64(json_writer_t *self, uint64_t number); void jsonw_hu(json_writer_t *self, unsigned short number); -void jsonw_int(json_writer_t *self, int64_t number); +void jsonw_int(json_writer_t *self, int number); +void jsonw_s64(json_writer_t *self, int64_t number); void jsonw_null(json_writer_t *self); void jsonw_lluint(json_writer_t *self, unsigned long long int num); @@ -44,9 +46,11 @@ void jsonw_lluint(json_writer_t *self, u void jsonw_string_field(json_writer_t *self, const char *prop, const char *val); void jsonw_bool_field(json_writer_t *self, const char *prop, bool value); void jsonw_float_field(json_writer_t *self, const char *prop, double num); -void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num); +void jsonw_uint_field(json_writer_t *self, const char *prop, unsigned int num); +void jsonw_u64_field(json_writer_t *self, const char *prop, uint64_t num); void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num); -void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num); +void jsonw_int_field(json_writer_t *self, const char *prop, int num); +void jsonw_s64_field(json_writer_t *self, const char *prop, int64_t num); void jsonw_null_field(json_writer_t *self, const char *prop); void jsonw_lluint_field(json_writer_t *self, const char *prop, unsigned long long int num); --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -555,21 +555,21 @@ static void print_vf_stats64(FILE *fp, s /* RX stats */ open_json_object("rx"); - print_uint(PRINT_JSON, "bytes", NULL, + print_u64(PRINT_JSON, "bytes", NULL, rta_getattr_u64(vf[IFLA_VF_STATS_RX_BYTES])); - print_uint(PRINT_JSON, "packets", NULL, + print_u64(PRINT_JSON, "packets", NULL, rta_getattr_u64(vf[IFLA_VF_STATS_RX_PACKETS])); - print_uint(PRINT_JSON, "multicast", NULL, + print_u64(PRINT_JSON, "multicast", NULL, rta_getattr_u64(vf[IFLA_VF_STATS_MULTICAST])); - print_uint(PRINT_JSON, "broadcast", NULL, + print_u64(PRINT_JSON, "broadcast", NULL, rta_getattr_u64(vf[IFLA_VF_STATS_BROADCAST])); close_json_object(); /* TX stats */ open_json_object("tx"); - print_uint(PRINT_JSON, "tx_bytes", NULL, + print_u64(PRINT_JSON, "tx_bytes", NULL, rta_getattr_u64(vf[IFLA_VF_STATS_TX_BYTES])); - print_uint(PRINT_JSON, "tx_packets", NULL, + print_u64(PRINT_JSON, "tx_packets", NULL, rta_getattr_u64(vf[IFLA_VF_STATS_TX_PACKETS])); close_json_object(); close_json_object(); @@ -602,50 +602,50 @@ static void print_link_stats64(FILE *fp, /* RX stats */ open_json_object("rx"); - print_uint(PRINT_JSON, "bytes", NULL, s->rx_bytes); - print_uint(PRINT_JSON, "packets", NULL, s->rx_packets); - print_uint(PRINT_JSON, "errors", NULL, s->rx_errors); - print_uint(PRINT_JSON, "dropped", NULL, s->rx_dropped); - print_uint(PRINT_JSON, "over_errors", NULL, s->rx_over_errors); - print_uint(PRINT_JSON, "multicast", NULL, s->multicast); + print_u64(PRINT_JSON, "bytes", NULL, s->rx_bytes); + print_u64(PRINT_JSON, "packets", NULL, s->rx_packets); + print_u64(PRINT_JSON, "errors", NULL, s->rx_errors); + print_u64(PRINT_JSON, "dropped", NULL, s->rx_dropped); + print_u64(PRINT_JSON, "over_errors", NULL, s->rx_over_errors); + print_u64(PRINT_JSON, "multicast", NULL, s->multicast); if (s->rx_compressed) - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "compressed", NULL, s->rx_compressed); /* RX error stats */ if (show_stats > 1) { - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "length_errors", NULL, s->rx_length_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "crc_errors", NULL, s->rx_crc_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "frame_errors", NULL, s->rx_frame_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "fifo_errors", NULL, s->rx_fifo_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "missed_errors", NULL, s->rx_missed_errors); if (s->rx_nohandler) - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "nohandler", NULL, s->rx_nohandler); } close_json_object(); /* TX stats */ open_json_object("tx"); - print_uint(PRINT_JSON, "bytes", NULL, s->tx_bytes); - print_uint(PRINT_JSON, "packets", NULL, s->tx_packets); - print_uint(PRINT_JSON, "errors", NULL, s->tx_errors); - print_uint(PRINT_JSON, "dropped", NULL, s->tx_dropped); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "bytes", NULL, s->tx_bytes); + print_u64(PRINT_JSON, "packets", NULL, s->tx_packets); + print_u64(PRINT_JSON, "errors", NULL, s->tx_errors); + print_u64(PRINT_JSON, "dropped", NULL, s->tx_dropped); + print_u64(PRINT_JSON, "carrier_errors", NULL, s->tx_carrier_errors); - print_uint(PRINT_JSON, "collisions", NULL, s->collisions); + print_u64(PRINT_JSON, "collisions", NULL, s->collisions); if (s->tx_compressed) print_uint(PRINT_JSON, "compressed", @@ -653,20 +653,20 @@ static void print_link_stats64(FILE *fp, /* TX error stats */ if (show_stats > 1) { - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "aborted_errors", NULL, s->tx_aborted_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "fifo_errors", NULL, s->tx_fifo_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "window_errors", NULL, s->tx_window_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "heartbeat_errors", NULL, s->tx_heartbeat_errors); if (carrier_changes) - print_uint(PRINT_JSON, "carrier_changes", NULL, + print_u64(PRINT_JSON, "carrier_changes", NULL, rta_getattr_u32(carrier_changes)); } close_json_object(); --- a/lib/json_print.c +++ b/lib/json_print.c @@ -117,8 +117,10 @@ void close_json_array(enum output_type t } \ } _PRINT_FUNC(int, int); +_PRINT_FUNC(s64, int64_t); _PRINT_FUNC(hu, unsigned short); -_PRINT_FUNC(uint, uint64_t); +_PRINT_FUNC(uint, unsigned int); +_PRINT_FUNC(u64, uint64_t); _PRINT_FUNC(lluint, unsigned long long int); _PRINT_FUNC(float, double); #undef _PRINT_FUNC --- a/lib/json_writer.c +++ b/lib/json_writer.c @@ -215,7 +215,12 @@ void jsonw_hu(json_writer_t *self, unsig jsonw_printf(self, "%hu", num); } -void jsonw_uint(json_writer_t *self, uint64_t num) +void jsonw_uint(json_writer_t *self, unsigned int num) +{ + jsonw_printf(self, "%u", num); +} + +void jsonw_u64(json_writer_t *self, uint64_t num) { jsonw_printf(self, "%"PRIu64, num); } @@ -225,7 +230,12 @@ void jsonw_lluint(json_writer_t *self, u jsonw_printf(self, "%llu", num); } -void jsonw_int(json_writer_t *self, int64_t num) +void jsonw_int(json_writer_t *self, int num) +{ + jsonw_printf(self, "%d", num); +} + +void jsonw_s64(json_writer_t *self, int64_t num) { jsonw_printf(self, "%"PRId64, num); } @@ -258,12 +268,18 @@ void jsonw_float_field_fmt(json_writer_t jsonw_float_fmt(self, fmt, val); } -void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num) +void jsonw_uint_field(json_writer_t *self, const char *prop, unsigned int num) { jsonw_name(self, prop); jsonw_uint(self, num); } +void jsonw_u64_field(json_writer_t *self, const char *prop, uint64_t num) +{ + jsonw_name(self, prop); + jsonw_u64(self, num); +} + void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num) { jsonw_name(self, prop); @@ -278,12 +294,18 @@ void jsonw_lluint_field(json_writer_t *s jsonw_lluint(self, num); } -void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num) +void jsonw_int_field(json_writer_t *self, const char *prop, int num) { jsonw_name(self, prop); jsonw_int(self, num); } +void jsonw_s64_field(json_writer_t *self, const char *prop, int64_t num) +{ + jsonw_name(self, prop); + jsonw_s64(self, num); +} + void jsonw_null_field(json_writer_t *self, const char *prop) { jsonw_name(self, prop);