]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Overload %p printk style
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 18 Nov 2016 23:24:14 +0000 (18:24 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 18 Nov 2016 23:24:14 +0000 (18:24 -0500)
src/include/log.h
src/lib/print.c

index 46ed2bed13cabef94b21aff5a5ee559bf08ec626..ffa0c6c5cd107a5855ae75e35e01aee74875a16b 100644 (file)
@@ -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));
index 5fb30a07615ea7e4546c7fbd02a880f60c02318c..9500c994ad8f78c1da497c1e50f7720c352486b5 100644 (file)
@@ -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;