krb5 commit: Modify k5buf interfaces for easier use
Greg Hudson
ghudson at MIT.EDU
Wed Jul 30 13:39:16 EDT 2014
https://github.com/krb5/krb5/commit/651f3af251d172361a954f55f2d87561ae42c2d0
commit 651f3af251d172361a954f55f2d87561ae42c2d0
Author: Greg Hudson <ghudson at mit.edu>
Date: Wed Jul 2 12:03:54 2014 -0400
Modify k5buf interfaces for easier use
Make struct k5buf less opaque and get rid of k5buf-int.h. Make it
easy to initialize a k5buf in an error state so that it can be freed
in a cleanup handler. Add a function k5_buf_status which returns 0 or
ENOMEM. Remove k5_buf_data and k5_buf_len. Rename k5_free_buf to
k5_buf_free. Adjust all callers to match.
src/clients/ksu/authorization.c | 4 +-
src/include/k5-buf.h | 87 ++++--------
src/lib/crypto/crypto_tests/t_hmac.c | 2 +-
src/lib/crypto/krb/cf2.c | 11 +-
src/lib/gssapi/generic/gssapiP_generic.h | 20 ++--
src/lib/gssapi/generic/oid_ops.c | 4 -
src/lib/gssapi/mechglue/g_export_cred.c | 6 +-
src/lib/kadm5/alt_prof.c | 11 +-
src/lib/kadm5/str_conv.c | 4 +-
src/lib/kdb/kdb5.c | 20 ++--
src/lib/krb5/ccache/cc_file.c | 22 +--
src/lib/krb5/ccache/ccmarshal.c | 12 +-
src/lib/krb5/krb/chpw.c | 12 +-
src/lib/krb5/krb/srv_rcache.c | 12 +-
src/lib/krb5/os/dnsglue.c | 5 +-
src/lib/krb5/os/dnssrv.c | 7 +-
src/lib/krb5/os/expand_path.c | 17 +--
src/lib/krb5/os/localauth_rule.c | 15 +-
src/lib/krb5/os/sendto_kdc.c | 6 +-
src/lib/krb5/os/trace.c | 2 +-
src/lib/krb5/rcache/rc_dfl.c | 15 +--
src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c | 4 +-
src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c | 2 +-
src/plugins/preauth/pkinit/pkinit_crypto_nss.c | 12 +-
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 6 +-
src/util/gss-kernel-lib/t_kgss_user.c | 6 +-
src/util/support/deps | 4 +-
src/util/support/json.c | 8 +-
src/util/support/k5buf-int.h | 48 -------
src/util/support/k5buf.c | 111 ++++++++-------
src/util/support/libkrb5support-fixed.exports | 5 +-
src/util/support/t_k5buf.c | 149 ++++++++------------
32 files changed, 258 insertions(+), 391 deletions(-)
diff --git a/src/clients/ksu/authorization.c b/src/clients/ksu/authorization.c
index 7f393b8..90aafbd 100644
--- a/src/clients/ksu/authorization.c
+++ b/src/clients/ksu/authorization.c
@@ -518,11 +518,11 @@ krb5_boolean find_first_cmd_that_exists(fcmd_arr, cmd_out, err_out)
for(j= 0; j < i; j ++)
k5_buf_add_fmt(&buf, " %s ", fcmd_arr[j]);
k5_buf_add(&buf, "\n");
- *err_out = k5_buf_data(&buf);
- if (*err_out == NULL) {
+ if (k5_buf_status(&buf) != 0) {
perror(prog_name);
exit(1);
}
+ *err_out = buf.data;
}
diff --git a/src/include/k5-buf.h b/src/include/k5-buf.h
index da10fd9..f3207bd 100644
--- a/src/include/k5-buf.h
+++ b/src/include/k5-buf.h
@@ -27,62 +27,47 @@
#ifndef K5_BUF_H
#define K5_BUF_H
-#if defined(_MSDOS) || defined(_WIN32)
-#include <win-mac.h>
-#endif
-#ifndef KRB5_CALLCONV
-#define KRB5_CALLCONV
-#define KRB5_CALLCONV_C
-#endif
-
#include <stdarg.h>
#include <string.h>
-#ifndef _WIN32
-#include <unistd.h>
-#endif
/*
* The k5buf module is intended to allow multi-step string construction in a
* fixed or dynamic buffer without the need to check for a failure at each step
* (and without aborting on malloc failure). If an allocation failure occurs
- * or if the fixed buffer runs out of room, the error will be discovered when
- * the caller retrieves the C string value or checks the length of the
- * resulting buffer.
+ * or the fixed buffer runs out of room, the buffer will be set to an error
+ * state which can be detected with k5_buf_status. Data in a buffer is
+ * terminated with a zero byte so that it can be used as a C string.
*
- * k5buf structures are stack-allocated, but are intended to be opaque, so do
- * not access the fields directly. This is a tool, not a way of life, so do
- * not put k5buf structure pointers into the public API or into significant
- * internal APIs.
+ * k5buf structures are usually stack-allocated. Do not put k5buf structure
+ * pointers into public APIs. It is okay to reference the data and len fields
+ * of a buffer (they will be NULL/0 if the buffer is in an error state), but do
+ * not change them.
*/
-/*
- * We must define the k5buf structure here to allow stack allocation. The
- * structure is intended to be opaque, so the fields have funny names.
- */
+/* Buffer type values */
+enum k5buftype { K5BUF_ERROR, K5BUF_FIXED, K5BUF_DYNAMIC };
+
struct k5buf {
- int xx_buftype;
- char *xx_data;
- size_t xx_space;
- size_t xx_len;
+ enum k5buftype buftype;
+ void *data;
+ size_t space;
+ size_t len;
};
+#define EMPTY_K5BUF { K5BUF_ERROR }
+
/* Initialize a k5buf using a fixed-sized, existing buffer. SPACE must be
* more than zero, or an assertion failure will result. */
void k5_buf_init_fixed(struct k5buf *buf, char *data, size_t space);
-/* Initialize a k5buf using an internally allocated dynamic buffer. The
- * buffer contents must be freed with k5_free_buf. */
+/* Initialize a k5buf using an internally allocated dynamic buffer. */
void k5_buf_init_dynamic(struct k5buf *buf);
/* Add a C string to BUF. */
void k5_buf_add(struct k5buf *buf, const char *data);
-/*
- * Add a counted set of bytes to BUF. It is okay for DATA[0..LEN-1]
- * to contain null bytes if you are prepared to deal with that in the
- * output (use k5_buf_len to retrieve the length of the output).
- */
-void k5_buf_add_len(struct k5buf *buf, const char *data, size_t len);
+/* Add a counted series of bytes to BUF. */
+void k5_buf_add_len(struct k5buf *buf, const void *data, size_t len);
/* Add sprintf-style formatted data to BUF. */
void k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
@@ -99,36 +84,16 @@ void *k5_buf_get_space(struct k5buf *buf, size_t len);
* length, or an assertion failure will result. */
void k5_buf_truncate(struct k5buf *buf, size_t len);
-/*
- * Retrieve the byte array value of BUF, or NULL if there has been an
- * allocation failure or the fixed buffer ran out of room.
- *
- * The byte array will be a C string unless binary data was added with
- * k5_buf_add_len; it will be null-terminated regardless. Modifying the byte
- * array does not invalidate the buffer, as long as its length is not changed.
- *
- * For a fixed buffer, the return value will always be equal to the passed-in
- * value of DATA at initialization time if it is not NULL.
- *
- * For a dynamic buffer, any buffer modification operation except
- * k5_buf_truncate may invalidate the byte array address.
- */
-char *k5_buf_data(struct k5buf *buf);
-
-/*
- * Retrieve the length of BUF, or -1 if there has been an allocation failure or
- * the fixed buffer ran out of room. The length is equal to
- * strlen(k5_buf_data(buf)) unless binary data was added with k5_buf_add_len.
- */
-ssize_t k5_buf_len(struct k5buf *buf);
+/* Return ENOMEM if buf is in an error state, 0 otherwise. */
+int k5_buf_status(struct k5buf *buf);
/*
* Free the storage used in the dynamic buffer BUF. The caller may choose to
- * take responsibility for freeing the return value of k5_buf_data instead of
- * using this function. If BUF is a fixed buffer, an assertion failure will
- * result. It is unnecessary (though harmless) to free a buffer after an error
- * is detected; the storage will already have been freed in that case.
+ * take responsibility for freeing the data pointer instead of using this
+ * function. If BUF is a fixed buffer, an assertion failure will result.
+ * Freeing a buffer in the error state, a buffer initialized with EMPTY_K5BUF,
+ * or a zeroed k5buf structure is a no-op.
*/
-void k5_free_buf(struct k5buf *buf);
+void k5_buf_free(struct k5buf *buf);
#endif /* K5_BUF_H */
diff --git a/src/lib/crypto/crypto_tests/t_hmac.c b/src/lib/crypto/crypto_tests/t_hmac.c
index 65efa60..8961380 100644
--- a/src/lib/crypto/crypto_tests/t_hmac.c
+++ b/src/lib/crypto/crypto_tests/t_hmac.c
@@ -250,7 +250,7 @@ static void test_hmac()
k5_buf_add(&buf, "0x");
for (j = 0; j < out.length; j++)
k5_buf_add_fmt(&buf, "%02x", 0xff & outbuf[j]);
- if (k5_buf_data(&buf) == NULL)
+ if (k5_buf_status(&buf) != 0)
abort();
if (strcmp(stroutbuf, md5tests[i].hexdigest)) {
printf("*** CHECK FAILED!\n"
diff --git a/src/lib/crypto/krb/cf2.c b/src/lib/crypto/krb/cf2.c
index 5eec154..a0654b6 100644
--- a/src/lib/crypto/krb/cf2.c
+++ b/src/lib/crypto/krb/cf2.c
@@ -59,12 +59,11 @@ prf_plus(krb5_context context, krb5_keyblock *k, const char *pepper,
buffer = k5calloc(iterations, prflen, &retval);
if (retval)
goto cleanup;
- if (k5_buf_len(&prf_inbuf) == -1) {
- retval = ENOMEM;
+ retval = k5_buf_status(&prf_inbuf);
+ if (retval)
goto cleanup;
- }
- in_data.length = (krb5_int32)k5_buf_len(&prf_inbuf);
- in_data.data = k5_buf_data(&prf_inbuf);
+ in_data.length = prf_inbuf.len;
+ in_data.data = prf_inbuf.data;
out_data.length = prflen;
out_data.data = buffer;
@@ -82,7 +81,7 @@ prf_plus(krb5_context context, krb5_keyblock *k, const char *pepper,
cleanup:
free(buffer);
- k5_free_buf(&prf_inbuf);
+ k5_buf_free(&prf_inbuf);
return retval;
}
diff --git a/src/lib/gssapi/generic/gssapiP_generic.h b/src/lib/gssapi/generic/gssapiP_generic.h
index 5e32186..686a217 100644
--- a/src/lib/gssapi/generic/gssapiP_generic.h
+++ b/src/lib/gssapi/generic/gssapiP_generic.h
@@ -273,13 +273,18 @@ k5buf_to_gss(OM_uint32 *minor,
gss_buffer_t output_buffer)
{
OM_uint32 status = GSS_S_COMPLETE;
- char *bp = k5_buf_data(input_k5buf);
- output_buffer->length = k5_buf_len(input_k5buf);
+
+ if (k5_buf_status(input_k5buf) != 0) {
+ *minor = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ output_buffer->length = input_k5buf->len;
#if defined(_WIN32) || defined(DEBUG_GSSALLOC)
if (output_buffer->length > 0) {
output_buffer->value = gssalloc_malloc(output_buffer->length);
if (output_buffer->value) {
- memcpy(output_buffer->value, bp, output_buffer->length);
+ memcpy(output_buffer->value, input_k5buf->data,
+ output_buffer->length);
} else {
status = GSS_S_FAILURE;
*minor = ENOMEM;
@@ -287,13 +292,10 @@ k5buf_to_gss(OM_uint32 *minor,
} else {
output_buffer->value = NULL;
}
- k5_free_buf(input_k5buf);
+ k5_buf_free(input_k5buf);
#else
- output_buffer->value = bp;
- /*
- * it would be nice to invalidate input_k5buf here
- * but there is no api for that currently...
- */
+ output_buffer->value = input_k5buf->data;
+ memset(input_k5buf, 0, sizeof(*input_k5buf));
#endif
return status;
}
diff --git a/src/lib/gssapi/generic/oid_ops.c b/src/lib/gssapi/generic/oid_ops.c
index 1229f38..5ad02fc 100644
--- a/src/lib/gssapi/generic/oid_ops.c
+++ b/src/lib/gssapi/generic/oid_ops.c
@@ -276,10 +276,6 @@ generic_gss_oid_to_str(OM_uint32 *minor_status,
}
}
k5_buf_add_len(&buf, "}\0", 2);
- if (k5_buf_data(&buf) == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
return k5buf_to_gss(minor_status, &buf, oid_str);
}
diff --git a/src/lib/gssapi/mechglue/g_export_cred.c b/src/lib/gssapi/mechglue/g_export_cred.c
index 16d1ebe..8f5fe4a 100644
--- a/src/lib/gssapi/mechglue/g_export_cred.c
+++ b/src/lib/gssapi/mechglue/g_export_cred.c
@@ -106,13 +106,9 @@ gss_export_cred(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
gss_release_buffer(&tmpmin, &mech_token);
}
- if (k5_buf_data(&buf) == NULL) {
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
return k5buf_to_gss(minor_status, &buf, token);
error:
- k5_free_buf(&buf);
+ k5_buf_free(&buf);
return status;
}
diff --git a/src/lib/kadm5/alt_prof.c b/src/lib/kadm5/alt_prof.c
index 205333b..db45d13 100644
--- a/src/lib/kadm5/alt_prof.c
+++ b/src/lib/kadm5/alt_prof.c
@@ -66,7 +66,7 @@ krb5_aprof_init(char *fname, char *envname, krb5_pointer *acontextp)
krb5_error_code ret;
profile_t profile;
const char *kdc_config;
- char *profile_path, **filenames;
+ char **filenames;
int i;
struct k5buf buf;
@@ -79,17 +79,16 @@ krb5_aprof_init(char *fname, char *envname, krb5_pointer *acontextp)
if (kdc_config)
k5_buf_add(&buf, kdc_config);
for (i = 0; filenames[i] != NULL; i++) {
- if (k5_buf_len(&buf) > 0)
+ if (buf.len > 0)
k5_buf_add(&buf, ":");
k5_buf_add(&buf, filenames[i]);
}
krb5_free_config_files(filenames);
- profile_path = k5_buf_data(&buf);
- if (profile_path == NULL)
+ if (k5_buf_status(&buf) != 0)
return ENOMEM;
profile = (profile_t) NULL;
- ret = profile_init_path(profile_path, &profile);
- free(profile_path);
+ ret = profile_init_path(buf.data, &profile);
+ k5_buf_free(&buf);
if (ret)
return ret;
*acontextp = profile;
diff --git a/src/lib/kadm5/str_conv.c b/src/lib/kadm5/str_conv.c
index e8de915..216b580 100644
--- a/src/lib/kadm5/str_conv.c
+++ b/src/lib/kadm5/str_conv.c
@@ -187,14 +187,14 @@ krb5_flags_to_string(flags, sep, buffer, buflen)
/* Blast through the table matching all we can */
for (i=0; i<flags_table_nents; i++) {
if (flags & flags_table[i].fl_flags) {
- if (k5_buf_len(&buf) > 0)
+ if (buf.len > 0)
k5_buf_add(&buf, sepstring);
k5_buf_add(&buf, _(flags_table[i].fl_output));
/* Keep track of what we matched */
pflags |= flags_table[i].fl_flags;
}
}
- if (k5_buf_data(&buf) == NULL)
+ if (k5_buf_status(&buf) != 0)
return(ENOMEM);
/* See if there's any leftovers */
diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c
index 7541b1e..7c82399 100644
--- a/src/lib/kdb/kdb5.c
+++ b/src/lib/kdb/kdb5.c
@@ -2034,10 +2034,9 @@ krb5_dbe_set_string(krb5_context context, krb5_db_entry *entry,
{
krb5_error_code code;
const char *pos, *end, *mapkey, *mapval;
- struct k5buf buf;
+ struct k5buf buf = EMPTY_K5BUF;
krb5_boolean found = FALSE;
krb5_tl_data tl_data;
- ssize_t len;
/* Copy the current mapping to buf, updating key with value if found. */
code = begin_attrs(context, entry, &pos, &end);
@@ -2063,17 +2062,20 @@ krb5_dbe_set_string(krb5_context context, krb5_db_entry *entry,
k5_buf_add_len(&buf, value, strlen(value) + 1);
}
- len = k5_buf_len(&buf);
- if (len == -1)
+ if (k5_buf_status(&buf) != 0)
return ENOMEM;
- if (len > 65535)
- return KRB5_KDB_STRINGS_TOOLONG;
+ if (buf.len > 65535) {
+ code = KRB5_KDB_STRINGS_TOOLONG;
+ goto cleanup;
+ }
tl_data.tl_data_type = KRB5_TL_STRING_ATTRS;
- tl_data.tl_data_contents = (krb5_octet *)k5_buf_data(&buf);
- tl_data.tl_data_length = len;
+ tl_data.tl_data_contents = buf.data;
+ tl_data.tl_data_length = buf.len;
code = krb5_dbe_update_tl_data(context, entry, &tl_data);
- k5_free_buf(&buf);
+
+cleanup:
+ k5_buf_free(&buf);
return code;
}
diff --git a/src/lib/krb5/ccache/cc_file.c b/src/lib/krb5/ccache/cc_file.c
index 3f6443f..2407851 100644
--- a/src/lib/krb5/ccache/cc_file.c
+++ b/src/lib/krb5/ccache/cc_file.c
@@ -402,7 +402,6 @@ read_principal(krb5_context context, krb5_ccache id, krb5_principal *princ)
krb5_error_code ret;
struct k5buf buf;
size_t maxsize;
- unsigned char *bytes;
*princ = NULL;
k5_cc_mutex_assert_locked(context, &((fcc_data *)id->data)->lock);
@@ -415,17 +414,15 @@ read_principal(krb5_context context, krb5_ccache id, krb5_principal *princ)
ret = load_principal(context, id, maxsize, &buf);
if (ret)
goto cleanup;
- bytes = (unsigned char *)k5_buf_data(&buf);
- if (bytes == NULL) {
- ret = ENOMEM;
+ ret = k5_buf_status(&buf);
+ if (ret)
goto cleanup;
- }
/* Unmarshal it from buf into princ. */
- ret = k5_unmarshal_princ(bytes, k5_buf_len(&buf), version(id), princ);
+ ret = k5_unmarshal_princ(buf.data, buf.len, version(id), princ);
cleanup:
- k5_free_buf(&buf);
+ k5_buf_free(&buf);
return ret;
}
@@ -1092,7 +1089,6 @@ fcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor,
fcc_data *data = id->data;
struct k5buf buf;
size_t maxsize;
- unsigned char *bytes;
memset(creds, 0, sizeof(*creds));
k5_cc_mutex_lock(context, &data->lock);
@@ -1111,18 +1107,16 @@ fcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor,
ret = load_cred(context, id, maxsize, &buf);
if (ret)
goto cleanup;
- bytes = (unsigned char *)k5_buf_data(&buf);
- if (bytes == NULL) {
- ret = ENOMEM;
+ ret = k5_buf_status(&buf);
+ if (ret)
goto cleanup;
- }
/* Unmarshal it from buf into creds. */
fcursor->pos = fcc_lseek(data, 0, SEEK_CUR);
- ret = k5_unmarshal_cred(bytes, k5_buf_len(&buf), version(id), creds);
+ ret = k5_unmarshal_cred(buf.data, buf.len, version(id), creds);
cleanup:
- k5_free_buf(&buf);
+ k5_buf_free(&buf);
MAYBE_CLOSE(context, id, ret);
k5_cc_mutex_unlock(context, &data->lock);
return ret;
diff --git a/src/lib/krb5/ccache/ccmarshal.c b/src/lib/krb5/ccache/ccmarshal.c
index c27b43f..d190577 100644
--- a/src/lib/krb5/ccache/ccmarshal.c
+++ b/src/lib/krb5/ccache/ccmarshal.c
@@ -449,10 +449,10 @@ k5_marshal_cred(krb5_creds *creds, int version, unsigned char **bytes_out,
marshal_authdata(&buf, version, creds->authdata);
put_data(&buf, version, &creds->ticket);
put_data(&buf, version, &creds->second_ticket);
- if (k5_buf_data(&buf) == NULL)
+ if (k5_buf_status(&buf) != 0)
return ENOMEM;
- *bytes_out = (unsigned char *)k5_buf_data(&buf);
- *len_out = k5_buf_len(&buf);
+ *bytes_out = buf.data;
+ *len_out = buf.len;
return 0;
}
@@ -468,9 +468,9 @@ k5_marshal_princ(krb5_principal princ, int version, unsigned char **bytes_out,
*len_out = 0;
k5_buf_init_dynamic(&buf);
marshal_princ(&buf, version, princ);
- if (k5_buf_data(&buf) == NULL)
+ if (k5_buf_status(&buf) != 0)
return ENOMEM;
- *bytes_out = (unsigned char *)k5_buf_data(&buf);
- *len_out = k5_buf_len(&buf);
+ *bytes_out = buf.data;
+ *len_out = buf.len;
return 0;
}
diff --git a/src/lib/krb5/krb/chpw.c b/src/lib/krb5/krb/chpw.c
index 463ce64..b8010b3 100644
--- a/src/lib/krb5/krb/chpw.c
+++ b/src/lib/krb5/krb/chpw.c
@@ -384,7 +384,7 @@ struct ad_policy_info {
static void
add_spaces(struct k5buf *buf)
{
- if (k5_buf_len(buf) > 0)
+ if (buf->len > 0)
k5_buf_add(buf, " ");
}
@@ -394,7 +394,6 @@ decode_ad_policy_info(const krb5_data *data, char **msg_out)
struct ad_policy_info policy;
uint64_t password_days;
const char *p;
- char *msg;
struct k5buf buf;
*msg_out = NULL;
@@ -465,14 +464,13 @@ decode_ad_policy_info(const krb5_data *data, char **msg_out)
(int)password_days);
}
- msg = k5_buf_data(&buf);
- if (msg == NULL)
+ if (k5_buf_status(&buf) != 0)
return ENOMEM;
- if (*msg != '\0')
- *msg_out = msg;
+ if (buf.len > 0)
+ *msg_out = buf.data;
else
- free(msg);
+ k5_buf_free(&buf);
return 0;
}
diff --git a/src/lib/krb5/krb/srv_rcache.c b/src/lib/krb5/krb/srv_rcache.c
index 1b0a91a..692c853 100644
--- a/src/lib/krb5/krb/srv_rcache.c
+++ b/src/lib/krb5/krb/srv_rcache.c
@@ -35,10 +35,10 @@ krb5_get_server_rcache(krb5_context context, const krb5_data *piece,
krb5_rcache *rcptr)
{
krb5_rcache rcache = 0;
- char *cachename = 0, *cachetype;
+ char *cachetype;
krb5_error_code retval;
unsigned int i;
- struct k5buf buf;
+ struct k5buf buf = EMPTY_K5BUF;
#ifdef HAVE_GETEUID
unsigned long uid = geteuid();
#endif
@@ -63,11 +63,10 @@ krb5_get_server_rcache(krb5_context context, const krb5_data *piece,
k5_buf_add_fmt(&buf, "_%lu", uid);
#endif
- cachename = k5_buf_data(&buf);
- if (cachename == NULL)
+ if (k5_buf_status(&buf) != 0)
return ENOMEM;
- retval = krb5_rc_resolve_full(context, &rcache, cachename);
+ retval = krb5_rc_resolve_full(context, &rcache, buf.data);
if (retval)
goto cleanup;
@@ -83,7 +82,6 @@ krb5_get_server_rcache(krb5_context context, const krb5_data *piece,
cleanup:
if (rcache)
krb5_rc_close(context, rcache);
- if (cachename)
- free(cachename);
+ k5_buf_free(&buf);
return retval;
}
diff --git a/src/lib/krb5/os/dnsglue.c b/src/lib/krb5/os/dnsglue.c
index fcb99ff..7d25fee 100644
--- a/src/lib/krb5/os/dnsglue.c
+++ b/src/lib/krb5/os/dnsglue.c
@@ -389,11 +389,10 @@ k5_try_realm_txt_rr(krb5_context context, const char *prefix, const char *name,
the local domain or domain search lists to be expanded.
*/
- len = k5_buf_len(&buf);
- if (len > 0 && host[len - 1] != '.')
+ if (buf.len > 0 && host[buf.len - 1] != '.')
k5_buf_add(&buf, ".");
}
- if (k5_buf_data(&buf) == NULL)
+ if (k5_buf_status(&buf) != 0)
return KRB5_ERR_HOST_REALM_UNKNOWN;
ret = krb5int_dns_init(&ds, host, C_IN, T_TXT);
if (ret < 0) {
diff --git a/src/lib/krb5/os/dnssrv.c b/src/lib/krb5/os/dnssrv.c
index 33ee0e7..c41b0d8 100644
--- a/src/lib/krb5/os/dnssrv.c
+++ b/src/lib/krb5/os/dnssrv.c
@@ -59,7 +59,7 @@ krb5int_make_srv_query_realm(const krb5_data *realm,
{
const unsigned char *p = NULL, *base = NULL;
char host[MAXDNAME];
- int size, ret, rdlen, nlen, len;
+ int size, ret, rdlen, nlen;
unsigned short priority, weight, port;
struct krb5int_dns_state *ds = NULL;
struct k5buf buf;
@@ -93,11 +93,10 @@ krb5int_make_srv_query_realm(const krb5_data *realm,
a search on the prefix alone then the intention is to allow
the local domain or domain search lists to be expanded. */
- len = k5_buf_len(&buf);
- if (len > 0 && host[len - 1] != '.')
+ if (buf.len > 0 && host[buf.len - 1] != '.')
k5_buf_add(&buf, ".");
- if (k5_buf_data(&buf) == NULL)
+ if (k5_buf_status(&buf) != 0)
return 0;
#ifdef TEST
diff --git a/src/lib/krb5/os/expand_path.c b/src/lib/krb5/os/expand_path.c
index 4646c54..6142b3b 100644
--- a/src/lib/krb5/os/expand_path.c
+++ b/src/lib/krb5/os/expand_path.c
@@ -454,7 +454,7 @@ k5_expand_path_tokens_extra(krb5_context context, const char *path_in,
{
krb5_error_code ret;
struct k5buf buf;
- char *tok_begin, *tok_end, *tok_val, *path, **extra_tokens = NULL;
+ char *tok_begin, *tok_end, *tok_val, **extra_tokens = NULL;
const char *path_left;
size_t nargs = 0, i;
va_list ap;
@@ -517,26 +517,25 @@ k5_expand_path_tokens_extra(krb5_context context, const char *path_in,
path_left = tok_end + 1;
}
- path = k5_buf_data(&buf);
- if (path == NULL) {
- ret = ENOMEM;
+ ret = k5_buf_status(&buf);
+ if (ret)
goto cleanup;
- }
+
#ifdef _WIN32
/* Also deal with slashes. */
{
char *p;
- for (p = path; *p != '\0'; p++) {
+ for (p = buf.data; *p != '\0'; p++) {
if (*p == '/')
*p = '\\';
}
}
#endif
- *path_out = path;
+ *path_out = buf.data;
+ memset(&buf, 0, sizeof(buf));
cleanup:
- if (*path_out == NULL)
- k5_free_buf(&buf);
+ k5_buf_free(&buf);
free_extra_tokens(extra_tokens);
return 0;
}
diff --git a/src/lib/krb5/os/localauth_rule.c b/src/lib/krb5/os/localauth_rule.c
index 584dcba..8522108 100644
--- a/src/lib/krb5/os/localauth_rule.c
+++ b/src/lib/krb5/os/localauth_rule.c
@@ -130,8 +130,10 @@ do_replacement(const char *regstr, const char *repl, krb5_boolean doall,
}
regfree(&re);
k5_buf_add(&buf, instr);
- *outstr = k5_buf_data(&buf);
- return *outstr == NULL ? ENOMEM : 0;
+ if (k5_buf_status(&buf) != 0)
+ return ENOMEM;
+ *outstr = buf.data;
+ return 0;
}
/*
@@ -207,7 +209,7 @@ aname_get_selstring(krb5_context context, krb5_const_principal aname,
const char **contextp, char **selstring_out)
{
const char *current;
- char *end, *str;
+ char *end;
long num_comps, ind;
const krb5_data *datap;
struct k5buf selstring;
@@ -257,16 +259,15 @@ aname_get_selstring(krb5_context context, krb5_const_principal aname,
/* Check that we hit a ']' and not the end of the string. */
if (*current != ']') {
- k5_free_buf(&selstring);
+ k5_buf_free(&selstring);
return KRB5_CONFIG_BADFORMAT;
}
- str = k5_buf_data(&selstring);
- if (str == NULL)
+ if (k5_buf_status(&selstring) != 0)
return ENOMEM;
*contextp = current + 1;
- *selstring_out = str;
+ *selstring_out = selstring.data;
return 0;
}
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
index 2242240..3b3b438 100644
--- a/src/lib/krb5/os/sendto_kdc.c
+++ b/src/lib/krb5/os/sendto_kdc.c
@@ -558,13 +558,13 @@ make_proxy_request(struct conn_state *state, const krb5_data *realm,
k5_buf_add(&buf, "Content-type: application/kerberos\r\n");
k5_buf_add_fmt(&buf, "Content-Length: %d\r\n\r\n", encoded_pm->length);
k5_buf_add_len(&buf, encoded_pm->data, encoded_pm->length);
- if (k5_buf_data(&buf) == NULL) {
+ if (k5_buf_status(&buf) != 0) {
ret = ENOMEM;
goto cleanup;
}
- *req_out = k5_buf_data(&buf);
- *len_out = k5_buf_len(&buf);
+ *req_out = buf.data;
+ *len_out = buf.len;
cleanup:
krb5_free_data_contents(NULL, &pm.kerb_message);
diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
index 5fbe573..83c8d4d 100644
--- a/src/lib/krb5/os/trace.c
+++ b/src/lib/krb5/os/trace.c
@@ -305,7 +305,7 @@ trace_format(krb5_context context, const char *fmt, va_list ap)
creds->client, creds->server);
}
}
- return k5_buf_data(&buf);
+ return buf.data;
}
/* Allows trace_format formatters to be represented in terms of other
diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c
index 8f517d0..2fb6aa0 100644
--- a/src/lib/krb5/rcache/rc_dfl.c
+++ b/src/lib/krb5/rcache/rc_dfl.c
@@ -642,11 +642,10 @@ krb5_rc_io_store(krb5_context context, struct dfl_data *t,
krb5_donot_replay *rep)
{
size_t clientlen, serverlen;
- ssize_t buflen;
unsigned int len;
krb5_error_code ret;
struct k5buf buf, extbuf;
- char *bufptr, *extstr;
+ char *extstr;
clientlen = strlen(rep->client);
serverlen = strlen(rep->server);
@@ -663,9 +662,9 @@ krb5_rc_io_store(krb5_context context, struct dfl_data *t,
k5_buf_add_fmt(&extbuf, "HASH:%s %lu:%s %lu:%s", rep->msghash,
(unsigned long)clientlen, rep->client,
(unsigned long)serverlen, rep->server);
- extstr = k5_buf_data(&extbuf);
- if (!extstr)
+ if (k5_buf_status(&extbuf) != 0)
return KRB5_RC_MALLOC;
+ extstr = extbuf.data;
/*
* Put the extension value into the server field of a
@@ -693,13 +692,11 @@ krb5_rc_io_store(krb5_context context, struct dfl_data *t,
k5_buf_add_len(&buf, (char *)&rep->cusec, sizeof(rep->cusec));
k5_buf_add_len(&buf, (char *)&rep->ctime, sizeof(rep->ctime));
- bufptr = k5_buf_data(&buf);
- buflen = k5_buf_len(&buf);
- if (bufptr == NULL || buflen < 0)
+ if (k5_buf_status(&buf) != 0)
return KRB5_RC_MALLOC;
- ret = krb5_rc_io_write(context, &t->d, bufptr, buflen);
- k5_free_buf(&buf);
+ ret = krb5_rc_io_write(context, &t->d, buf.data, buf.len);
+ k5_buf_free(&buf);
return ret;
}
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
index 3f3efdc..af0eaf1 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
@@ -422,9 +422,9 @@ krb5_ldap_parse_principal_name(char *i_princ_name, char **o_princ_name)
k5_buf_add_len(&buf, p, 1);
}
k5_buf_add(&buf, at_rlm_name);
- *o_princ_name = k5_buf_data(&buf);
- if (!*o_princ_name)
+ if (k5_buf_status(&buf) != 0)
return ENOMEM;
+ *o_princ_name = buf.data;
}
return 0;
}
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c
index 7858a55..e9fb3fa 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c
@@ -87,7 +87,7 @@ ldap_filter_correct (char *in)
break;
k5_buf_add_fmt(&buf, "\\%2x", (unsigned char)*in++);
}
- return k5_buf_data(&buf);
+ return buf.data;
}
static int
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c
index 0226163..c849f87 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c
@@ -2173,11 +2173,11 @@ reassemble_pkcs11_name(PLArenaPool *pool, pkinit_identity_opts *idopts)
k5_buf_add_fmt(&buf, "%sslotid=%ld", n++ ? ":" : "",
(long)idopts->slotid);
}
- if (k5_buf_len(&buf) >= 0)
- ret = PORT_ArenaStrdup(pool, k5_buf_data(&buf));
+ if (k5_buf_status(&buf) == 0)
+ ret = PORT_ArenaStrdup(pool, buf.data);
else
ret = NULL;
- k5_free_buf(&buf);
+ k5_buf_free(&buf);
return ret;
}
@@ -2209,11 +2209,11 @@ reassemble_pkcs11_identity(PLArenaPool *pool, pkinit_identity_opts *idopts,
if (tokenname != NULL)
k5_buf_add_fmt(&buf, "%stoken=%s", n++ ? ":" : "", tokenname);
- if (k5_buf_len(&buf) >= 0)
- ret = PORT_ArenaStrdup(pool, k5_buf_data(&buf));
+ if (k5_buf_status(&buf) == 0)
+ ret = PORT_ArenaStrdup(pool, buf.data);
else
ret = NULL;
- k5_free_buf(&buf);
+ k5_buf_free(&buf);
return ret;
}
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 246bc1b..4d9b5e5 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -4450,11 +4450,11 @@ reassemble_pkcs11_name(pkinit_identity_opts *idopts)
k5_buf_add_fmt(&buf, "%sslotid=%ld", n++ ? ":" : "",
(long)idopts->slotid);
}
- if (k5_buf_len(&buf) >= 0)
- ret = strdup(k5_buf_data(&buf));
+ if (k5_buf_status(&buf) == 0)
+ ret = strdup(buf.data);
else
ret = NULL;
- k5_free_buf(&buf);
+ k5_buf_free(&buf);
return ret;
}
diff --git a/src/util/gss-kernel-lib/t_kgss_user.c b/src/util/gss-kernel-lib/t_kgss_user.c
index 0af9aa6..8c67b5d 100644
--- a/src/util/gss-kernel-lib/t_kgss_user.c
+++ b/src/util/gss-kernel-lib/t_kgss_user.c
@@ -175,9 +175,9 @@ marshal_lucid_context(const gss_krb5_lucid_context_v1_t *lctx,
add_lucid_key(&buf, &lctx->cfx_kd.acceptor_subkey);
} else
abort();
- assert(k5_buf_data(&buf) != NULL);
- *data_out = (unsigned char *)k5_buf_data(&buf);
- *len_out = k5_buf_len(&buf);
+ assert(k5_buf_status(&buf) == 0);
+ *data_out = buf.data;
+ *len_out = buf.len;
}
/* Export ctx as a lucid context, marshal it, and write it to fd. */
diff --git a/src/util/support/deps b/src/util/support/deps
index 76bdefd..82a2b4e 100644
--- a/src/util/support/deps
+++ b/src/util/support/deps
@@ -20,7 +20,7 @@ errors.so errors.po $(OUTPRE)errors.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(top_srcdir)/include/k5-thread.h errors.c supp-int.h
k5buf.so k5buf.po $(OUTPRE)k5buf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
- $(top_srcdir)/include/k5-thread.h k5buf-int.h k5buf.c
+ $(top_srcdir)/include/k5-thread.h k5buf.c
gmt_mktime.so gmt_mktime.po $(OUTPRE)gmt_mktime.$(OBJEXT): \
$(BUILDTOP)/include/autoconf.h $(top_srcdir)/include/k5-gmt_mktime.h \
gmt_mktime.c
@@ -53,7 +53,7 @@ mkstemp.so mkstemp.po $(OUTPRE)mkstemp.$(OBJEXT): $(BUILDTOP)/include/autoconf.h
mkstemp.c
t_k5buf.so t_k5buf.po $(OUTPRE)t_k5buf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
- $(top_srcdir)/include/k5-thread.h k5buf-int.h t_k5buf.c
+ $(top_srcdir)/include/k5-thread.h t_k5buf.c
t_unal.so t_unal.po $(OUTPRE)t_unal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
t_unal.c
diff --git a/src/util/support/json.c b/src/util/support/json.c
index d23267c..98f6568 100644
--- a/src/util/support/json.c
+++ b/src/util/support/json.c
@@ -696,11 +696,13 @@ k5_json_encode(k5_json_value val, char **json_out)
k5_buf_init_dynamic(&buf);
ret = encode_value(&buf, val);
if (ret) {
- k5_free_buf(&buf);
+ k5_buf_free(&buf);
return ret;
}
- *json_out = k5_buf_data(&buf);
- return (*json_out == NULL) ? ENOMEM : 0;
+ if (k5_buf_status(&buf) != 0)
+ return ENOMEM;
+ *json_out = buf.data;
+ return 0;
}
/*** JSON decoding ***/
diff --git a/src/util/support/k5buf-int.h b/src/util/support/k5buf-int.h
deleted file mode 100644
index 6f2ec19..0000000
--- a/src/util/support/k5buf-int.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/* util/support/k5buf-int.h - Internal declarations for string buffers */
-/*
- * Copyright 2008 Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-#ifndef K5BUF_INT_H
-#define K5BUF_INT_H
-
-#include "k5-platform.h"
-#include "k5-buf.h"
-
-/*
- * The k5buf structure has funny field names to discourage callers from
- * violating the abstraction barrier. Define less funny names for them here.
- */
-#define buftype xx_buftype
-#define data xx_data
-#define space xx_space
-#define len xx_len
-
-#define DYNAMIC_INITIAL_SIZE 128
-#define SPACE_MAX (SIZE_MAX / 2) /* rounds down, since SIZE_MAX is odd */
-
-/* Buffer type values. */
-enum { BUFTYPE_FIXED, BUFTYPE_DYNAMIC, BUFTYPE_ERROR };
-
-#endif /* K5BUF_INT_H */
diff --git a/src/util/support/k5buf.c b/src/util/support/k5buf.c
index c3c81b0..f619f6a 100644
--- a/src/util/support/k5buf.c
+++ b/src/util/support/k5buf.c
@@ -30,20 +30,36 @@
* needs to be generated with error tables, after util/et, which builds after
* this directory.
*/
-#include "k5buf-int.h"
+#include "k5-platform.h"
+#include "k5-buf.h"
#include <assert.h>
/*
* Structure invariants:
*
- * buftype is BUFTYPE_FIXED, BUFTYPE_DYNAMIC, or BUFTYPE_ERROR
- * if buftype is not BUFTYPE_ERROR:
+ * buftype is K5BUF_FIXED, K5BUF_DYNAMIC, or K5BUF_ERROR
+ * if buftype is K5BUF_ERROR, the other fields are NULL or 0
+ * if buftype is not K5BUF_ERROR:
* space > 0
- * space <= floor(SIZE_MAX / 2) (to fit within ssize_t)
* len < space
* data[len] = '\0'
*/
+/* Return a character pointer to the current end of buf. */
+static inline char *
+endptr(struct k5buf *buf)
+{
+ return (char *)buf->data + buf->len;
+}
+
+static inline void
+set_error(struct k5buf *buf)
+{
+ buf->buftype = K5BUF_ERROR;
+ buf->data = NULL;
+ buf->space = buf->len = 0;
+}
+
/*
* Make sure there is room for LEN more characters in BUF, in addition to the
* null terminator and what's already in there. Return true on success. On
@@ -55,18 +71,19 @@ ensure_space(struct k5buf *buf, size_t len)
size_t new_space;
char *new_data;
- if (buf->buftype == BUFTYPE_ERROR)
+ if (buf->buftype == K5BUF_ERROR)
return 0;
if (buf->space - 1 - buf->len >= len) /* Enough room already. */
return 1;
- if (buf->buftype == BUFTYPE_FIXED) /* Can't resize a fixed buffer. */
+ if (buf->buftype == K5BUF_FIXED) /* Can't resize a fixed buffer. */
goto error_exit;
- assert(buf->buftype == BUFTYPE_DYNAMIC);
+ assert(buf->buftype == K5BUF_DYNAMIC);
new_space = buf->space * 2;
- while (new_space <= SPACE_MAX && new_space - buf->len - 1 < len)
+ while (new_space - buf->len - 1 < len) {
+ if (new_space > SIZE_MAX / 2)
+ goto error_exit;
new_space *= 2;
- if (new_space > SPACE_MAX)
- goto error_exit;
+ }
new_data = realloc(buf->data, new_space);
if (new_data == NULL)
goto error_exit;
@@ -75,11 +92,9 @@ ensure_space(struct k5buf *buf, size_t len)
return 1;
error_exit:
- if (buf->buftype == BUFTYPE_DYNAMIC) {
+ if (buf->buftype == K5BUF_DYNAMIC)
free(buf->data);
- buf->data = NULL;
- }
- buf->buftype = BUFTYPE_ERROR;
+ set_error(buf);
return 0;
}
@@ -87,25 +102,25 @@ void
k5_buf_init_fixed(struct k5buf *buf, char *data, size_t space)
{
assert(space > 0);
- buf->buftype = BUFTYPE_FIXED;
+ buf->buftype = K5BUF_FIXED;
buf->data = data;
buf->space = space;
buf->len = 0;
- buf->data[0] = '\0';
+ *endptr(buf) = '\0';
}
void
k5_buf_init_dynamic(struct k5buf *buf)
{
- buf->buftype = BUFTYPE_DYNAMIC;
- buf->space = DYNAMIC_INITIAL_SIZE;
+ buf->buftype = K5BUF_DYNAMIC;
+ buf->space = 128;
buf->data = malloc(buf->space);
if (buf->data == NULL) {
- buf->buftype = BUFTYPE_ERROR;
+ set_error(buf);
return;
}
buf->len = 0;
- buf->data[0] = '\0';
+ *endptr(buf) = '\0';
}
void
@@ -115,14 +130,14 @@ k5_buf_add(struct k5buf *buf, const char *data)
}
void
-k5_buf_add_len(struct k5buf *buf, const char *data, size_t len)
+k5_buf_add_len(struct k5buf *buf, const void *data, size_t len)
{
if (!ensure_space(buf, len))
return;
if (len > 0)
- memcpy(buf->data + buf->len, data, len);
+ memcpy(endptr(buf), data, len);
buf->len += len;
- buf->data[buf->len] = '\0';
+ *endptr(buf) = '\0';
}
void
@@ -133,26 +148,26 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
size_t remaining;
char *tmp;
- if (buf->buftype == BUFTYPE_ERROR)
+ if (buf->buftype == K5BUF_ERROR)
return;
remaining = buf->space - buf->len;
- if (buf->buftype == BUFTYPE_FIXED) {
+ if (buf->buftype == K5BUF_FIXED) {
/* Format the data directly into the fixed buffer. */
va_start(ap, fmt);
- r = vsnprintf(buf->data + buf->len, remaining, fmt, ap);
+ r = vsnprintf(endptr(buf), remaining, fmt, ap);
va_end(ap);
if (SNPRINTF_OVERFLOW(r, remaining))
- buf->buftype = BUFTYPE_ERROR;
+ set_error(buf);
else
buf->len += (unsigned int) r;
return;
}
/* Optimistically format the data directly into the dynamic buffer. */
- assert(buf->buftype == BUFTYPE_DYNAMIC);
+ assert(buf->buftype == K5BUF_DYNAMIC);
va_start(ap, fmt);
- r = vsnprintf(buf->data + buf->len, remaining, fmt, ap);
+ r = vsnprintf(endptr(buf), remaining, fmt, ap);
va_end(ap);
if (!SNPRINTF_OVERFLOW(r, remaining)) {
buf->len += (unsigned int) r;
@@ -165,10 +180,10 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
return;
remaining = buf->space - buf->len;
va_start(ap, fmt);
- r = vsnprintf(buf->data + buf->len, remaining, fmt, ap);
+ r = vsnprintf(endptr(buf), remaining, fmt, ap);
va_end(ap);
if (SNPRINTF_OVERFLOW(r, remaining)) /* Shouldn't ever happen. */
- buf->buftype = BUFTYPE_ERROR;
+ k5_buf_free(buf);
else
buf->len += (unsigned int) r;
return;
@@ -180,12 +195,12 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
r = vasprintf(&tmp, fmt, ap);
va_end(ap);
if (r < 0) {
- buf->buftype = BUFTYPE_ERROR;
+ k5_buf_free(buf);
return;
}
if (ensure_space(buf, r)) {
/* Copy the temporary string into buf, including terminator. */
- memcpy(buf->data + buf->len, tmp, r + 1);
+ memcpy(endptr(buf), tmp, r + 1);
buf->len += r;
}
free(tmp);
@@ -197,40 +212,32 @@ k5_buf_get_space(struct k5buf *buf, size_t len)
if (!ensure_space(buf, len))
return NULL;
buf->len += len;
- buf->data[buf->len] = '\0';
- return &buf->data[buf->len - len];
+ *endptr(buf) = '\0';
+ return endptr(buf) - len;
}
void
k5_buf_truncate(struct k5buf *buf, size_t len)
{
- if (buf->buftype == BUFTYPE_ERROR)
+ if (buf->buftype == K5BUF_ERROR)
return;
assert(len <= buf->len);
buf->len = len;
- buf->data[buf->len] = '\0';
+ *endptr(buf) = '\0';
}
-
-char *
-k5_buf_data(struct k5buf *buf)
+int
+k5_buf_status(struct k5buf *buf)
{
- return (buf->buftype == BUFTYPE_ERROR) ? NULL : buf->data;
-}
-
-ssize_t
-k5_buf_len(struct k5buf *buf)
-{
- return (buf->buftype == BUFTYPE_ERROR) ? -1 : (ssize_t) buf->len;
+ return (buf->buftype == K5BUF_ERROR) ? ENOMEM : 0;
}
void
-k5_free_buf(struct k5buf *buf)
+k5_buf_free(struct k5buf *buf)
{
- if (buf->buftype == BUFTYPE_ERROR)
+ if (buf->buftype == K5BUF_ERROR)
return;
- assert(buf->buftype == BUFTYPE_DYNAMIC);
+ assert(buf->buftype == K5BUF_DYNAMIC);
free(buf->data);
- buf->data = NULL;
- buf->buftype = BUFTYPE_ERROR;
+ set_error(buf);
}
diff --git a/src/util/support/libkrb5support-fixed.exports b/src/util/support/libkrb5support-fixed.exports
index b5ca0b2..1aa2428 100644
--- a/src/util/support/libkrb5support-fixed.exports
+++ b/src/util/support/libkrb5support-fixed.exports
@@ -8,9 +8,8 @@ k5_buf_add_len
k5_buf_add_fmt
k5_buf_get_space
k5_buf_truncate
-k5_buf_data
-k5_buf_len
-k5_free_buf
+k5_buf_status
+k5_buf_free
k5_set_error
k5_vset_error
k5_get_error
diff --git a/src/util/support/t_k5buf.c b/src/util/support/t_k5buf.c
index 5e660d4..ba86851 100644
--- a/src/util/support/t_k5buf.c
+++ b/src/util/support/t_k5buf.c
@@ -24,7 +24,8 @@
* or implied warranty.
*/
-#include "k5buf-int.h"
+#include "k5-platform.h"
+#include "k5-buf.h"
#include <stdio.h>
#include <stdlib.h>
@@ -41,47 +42,45 @@ fail_if(int condition, const char *name)
static void
check_buf(struct k5buf *buf, const char *name)
{
- fail_if(buf->buftype != BUFTYPE_FIXED && buf->buftype != BUFTYPE_DYNAMIC
- && buf->buftype != BUFTYPE_ERROR, name);
- if (buf->buftype == BUFTYPE_ERROR)
- return;
- fail_if(buf->space == 0, name);
- fail_if(buf->space > SPACE_MAX, name);
- fail_if(buf->len >= buf->space, name);
- fail_if(buf->data[buf->len] != 0, name);
+ fail_if(buf->buftype != K5BUF_FIXED && buf->buftype != K5BUF_DYNAMIC &&
+ buf->buftype != K5BUF_ERROR, name);
+ if (buf->buftype == K5BUF_ERROR) {
+ fail_if(buf->data != NULL, name);
+ fail_if(buf->space != 0 || buf->len != 0, name);
+ } else {
+ fail_if(buf->space == 0, name);
+ fail_if(buf->len >= buf->space, name);
+ fail_if(((char *)buf->data)[buf->len] != 0, name);
+ }
}
static void
test_basic()
{
struct k5buf buf;
- char storage[1024], *s;
- ssize_t len;
+ char storage[1024];
k5_buf_init_fixed(&buf, storage, sizeof(storage));
k5_buf_add(&buf, "Hello ");
k5_buf_add_len(&buf, "world", 5);
check_buf(&buf, "basic fixed");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(!s || strcmp(s, "Hello world") != 0 || len != 11, "basic fixed");
+ fail_if(buf.data == NULL || buf.len != 11, "basic fixed");
+ fail_if(strcmp(buf.data, "Hello world") != 0, "basic fixed");
k5_buf_init_dynamic(&buf);
k5_buf_add_len(&buf, "Hello", 5);
k5_buf_add(&buf, " world");
check_buf(&buf, "basic dynamic");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(!s || strcmp(s, "Hello world") != 0 || len != 11, "basic dynamic");
- k5_free_buf(&buf);
+ fail_if(buf.data == NULL || buf.len != 11, "basic dynamic");
+ fail_if(strcmp(buf.data, "Hello world") != 0, "basic dynamic");
+ k5_buf_free(&buf);
}
static void
test_realloc()
{
struct k5buf buf;
- char data[1024], *s;
- ssize_t len;
+ char data[1024];
size_t i;
for (i = 0; i < sizeof(data); i++)
@@ -93,18 +92,16 @@ test_realloc()
k5_buf_add_len(&buf, data, 128);
fail_if(buf.space != 256, "realloc 1");
check_buf(&buf, "realloc 1");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(!s || len != 138 || memcmp(s, data, len) != 0, "realloc 1");
+ fail_if(buf.data == NULL || buf.len != 138, "realloc 1");
+ fail_if(memcmp(buf.data, data, buf.len) != 0, "realloc 1");
/* Cause the same buffer to double in size to 512 bytes. */
k5_buf_add_len(&buf, data, 128);
fail_if(buf.space != 512, "realloc 2");
check_buf(&buf, "realloc 2");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(!s || len != 266 || memcmp(s, data, len) != 0, "realloc 2");
- k5_free_buf(&buf);
+ fail_if(buf.data == NULL || buf.len != 266, "realloc 2");
+ fail_if(memcmp(buf.data, data, buf.len) != 0, "realloc 2");
+ k5_buf_free(&buf);
/* Cause a buffer to increase from 128 to 512 bytes directly. */
k5_buf_init_dynamic(&buf);
@@ -112,10 +109,9 @@ test_realloc()
k5_buf_add_len(&buf, data, 256);
fail_if(buf.space != 512, "realloc 3");
check_buf(&buf, "realloc 3");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(!s || len != 266 || memcmp(s, data, len) != 0, "realloc 3");
- k5_free_buf(&buf);
+ fail_if(buf.data == NULL || buf.len != 266, "realloc 3");
+ fail_if(memcmp(buf.data, data, buf.len) != 0, "realloc 3");
+ k5_buf_free(&buf);
/* Cause a buffer to increase from 128 to 1024 bytes directly. */
k5_buf_init_dynamic(&buf);
@@ -123,60 +119,38 @@ test_realloc()
k5_buf_add_len(&buf, data, 512);
fail_if(buf.space != 1024, "realloc 4");
check_buf(&buf, "realloc 4");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(!s || len != 522 || memcmp(s, data, len) != 0, "realloc 4");
- k5_free_buf(&buf);
-
- /* Cause a reallocation to fail by exceeding SPACE_MAX. */
- k5_buf_init_dynamic(&buf);
- k5_buf_add_len(&buf, data, 10);
- k5_buf_add_len(&buf, NULL, SPACE_MAX);
- check_buf(&buf, "realloc 5");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(buf.buftype != BUFTYPE_ERROR || s != NULL || len != -1,
- "realloc 5");
- k5_free_buf(&buf);
+ fail_if(buf.data == NULL || buf.len != 522, "realloc 4");
+ fail_if(memcmp(buf.data, data, buf.len) != 0, "realloc 4");
+ k5_buf_free(&buf);
/* Cause a reallocation to fail by integer overflow. */
k5_buf_init_dynamic(&buf);
k5_buf_add_len(&buf, data, 100);
- k5_buf_add_len(&buf, NULL, SPACE_MAX * 2);
- check_buf(&buf, "realloc 6");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(buf.buftype != BUFTYPE_ERROR || s != NULL || len != -1,
- "realloc 6");
- k5_free_buf(&buf);
+ k5_buf_add_len(&buf, NULL, SIZE_MAX);
+ check_buf(&buf, "realloc 5");
+ fail_if(buf.buftype != K5BUF_ERROR, "realloc 5");
+ k5_buf_free(&buf);
}
static void
test_overflow()
{
struct k5buf buf;
- char storage[10], *s;
- ssize_t len;
+ char storage[10];
/* Cause a fixed-sized buffer overflow. */
k5_buf_init_fixed(&buf, storage, sizeof(storage));
k5_buf_add(&buf, "12345");
k5_buf_add(&buf, "12345");
check_buf(&buf, "overflow 1");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(buf.buftype != BUFTYPE_ERROR || s != NULL || len != -1,
- "overflow 1");
+ fail_if(buf.buftype != K5BUF_ERROR, "overflow 1");
/* Cause a fixed-sized buffer overflow with integer overflow. */
k5_buf_init_fixed(&buf, storage, sizeof(storage));
k5_buf_add(&buf, "12345");
- k5_buf_add_len(&buf, NULL, SPACE_MAX * 2);
+ k5_buf_add_len(&buf, NULL, SIZE_MAX);
check_buf(&buf, "overflow 2");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(buf.buftype != BUFTYPE_ERROR || s != NULL || len != -1,
- "overflow 2");
+ fail_if(buf.buftype != K5BUF_ERROR, "overflow 2");
}
static void
@@ -188,7 +162,7 @@ test_error()
/* Cause an overflow and then perform actions afterwards. */
k5_buf_init_fixed(&buf, storage, sizeof(storage));
k5_buf_add(&buf, "1");
- fail_if(buf.buftype != BUFTYPE_ERROR, "error");
+ fail_if(buf.buftype != K5BUF_ERROR, "error");
check_buf(&buf, "error");
k5_buf_add(&buf, "test");
check_buf(&buf, "error");
@@ -196,52 +170,46 @@ test_error()
check_buf(&buf, "error");
k5_buf_truncate(&buf, 3);
check_buf(&buf, "error");
- fail_if(buf.buftype != BUFTYPE_ERROR, "error");
+ fail_if(buf.buftype != K5BUF_ERROR, "error");
}
static void
test_truncate()
{
struct k5buf buf;
- char *s;
- ssize_t len;
k5_buf_init_dynamic(&buf);
k5_buf_add(&buf, "abcde");
k5_buf_add(&buf, "fghij");
k5_buf_truncate(&buf, 7);
check_buf(&buf, "truncate");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(!s || len != 7 || strcmp(s, "abcdefg") != 0, "truncate");
- k5_free_buf(&buf);
+ fail_if(buf.data == NULL || buf.len != 7, "truncate");
+ fail_if(strcmp(buf.data, "abcdefg") != 0, "truncate");
+ k5_buf_free(&buf);
}
static void
test_binary()
{
struct k5buf buf;
- char *s, data[] = { 'a', 0, 'b' };
- ssize_t len;
+ char data[] = { 'a', 0, 'b' }, *s;
k5_buf_init_dynamic(&buf);
k5_buf_add_len(&buf, data, 3);
k5_buf_add_len(&buf, data, 3);
check_buf(&buf, "binary");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(!s || len != 6, "binary");
+ fail_if(buf.data == NULL || buf.len != 6, "binary");
+ s = buf.data;
fail_if(s[0] != 'a' || s[1] != 0 || s[2] != 'b', "binary");
fail_if(s[3] != 'a' || s[4] != 0 || s[5] != 'b', "binary");
- k5_free_buf(&buf);
+ k5_buf_free(&buf);
}
static void
test_fmt()
{
struct k5buf buf;
- char *s, storage[10], data[1024];
- ssize_t len;
+ char storage[10], data[1024];
size_t i;
for (i = 0; i < sizeof(data) - 1; i++)
@@ -253,34 +221,29 @@ test_fmt()
k5_buf_add(&buf, "foo");
k5_buf_add_fmt(&buf, " %d ", 3);
check_buf(&buf, "fmt 1");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(!s || len != 6 || strcmp(s, "foo 3 ") != 0, "fmt 1");
+ fail_if(buf.data == NULL || buf.len != 6, "fmt 1");
+ fail_if(strcmp(buf.data, "foo 3 ") != 0, "fmt 1");
/* Overflow the same buffer with formatted text. */
k5_buf_add_fmt(&buf, "%d%d%d%d", 1, 2, 3, 4);
check_buf(&buf, "fmt 2");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(buf.buftype != BUFTYPE_ERROR || s != NULL || len != -1, "fmt 2");
+ fail_if(buf.buftype != K5BUF_ERROR, "fmt 2");
/* Format some text into a non-empty dynamic buffer. */
k5_buf_init_dynamic(&buf);
k5_buf_add(&buf, "foo");
k5_buf_add_fmt(&buf, " %d ", 3);
check_buf(&buf, "fmt 3");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(!s || len != 6 || strcmp(s, "foo 3 ") != 0, "fmt 3");
+ fail_if(buf.data == NULL || buf.len != 6, "fmt 3");
+ fail_if(strcmp(buf.data, "foo 3 ") != 0, "fmt 3");
/* Format more text into the same buffer, causing a big resize. */
k5_buf_add_fmt(&buf, "%s", data);
check_buf(&buf, "fmt 4");
fail_if(buf.space != 2048, "fmt 4");
- s = k5_buf_data(&buf);
- len = k5_buf_len(&buf);
- fail_if(!s || len != 1029 || strcmp(s + 6, data) != 0, "fmt 4");
- k5_free_buf(&buf);
+ fail_if(buf.data == NULL || buf.len != 1029, "fmt 4");
+ fail_if(strcmp((char *)buf.data + 6, data) != 0, "fmt 4");
+ k5_buf_free(&buf);
}
int
More information about the cvs-krb5
mailing list