From: Arran Cudbard-Bell Date: Fri, 18 Nov 2016 23:24:14 +0000 (-0500) Subject: Overload %p printk style X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fc15c4911130beaa4eca48d13ccb211c6cf040ce;p=thirdparty%2Ffreeradius-server.git Overload %p printk style --- diff --git a/src/include/log.h b/src/include/log.h index 46ed2bed13c..ffa0c6c5cd1 100644 --- a/src/include/log.h +++ b/src/include/log.h @@ -112,7 +112,7 @@ bool radlog_debug_enabled(log_type_t type, log_lvl_t lvl, REQUEST *request) CC_HINT(nonnull); void vradlog_request(log_type_t type, log_lvl_t lvl, REQUEST *request, char const *msg, va_list ap) - CC_HINT(nonnull (3, 4)); + CC_HINT(format (printf, 4, 0)) CC_HINT(nonnull (3, 4)); void radlog_request(log_type_t type, log_lvl_t lvl, REQUEST *request, char const *msg, ...) CC_HINT(format (printf, 4, 5)) CC_HINT(nonnull (3, 4)); diff --git a/src/lib/print.c b/src/lib/print.c index 5fb30a07615..9500c994ad8 100644 --- a/src/lib/print.c +++ b/src/lib/print.c @@ -399,13 +399,27 @@ char *fr_asprint(TALLOC_CTX *ctx, char const *in, ssize_t inlen, char quote) } DIAG_OFF(format-nonliteral) -/** Special version of printf which supports %b and %v +/** Special version of vasprintf which implements custom format specifiers * * @todo Do something sensible with 'n$', though it's probably not actually used - * anywhere in the server. + * anywhere in our code base. * - * - %b takes a talloced binary buffer and prints it as hex. - * The length of the buffer is determined with a cal + * - %pH takes a talloced binary buffer and prints it as hex. The length of the + * buffer is determined with a call to talloc_array_length() + * + * - %pV prints a value box as a string. + * + * This breaks strict compatibility with printf but allows us to continue using + * the static format string and argument type validation. + * + * This same idea is used in Linux for the printk function. + * + * @param[in] ctx to allocate buffer in. + * @param[in] fmt string. + * @param[in] ap variadic argument list. + * @return + * - The result of string interpolation. + * - NULL if OOM. */ char *fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap) { @@ -586,84 +600,92 @@ char *fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap) break; case 'p': - (void) va_arg(ap_q, void *); /* void * */ - break; - - case 'n': - (void) va_arg(ap_q, int *); /* int * */ - break; - - /* - * Custom types - */ - case 'v': - { - value_box_t const *value = va_arg(ap_q, value_box_t const *); - /* - * Allocations that are not part of the output - * string need to occur in the NULL ctx so we don't fragment - * any pool associated with it. + * Custom types */ - custom = value_box_asprint(NULL, value->type, value->datum.enumv, value, '"'); - if (!custom) { - talloc_free(out); - return NULL; - } + switch (*(p + 1)) { - do_splice: - /* - * Pass part of a format string to printf - */ - if (fmt_q != fmt_p) { - char *sub_fmt; - - sub_fmt = talloc_strndup(NULL, fmt_p, fmt_q - fmt_p); - out_tmp = talloc_vasprintf_append_buffer(out, sub_fmt, ap_p); - talloc_free(sub_fmt); - if (!out_tmp) { - oom: - fr_strerror_printf("Out of memory"); + case 'H': + { + value_box_t const *value = va_arg(ap_q, value_box_t const *); + + p++; + + /* + * Allocations that are not part of the output + * string need to occur in the NULL ctx so we don't fragment + * any pool associated with it. + */ + custom = value_box_asprint(NULL, value->type, value->datum.enumv, value, '"'); + if (!custom) { talloc_free(out); - talloc_free(custom); - va_end(ap_p); - va_end(ap_q); return NULL; } - out = out_tmp; - out_tmp = talloc_strdup_append_buffer(out, custom); - TALLOC_FREE(custom); - if (!out_tmp) goto oom; - out = out_tmp; + do_splice: + /* + * Pass part of a format string to printf + */ + if (fmt_q != fmt_p) { + char *sub_fmt; + + sub_fmt = talloc_strndup(NULL, fmt_p, fmt_q - fmt_p); + out_tmp = talloc_vasprintf_append_buffer(out, sub_fmt, ap_p); + talloc_free(sub_fmt); + if (!out_tmp) { + oom: + fr_strerror_printf("Out of memory"); + talloc_free(out); + talloc_free(custom); + va_end(ap_p); + va_end(ap_q); + return NULL; + } + out = out_tmp; + + out_tmp = talloc_strdup_append_buffer(out, custom); + TALLOC_FREE(custom); + if (!out_tmp) goto oom; + out = out_tmp; - va_end(ap_p); /* one time use only */ - va_copy(ap_p, ap_q); /* already advanced to the next argument */ + va_end(ap_p); /* one time use only */ + va_copy(ap_p, ap_q); /* already advanced to the next argument */ + } + + fmt_p = p + 1; } + break; - fmt_p = p + 1; - } - break; + case 'B': + { + uint8_t const *bin = va_arg(ap_q, uint8_t *); - case 'b': - { - uint8_t const *bin = va_arg(ap_q, uint8_t *); + p++; - /* - * Only automagically figure out the length - * if it's not specified. - * - * This allows %b to be used with stack buffers, - * so long as the length is specified in the format string. - */ - if (precision == 0) precision = talloc_array_length(bin); + /* + * Only automagically figure out the length + * if it's not specified. + * + * This allows %b to be used with stack buffers, + * so long as the length is specified in the format string. + */ + if (precision == 0) precision = talloc_array_length(bin); - custom = talloc_array(NULL, char, (precision * 2) + 1); - if (!custom) goto oom; - fr_bin2hex(custom, bin, precision); + custom = talloc_array(NULL, char, (precision * 2) + 1); + if (!custom) goto oom; + fr_bin2hex(custom, bin, precision); - goto do_splice; - } + goto do_splice; + } + + default: + (void) va_arg(ap_q, void *); /* void * */ + } + break; + + case 'n': + (void) va_arg(ap_q, int *); /* int * */ + break; default: break;