Path: blob/main/crypto/krb5/src/util/support/t_k5buf.c
34889 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/* util/support/t_k5buf.c - Test the k5buf string buffer module */2/*3* Copyright 2008 Massachusetts Institute of Technology.4* All Rights Reserved.5*6* Export of this software from the United States of America may7* require a specific license from the United States Government.8* It is the responsibility of any person or organization contemplating9* export to obtain such a license before exporting.10*11* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and12* distribute this software and its documentation for any purpose and13* without fee is hereby granted, provided that the above copyright14* notice appear in all copies and that both that copyright notice and15* this permission notice appear in supporting documentation, and that16* the name of M.I.T. not be used in advertising or publicity pertaining17* to distribution of the software without specific, written prior18* permission. Furthermore if you modify this software you must label19* your software as modified software and not distribute it in such a20* fashion that it might be confused with the original M.I.T. software.21* M.I.T. makes no representations about the suitability of22* this software for any purpose. It is provided "as is" without express23* or implied warranty.24*/2526#include "k5-platform.h"27#include "k5-buf.h"28#include <stdio.h>29#include <stdlib.h>3031static void32fail_if(int condition, const char *name)33{34if (condition) {35fprintf(stderr, "%s failed\n", name);36exit(1);37}38}3940/* Test the invariants of a buffer. */41static void42check_buf(struct k5buf *buf, const char *name)43{44fail_if(buf->buftype != K5BUF_FIXED && buf->buftype != K5BUF_DYNAMIC &&45buf->buftype != K5BUF_ERROR, name);46if (buf->buftype == K5BUF_ERROR) {47fail_if(buf->data != NULL, name);48fail_if(buf->space != 0 || buf->len != 0, name);49} else {50fail_if(buf->space == 0, name);51fail_if(buf->len >= buf->space, name);52}53}5455static void56test_basic(void)57{58struct k5buf buf;59char storage[1024];6061k5_buf_init_fixed(&buf, storage, sizeof(storage));62k5_buf_add(&buf, "Hello ");63k5_buf_add_len(&buf, "world", 5);64check_buf(&buf, "basic fixed");65fail_if(buf.data == NULL || buf.len != 11, "basic fixed");66fail_if(memcmp(buf.data, "Hello world", 11) != 0, "basic fixed");6768k5_buf_init_dynamic(&buf);69k5_buf_add_len(&buf, "Hello", 5);70k5_buf_add(&buf, " world");71check_buf(&buf, "basic dynamic");72fail_if(buf.data == NULL || buf.len != 11, "basic dynamic");73fail_if(memcmp(buf.data, "Hello world", 11) != 0, "basic dynamic");74k5_buf_free(&buf);75}7677static void78test_realloc(void)79{80struct k5buf buf;81char data[1024];82size_t i;8384for (i = 0; i < sizeof(data); i++)85data[i] = 'a';8687/* Cause the buffer size to double from 128 to 256 bytes. */88k5_buf_init_dynamic(&buf);89k5_buf_add_len(&buf, data, 10);90k5_buf_add_len(&buf, data, 128);91fail_if(buf.space != 256, "realloc 1");92check_buf(&buf, "realloc 1");93fail_if(buf.data == NULL || buf.len != 138, "realloc 1");94fail_if(memcmp(buf.data, data, buf.len) != 0, "realloc 1");9596/* Cause the same buffer to double in size to 512 bytes. */97k5_buf_add_len(&buf, data, 128);98fail_if(buf.space != 512, "realloc 2");99check_buf(&buf, "realloc 2");100fail_if(buf.data == NULL || buf.len != 266, "realloc 2");101fail_if(memcmp(buf.data, data, buf.len) != 0, "realloc 2");102k5_buf_free(&buf);103104/* Cause a buffer to increase from 128 to 512 bytes directly. */105k5_buf_init_dynamic(&buf);106k5_buf_add_len(&buf, data, 10);107k5_buf_add_len(&buf, data, 256);108fail_if(buf.space != 512, "realloc 3");109check_buf(&buf, "realloc 3");110fail_if(buf.data == NULL || buf.len != 266, "realloc 3");111fail_if(memcmp(buf.data, data, buf.len) != 0, "realloc 3");112k5_buf_free(&buf);113114/* Cause a buffer to increase from 128 to 1024 bytes directly. */115k5_buf_init_dynamic(&buf);116k5_buf_add_len(&buf, data, 10);117k5_buf_add_len(&buf, data, 512);118fail_if(buf.space != 1024, "realloc 4");119check_buf(&buf, "realloc 4");120fail_if(buf.data == NULL || buf.len != 522, "realloc 4");121fail_if(memcmp(buf.data, data, buf.len) != 0, "realloc 4");122k5_buf_free(&buf);123124/* Cause a reallocation to fail by integer overflow. */125k5_buf_init_dynamic(&buf);126k5_buf_add_len(&buf, data, 100);127k5_buf_add_len(&buf, NULL, SIZE_MAX);128check_buf(&buf, "realloc 5");129fail_if(buf.buftype != K5BUF_ERROR, "realloc 5");130k5_buf_free(&buf);131}132133static void134test_overflow(void)135{136struct k5buf buf;137char storage[10];138139/* Cause a fixed-sized buffer overflow. */140k5_buf_init_fixed(&buf, storage, sizeof(storage));141k5_buf_add(&buf, "12345");142k5_buf_add(&buf, "123456");143check_buf(&buf, "overflow 1");144fail_if(buf.buftype != K5BUF_ERROR, "overflow 1");145146/* Cause a fixed-sized buffer overflow with integer overflow. */147k5_buf_init_fixed(&buf, storage, sizeof(storage));148k5_buf_add(&buf, "12345");149k5_buf_add_len(&buf, NULL, SIZE_MAX);150check_buf(&buf, "overflow 2");151fail_if(buf.buftype != K5BUF_ERROR, "overflow 2");152}153154static void155test_error(void)156{157struct k5buf buf;158char storage[1];159160/* Cause an overflow and then perform actions afterwards. */161k5_buf_init_fixed(&buf, storage, sizeof(storage));162k5_buf_add(&buf, "12");163fail_if(buf.buftype != K5BUF_ERROR, "error");164check_buf(&buf, "error");165k5_buf_add(&buf, "test");166check_buf(&buf, "error");167k5_buf_add_len(&buf, "test", 4);168check_buf(&buf, "error");169k5_buf_truncate(&buf, 3);170check_buf(&buf, "error");171fail_if(buf.buftype != K5BUF_ERROR, "error");172}173174static void175test_truncate(void)176{177struct k5buf buf;178179k5_buf_init_dynamic(&buf);180k5_buf_add(&buf, "abcde");181k5_buf_add(&buf, "fghij");182k5_buf_truncate(&buf, 7);183check_buf(&buf, "truncate");184fail_if(buf.data == NULL || buf.len != 7, "truncate");185fail_if(memcmp(buf.data, "abcdefg", 7) != 0, "truncate");186k5_buf_free(&buf);187}188189static void190test_binary(void)191{192struct k5buf buf;193char data[] = { 'a', 0, 'b' }, *s;194195k5_buf_init_dynamic(&buf);196k5_buf_add_len(&buf, data, 3);197k5_buf_add_len(&buf, data, 3);198check_buf(&buf, "binary");199fail_if(buf.data == NULL || buf.len != 6, "binary");200s = buf.data;201fail_if(s[0] != 'a' || s[1] != 0 || s[2] != 'b', "binary");202fail_if(s[3] != 'a' || s[4] != 0 || s[5] != 'b', "binary");203k5_buf_free(&buf);204}205206static void207test_fmt(void)208{209struct k5buf buf;210char storage[10], data[1024];211size_t i;212213for (i = 0; i < sizeof(data) - 1; i++)214data[i] = 'a';215data[i] = '\0';216217/* Format some text into a non-empty fixed buffer. */218k5_buf_init_fixed(&buf, storage, sizeof(storage));219k5_buf_add(&buf, "foo");220k5_buf_add_fmt(&buf, " %d ", 3);221check_buf(&buf, "fmt 1");222fail_if(buf.data == NULL || buf.len != 6, "fmt 1");223fail_if(memcmp(buf.data, "foo 3 ", 6) != 0, "fmt 1");224225/* Overflow the same buffer with formatted text. */226k5_buf_add_fmt(&buf, "%d%d%d%d", 1, 2, 3, 4);227check_buf(&buf, "fmt 2");228fail_if(buf.buftype != K5BUF_ERROR, "fmt 2");229230/* Format some text into a non-empty dynamic buffer. */231k5_buf_init_dynamic(&buf);232k5_buf_add(&buf, "foo");233k5_buf_add_fmt(&buf, " %d ", 3);234check_buf(&buf, "fmt 3");235fail_if(buf.data == NULL || buf.len != 6, "fmt 3");236fail_if(memcmp(buf.data, "foo 3 ", 6) != 0, "fmt 3");237238/* Format more text into the same buffer, causing a big resize. */239k5_buf_add_fmt(&buf, "%s", data);240check_buf(&buf, "fmt 4");241fail_if(buf.space != 2048, "fmt 4");242fail_if(buf.data == NULL || buf.len != 1029, "fmt 4");243fail_if(memcmp((char *)buf.data + 6, data, 1023) != 0, "fmt 4");244k5_buf_free(&buf);245}246247int248main(void)249{250test_basic();251test_realloc();252test_overflow();253test_error();254test_truncate();255test_binary();256test_fmt();257return 0;258}259260261