2018-06-07 16:37:24 +00:00
|
|
|
From 74e1079df0cc6e8932e487455177a69f782b863a Mon Sep 17 00:00:00 2001
|
2018-03-27 15:02:50 +00:00
|
|
|
From: Greg Hudson <ghudson@mit.edu>
|
|
|
|
Date: Thu, 4 Jan 2018 14:35:12 -0500
|
|
|
|
Subject: [PATCH] Add k5_buf_add_vfmt to k5buf interface
|
|
|
|
|
|
|
|
(cherry picked from commit f05766469efc2a055085c0bcf9d40c4cdf47fe36)
|
|
|
|
---
|
2018-04-17 17:27:54 +00:00
|
|
|
src/include/k5-buf.h | 8 ++++++
|
|
|
|
src/util/support/k5buf.c | 26 +++++++++++--------
|
2018-03-27 15:02:50 +00:00
|
|
|
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 f3207bd09..1223916a6 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 f619f6a48..35978f238 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 30c946e7e..cb9bf0826 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
|