#include "k5buf-int.h"
#include <stdio.h>
#include <stdlib.h>
static void fail_if(int condition, const char *name)
{
if (condition) {
fprintf(stderr, "%s failed\n", name);
exit(1);
}
}
static void check_buf(struct k5buf *buf, const char *name)
{
fail_if(buf->buftype != FIXED && buf->buftype != DYNAMIC
&& buf->buftype != ERROR, name);
if (buf->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);
}
static void test_basic()
{
struct k5buf buf;
char storage[1024], *s;
ssize_t len;
krb5int_buf_init_fixed(&buf, storage, sizeof(storage));
krb5int_buf_add(&buf, "Hello ");
krb5int_buf_add_len(&buf, "world", 5);
check_buf(&buf, "basic fixed");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(!s || strcmp(s, "Hello world") != 0 || len != 11, "basic fixed");
krb5int_buf_init_dynamic(&buf);
krb5int_buf_add_len(&buf, "Hello", 5);
krb5int_buf_add(&buf, " world");
check_buf(&buf, "basic dynamic");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(!s || strcmp(s, "Hello world") != 0 || len != 11, "basic dynamic");
krb5int_free_buf(&buf);
}
static void test_realloc()
{
struct k5buf buf;
char data[1024], *s;
ssize_t len;
size_t i;
for (i = 0; i < sizeof(data); i++)
data[i] = 'a';
krb5int_buf_init_dynamic(&buf);
krb5int_buf_add_len(&buf, data, 10);
krb5int_buf_add_len(&buf, data, 128);
fail_if(buf.space != 256, "realloc 1");
check_buf(&buf, "realloc 1");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(!s || len != 138 || memcmp(s, data, len) != 0, "realloc 1");
krb5int_buf_add_len(&buf, data, 128);
fail_if(buf.space != 512, "realloc 2");
check_buf(&buf, "realloc 2");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(!s || len != 266 || memcmp(s, data, len) != 0, "realloc 2");
krb5int_free_buf(&buf);
krb5int_buf_init_dynamic(&buf);
krb5int_buf_add_len(&buf, data, 10);
krb5int_buf_add_len(&buf, data, 256);
fail_if(buf.space != 512, "realloc 3");
check_buf(&buf, "realloc 3");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(!s || len != 266 || memcmp(s, data, len) != 0, "realloc 3");
krb5int_free_buf(&buf);
krb5int_buf_init_dynamic(&buf);
krb5int_buf_add_len(&buf, data, 10);
krb5int_buf_add_len(&buf, data, 512);
fail_if(buf.space != 1024, "realloc 4");
check_buf(&buf, "realloc 4");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(!s || len != 522 || memcmp(s, data, len) != 0, "realloc 4");
krb5int_free_buf(&buf);
krb5int_buf_init_dynamic(&buf);
krb5int_buf_add_len(&buf, data, 10);
krb5int_buf_add_len(&buf, NULL, SPACE_MAX);
check_buf(&buf, "realloc 5");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(buf.buftype != ERROR || s != NULL || len != -1, "realloc 5");
krb5int_free_buf(&buf);
krb5int_buf_init_dynamic(&buf);
krb5int_buf_add_len(&buf, data, 100);
krb5int_buf_add_len(&buf, NULL, SPACE_MAX * 2);
check_buf(&buf, "realloc 6");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(buf.buftype != ERROR || s != NULL || len != -1, "realloc 6");
krb5int_free_buf(&buf);
}
static void test_overflow()
{
struct k5buf buf;
char storage[10], *s;
ssize_t len;
krb5int_buf_init_fixed(&buf, storage, sizeof(storage));
krb5int_buf_add(&buf, "12345");
krb5int_buf_add(&buf, "12345");
check_buf(&buf, "overflow 1");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(buf.buftype != ERROR || s != NULL || len != -1, "overflow 1");
krb5int_buf_init_fixed(&buf, storage, sizeof(storage));
krb5int_buf_add(&buf, "12345");
krb5int_buf_add_len(&buf, NULL, SPACE_MAX * 2);
check_buf(&buf, "overflow 2");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(buf.buftype != ERROR || s != NULL || len != -1, "overflow 2");
}
static void test_error()
{
struct k5buf buf;
char storage[1];
krb5int_buf_init_fixed(&buf, storage, sizeof(storage));
krb5int_buf_add(&buf, "1");
fail_if(buf.buftype != ERROR, "error");
check_buf(&buf, "error");
krb5int_buf_add(&buf, "test");
check_buf(&buf, "error");
krb5int_buf_add_len(&buf, "test", 4);
check_buf(&buf, "error");
krb5int_buf_truncate(&buf, 3);
check_buf(&buf, "error");
fail_if(buf.buftype != ERROR, "error");
}
static void test_truncate()
{
struct k5buf buf;
char *s;
ssize_t len;
krb5int_buf_init_dynamic(&buf);
krb5int_buf_add(&buf, "abcde");
krb5int_buf_add(&buf, "fghij");
krb5int_buf_truncate(&buf, 7);
check_buf(&buf, "truncate");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(!s || len != 7 || strcmp(s, "abcdefg") != 0, "truncate");
krb5int_free_buf(&buf);
}
static void test_binary()
{
struct k5buf buf;
char *s, data[] = { 'a', 0, 'b' };
ssize_t len;
krb5int_buf_init_dynamic(&buf);
krb5int_buf_add_len(&buf, data, 3);
krb5int_buf_add_len(&buf, data, 3);
check_buf(&buf, "binary");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(!s || len != 6, "binary");
fail_if(s[0] != 'a' || s[1] != 0 || s[2] != 'b', "binary");
fail_if(s[3] != 'a' || s[4] != 0 || s[5] != 'b', "binary");
krb5int_free_buf(&buf);
}
static void test_fmt()
{
struct k5buf buf;
char *s, storage[10], data[1024];
ssize_t len;
size_t i;
for (i = 0; i < sizeof(data) - 1; i++)
data[i] = 'a';
data[i] = '\0';
krb5int_buf_init_fixed(&buf, storage, sizeof(storage));
krb5int_buf_add(&buf, "foo");
krb5int_buf_add_fmt(&buf, " %d ", 3);
check_buf(&buf, "fmt 1");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(!s || len != 6 || strcmp(s, "foo 3 ") != 0, "fmt 1");
krb5int_buf_add_fmt(&buf, "%d%d%d%d", 1, 2, 3, 4);
check_buf(&buf, "fmt 2");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(buf.buftype != ERROR || s != NULL || len != -1, "fmt 2");
krb5int_buf_init_dynamic(&buf);
krb5int_buf_add(&buf, "foo");
krb5int_buf_add_fmt(&buf, " %d ", 3);
check_buf(&buf, "fmt 3");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(!s || len != 6 || strcmp(s, "foo 3 ") != 0, "fmt 3");
krb5int_buf_add_fmt(&buf, "%s", data);
check_buf(&buf, "fmt 4");
fail_if(buf.space != 2048, "fmt 4");
s = krb5int_buf_data(&buf);
len = krb5int_buf_len(&buf);
fail_if(!s || len != 1029 || strcmp(s + 6, data) != 0, "fmt 4");
krb5int_free_buf(&buf);
}
int main()
{
test_basic();
test_realloc();
test_overflow();
test_error();
test_truncate();
test_binary();
test_fmt();
return 0;
}