krb5 commit: Add k5_buf_add_vfmt to k5buf interface

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/f05766469efc2a055085c0bcf9d40c4cdf47fe36
commit f05766469efc2a055085c0bcf9d40c4cdf47fe36
Author: Greg Hudson <[email protected]>
Date:   Thu Jan 4 14:35:12 2018 -0500

    Add k5_buf_add_vfmt to k5buf interface

 src/include/k5-buf.h                          |    8 +++++++
 src/util/support/k5buf.c                      |   26 ++++++++++++++----------
 src/util/support/libkrb5support-fixed.exports |    1 +
 3 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/src/include/k5-buf.h b/src/include/k5-buf.h
index f3207bd..1223916 100644
--- a/src/include/k5-buf.h
+++ b/src/include/k5-buf.h
@@ -76,6 +76,14 @@ void k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
 #endif
     ;
 
+/* Add sprintf-style formatted data to BUF, with a va_list.  The value of ap is
+ * undefined after the call. */
+void k5_buf_add_vfmt(struct k5buf *buf, const char *fmt, va_list ap)
+#if !defined(__cplusplus) && (__GNUC__ > 2)
+    __attribute__((__format__(__printf__, 2, 0)))
+#endif
+    ;
+
 /* Extend the length of buf by len and return a pointer to the reserved space,
  * to be filled in by the caller.  Return NULL on error. */
 void *k5_buf_get_space(struct k5buf *buf, size_t len);
diff --git a/src/util/support/k5buf.c b/src/util/support/k5buf.c
index f619f6a..35978f2 100644
--- a/src/util/support/k5buf.c
+++ b/src/util/support/k5buf.c
@@ -141,9 +141,9 @@ k5_buf_add_len(struct k5buf *buf, const void *data, size_t len)
 }
 
 void
-k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
+k5_buf_add_vfmt(struct k5buf *buf, const char *fmt, va_list ap)
 {
-    va_list ap;
+    va_list apcopy;
     int r;
     size_t remaining;
     char *tmp;
@@ -154,9 +154,7 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
 
     if (buf->buftype == K5BUF_FIXED) {
         /* Format the data directly into the fixed buffer. */
-        va_start(ap, fmt);
         r = vsnprintf(endptr(buf), remaining, fmt, ap);
-        va_end(ap);
         if (SNPRINTF_OVERFLOW(r, remaining))
             set_error(buf);
         else
@@ -166,9 +164,9 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
 
     /* Optimistically format the data directly into the dynamic buffer. */
     assert(buf->buftype == K5BUF_DYNAMIC);
-    va_start(ap, fmt);
-    r = vsnprintf(endptr(buf), remaining, fmt, ap);
-    va_end(ap);
+    va_copy(apcopy, ap);
+    r = vsnprintf(endptr(buf), remaining, fmt, apcopy);
+    va_end(apcopy);
     if (!SNPRINTF_OVERFLOW(r, remaining)) {
         buf->len += (unsigned int) r;
         return;
@@ -179,9 +177,7 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
         if (!ensure_space(buf, r))
             return;
         remaining = buf->space - buf->len;
-        va_start(ap, fmt);
         r = vsnprintf(endptr(buf), remaining, fmt, ap);
-        va_end(ap);
         if (SNPRINTF_OVERFLOW(r, remaining))  /* Shouldn't ever happen. */
             k5_buf_free(buf);
         else
@@ -191,9 +187,7 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
 
     /* It's a pre-C99 snprintf implementation, or something else went wrong.
      * Fall back to asprintf. */
-    va_start(ap, fmt);
     r = vasprintf(&tmp, fmt, ap);
-    va_end(ap);
     if (r < 0) {
         k5_buf_free(buf);
         return;
@@ -206,6 +200,16 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
     free(tmp);
 }
 
+void
+k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    k5_buf_add_vfmt(buf, fmt, ap);
+    va_end(ap);
+}
+
 void *
 k5_buf_get_space(struct k5buf *buf, size_t len)
 {
diff --git a/src/util/support/libkrb5support-fixed.exports b/src/util/support/libkrb5support-fixed.exports
index fd74a18..12dab38 100644
--- a/src/util/support/libkrb5support-fixed.exports
+++ b/src/util/support/libkrb5support-fixed.exports
@@ -6,6 +6,7 @@ k5_buf_init_dynamic
 k5_buf_add
 k5_buf_add_len
 k5_buf_add_fmt
+k5_buf_add_vfmt
 k5_buf_get_space
 k5_buf_truncate
 k5_buf_status
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.