From a5e8f222463bd20aa216c1ffcff6e066a8a40483 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Fri, 20 Mar 2015 18:19:06 +0100 Subject: [PATCH] snprintf style fixed buffers --- src/dict.c | 25 +++++++++++++++++++++++++ src/getdns/getdns_extra.h | 9 ++++++++- src/gldns/gbuffer.c | 4 ++-- src/gldns/gbuffer.h | 25 ++++++++++++++++++------- src/libgetdns.symbols | 7 +++++-- 5 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/dict.c b/src/dict.c index 439ec0e6..e35a1f44 100644 --- a/src/dict.c +++ b/src/dict.c @@ -914,6 +914,18 @@ getdns_pretty_print_dict(const struct getdns_dict *dict) return ret; } /* getdns_pretty_print_dict */ +int +getdns_pretty_snprint_dict(char *str, size_t size, const getdns_dict *dict) +{ + gldns_buffer buf; + + if (!dict) return -1; + + gldns_buffer_init_frm_data(&buf, str, size); + return getdns_pp_dict(&buf, 0, dict) < 0 + ? -1 : gldns_buffer_position(&buf); +} + char * getdns_pretty_print_list(const getdns_list *list) { @@ -936,6 +948,19 @@ getdns_pretty_print_list(const getdns_list *list) return ret; } +int +getdns_pretty_snprint_list(char *str, size_t size, const getdns_list *list) +{ + gldns_buffer buf; + + if (!list) return -1; + + gldns_buffer_init_frm_data(&buf, str, size); + return getdns_pp_list(&buf, 0, list, 0) < 0 + ? -1 : gldns_buffer_position(&buf); +} + + getdns_return_t getdns_dict_remove_name(struct getdns_dict *this_dict, const char *name) { diff --git a/src/getdns/getdns_extra.h b/src/getdns/getdns_extra.h index 874ef64d..2b231c6b 100644 --- a/src/getdns/getdns_extra.h +++ b/src/getdns/getdns_extra.h @@ -187,7 +187,14 @@ getdns_context_get_edns_version(getdns_context *context, uint8_t* value); getdns_return_t getdns_context_get_edns_do_bit(getdns_context *context, uint8_t* value); -char *getdns_pretty_print_list(const getdns_list *some_list); +int +getdns_pretty_snprint_dict(char *str, size_t size, const getdns_dict *dict); + +char * +getdns_pretty_print_list(const getdns_list *some_list); + +int +getdns_pretty_snprint_list(char *str, size_t size, const getdns_list *list); #ifdef __cplusplus } diff --git a/src/gldns/gbuffer.c b/src/gldns/gbuffer.c index 26d092e5..a73281c5 100644 --- a/src/gldns/gbuffer.c +++ b/src/gldns/gbuffer.c @@ -74,7 +74,7 @@ gldns_buffer_set_capacity(gldns_buffer *buffer, size_t capacity) void *data; gldns_buffer_invariant(buffer); - assert(buffer->_position <= capacity); + assert(buffer->_position <= capacity && !buffer->_fixed); data = (uint8_t *) realloc(buffer->_data, capacity); if (!data) { @@ -126,7 +126,7 @@ gldns_buffer_printf(gldns_buffer *buffer, const char *format, ...) if (written == -1) { buffer->_status_err = 1; return -1; - } else if ((size_t) written >= remaining) { + } else if (!buffer->_fixed && (size_t) written >= remaining) { if (!gldns_buffer_reserve(buffer, (size_t) written + 1)) { buffer->_status_err = 1; return -1; diff --git a/src/gldns/gbuffer.h b/src/gldns/gbuffer.h index 70ef08b2..56e19c78 100644 --- a/src/gldns/gbuffer.h +++ b/src/gldns/gbuffer.h @@ -134,7 +134,7 @@ INLINE void gldns_buffer_invariant(gldns_buffer *buffer) { assert(buffer != NULL); - assert(buffer->_position <= buffer->_limit); + assert(buffer->_position <= buffer->_limit || buffer->_fixed); assert(buffer->_limit <= buffer->_capacity); assert(buffer->_data != NULL); } @@ -231,7 +231,7 @@ gldns_buffer_position(gldns_buffer *buffer) INLINE void gldns_buffer_set_position(gldns_buffer *buffer, size_t mark) { - assert(mark <= buffer->_limit); + assert(mark <= buffer->_limit || buffer->_fixed); buffer->_position = mark; } @@ -245,7 +245,7 @@ gldns_buffer_set_position(gldns_buffer *buffer, size_t mark) INLINE void gldns_buffer_skip(gldns_buffer *buffer, ssize_t count) { - assert(buffer->_position + count <= buffer->_limit); + assert(buffer->_position + count <= buffer->_limit || buffer->_fixed); buffer->_position += count; } @@ -317,7 +317,7 @@ int gldns_buffer_reserve(gldns_buffer *buffer, size_t amount); INLINE uint8_t * gldns_buffer_at(const gldns_buffer *buffer, size_t at) { - assert(at <= buffer->_limit); + assert(at <= buffer->_limit || buffer->_fixed); return buffer->_data + at; } @@ -353,6 +353,7 @@ gldns_buffer_end(gldns_buffer *buffer) INLINE uint8_t * gldns_buffer_current(gldns_buffer *buffer) { + assert(buffer->_position <= buffer->_limit || buffer->_fixed); return gldns_buffer_at(buffer, buffer->_position); } @@ -367,8 +368,7 @@ INLINE size_t gldns_buffer_remaining_at(gldns_buffer *buffer, size_t at) { gldns_buffer_invariant(buffer); - assert(at <= buffer->_limit); - return buffer->_limit - at; + return at < buffer->_limit ? buffer->_limit - at : 0; } /** @@ -420,7 +420,15 @@ gldns_buffer_available(gldns_buffer *buffer, size_t count) INLINE void gldns_buffer_write_at(gldns_buffer *buffer, size_t at, const void *data, size_t count) { - assert(gldns_buffer_available_at(buffer, at, count)); + if (!buffer->_fixed) + assert(gldns_buffer_available_at(buffer, at, count)); + else if (gldns_buffer_remaining_at(buffer, at) == 0) + return; + else if (count > gldns_buffer_remaining_at(buffer, at)) { + memcpy(buffer->_data + at, data, + gldns_buffer_remaining_at(buffer, at)); + return; + } memcpy(buffer->_data + at, data, count); } @@ -469,6 +477,7 @@ gldns_buffer_write_string(gldns_buffer *buffer, const char *str) INLINE void gldns_buffer_write_u8_at(gldns_buffer *buffer, size_t at, uint8_t data) { + if (buffer->_fixed && at + sizeof(data) > buffer->_limit) return; assert(gldns_buffer_available_at(buffer, at, sizeof(data))); buffer->_data[at] = data; } @@ -494,6 +503,7 @@ gldns_buffer_write_u8(gldns_buffer *buffer, uint8_t data) INLINE void gldns_buffer_write_u16_at(gldns_buffer *buffer, size_t at, uint16_t data) { + if (buffer->_fixed && at + sizeof(data) > buffer->_limit) return; assert(gldns_buffer_available_at(buffer, at, sizeof(data))); gldns_write_uint16(buffer->_data + at, data); } @@ -519,6 +529,7 @@ gldns_buffer_write_u16(gldns_buffer *buffer, uint16_t data) INLINE void gldns_buffer_write_u32_at(gldns_buffer *buffer, size_t at, uint32_t data) { + if (buffer->_fixed && at + sizeof(data) > buffer->_limit) return; assert(gldns_buffer_available_at(buffer, at, sizeof(data))); gldns_write_uint32(buffer->_data + at, data); } diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index d8740b15..7a1b0828 100644 --- a/src/libgetdns.symbols +++ b/src/libgetdns.symbols @@ -97,8 +97,6 @@ getdns_context_process_async getdns_context_set_eventloop getdns_context_detach_eventloop getdns_context_run -plain_mem_funcs_user_arg -priv_getdns_context_mf getdns_context_get_resolution_type getdns_context_get_namespaces getdns_context_get_dns_transport @@ -115,3 +113,8 @@ getdns_context_get_edns_maximum_udp_payload_size getdns_context_get_edns_extended_rcode getdns_context_get_edns_version getdns_context_get_edns_do_bit +getdns_pretty_snprint_dict +getdns_pretty_print_list +getdns_pretty_snprint_list +plain_mem_funcs_user_arg +priv_getdns_context_mf