#include "safestr.h"
#include <xxl.h>
#include <stdlib.h>
#include <string.h>
#define FAIL(why) \
do { \
fprintf(stderr, "%s\n", (why)); \
exit(1); \
} while (0)
static void
test_alloc(void)
{
int passed;
safestr_t str;
XXL_ASSET_BLOCK_BEGIN {
str = safestr_alloc(512, SAFESTR_ASSET_TEMPORARY);
if (safestr_length(str) != 0)
FAIL("Allocated string has a length!");
} XXL_ASSET_BLOCK_END;
XXL_TRY_BEGIN {
passed = 0;
safestr_free(str);
} XXL_CATCH(SAFESTR_ERROR_BAD_ADDRESS) {
passed = 1;
} XXL_TRY_END;
if (!passed) FAIL("SafeStr asset management didn't clean up properly!");
str = safestr_alloc(1, 0);
safestr_reference(str);
XXL_TRY_BEGIN {
passed = 1;
safestr_free(str);
} XXL_CATCH(SAFESTR_ERROR_BAD_ADDRESS) {
passed = 0;
} XXL_TRY_END;
if (!passed) FAIL("safestr_free(1) failed");
XXL_TRY_BEGIN {
passed = 1;
safestr_free(str);
} XXL_CATCH(SAFESTR_ERROR_BAD_ADDRESS) {
passed = 0;
} XXL_TRY_END;
if (!passed) FAIL("safestr_free(2) failed");
XXL_TRY_BEGIN {
passed = 0;
safestr_free(str);
} XXL_CATCH(SAFESTR_ERROR_BAD_ADDRESS) {
passed = 1;
} XXL_TRY_END;
if (!passed) FAIL("safestr_free(3) failed");
}
static void
test_create(void)
{
int passed;
char *c_str;
safestr_t clone, str;
u_int32_t i;
/* safestr_create() */
c_str = "A quick brown fox jumps over the lazy dog.";
str = safestr_create(c_str, SAFESTR_IMMUTABLE);
if (safestr_length(str) != strlen(c_str))
FAIL("String length after safestr_create() is wrong!");
/* safestr_charat() */
for (i = safestr_length(str); i > 0; i--) {
if (safestr_charat(str, i - 1) != c_str[i - 1])
FAIL("safestr_charat() fails!");
}
XXL_TRY_BEGIN {
passed = 0;
safestr_charat(str, safestr_length(str));
} XXL_CATCH(SAFESTR_ERROR_INDEX_OUT_OF_RANGE) {
passed = 1;
} XXL_TRY_END;
if (!passed) FAIL("safestr_charat with index out of range failed to throw!");
/* safestr_setcharat(), immutability, etc. */
XXL_TRY_BEGIN {
passed = 0;
safestr_setcharat(str, 0, 'a', 1);
} XXL_CATCH(SAFESTR_ERROR_IMMUTABLE_STRING) {
passed = 1;
} XXL_TRY_END;
if (!passed) FAIL("safestr_setcharat on immutable string failed to throw!");
safestr_makewritable(str);
safestr_setcharat(str, 0, 'a', 1);
if (safestr_charat(str, 0) != 'a')
FAIL("safestr_setcharat failed to modify the string!");
XXL_TRY_BEGIN {
passed = 0;
safestr_setcharat(str, safestr_length(str), 'X', 1);
} XXL_CATCH(SAFESTR_ERROR_INDEX_OUT_OF_RANGE) {
passed = 1;
} XXL_TRY_END;
if (!passed) FAIL("safestr_setcharat with index out of range failed to throw!");
safestr_setcharat(str, 0, 'A', 1);
if (safestr_charat(str, 0) != 'A')
FAIL("safestr_setcharat failed to modify the string (2)!");
safestr_makereadonly(str);
XXL_TRY_BEGIN {
passed = 0;
safestr_setcharat(str, 0, 'X', 1);
} XXL_CATCH(SAFESTR_ERROR_IMMUTABLE_STRING) {
passed = 1;
} XXL_TRY_END;
if (!passed) FAIL("safestr_makereadonly failed to make the string immutable!");
/* safestr_clone() */
clone = safestr_clone(str, 0);
if (safestr_length(clone) != safestr_length(str))
FAIL("Cloned string's length does not match source length!");
if (!safestr_equal(clone, str, 0)) {
if (strcmp((char *)clone, (char *)str)) {
printf("str: [%s]\nclone: [%s]\n", (char *)str, (char *)clone);
FAIL("Cloned string's content is incorrect.");
}
FAIL("safestr_equal() failed to match two equal strings!");
}
/* safestr_makereadonly(), safestr_makewritable(), safestr_isreadonly() */
if (!safestr_isreadonly(str)) FAIL("String isn't read-only as expected!");
safestr_makewritable(str);
if (safestr_isreadonly(str)) FAIL("String is read-only and shouldn't be!");
safestr_makereadonly(str);
if (!safestr_isreadonly(str)) FAIL("String isn't read-only and should be!");
safestr_makewritable(str);
/* safestr_convert() */
c_str = "A QUICK BROWN FOX JUMPS OVER THE LAZY DOG.";
safestr_convert(str, SAFESTR_CONVERT_UPPERCASE);
if (!safestr_equal(str, SAFESTR_TEMP(c_str), 0)) {
if (strcmp((char *)str, c_str)) {
printf("str: [%s]\nc_str: [%s]\n", (char *)str, c_str);
FAIL("Uppercase converted string's content is incorrect.");
}
FAIL("safestr_equal() failed to match two equal strings!");
}
c_str = "a quick brown fox jumps over the lazy dog.";
safestr_convert(str, SAFESTR_CONVERT_LOWERCASE);
if (!safestr_equal(str, SAFESTR_TEMP(c_str), 0)) {
if (strcmp((char *)str, c_str)) {
printf("str: [%s]\nc_str: [%s]\n", (char *)str, c_str);
FAIL("Lowercase convert string's content is incorrect.");
}
FAIL("safestr_equal() failed to match two equal strings!");
}
c_str = "A Quick Brown Fox Jumps Over The Lazy Dog.";
safestr_convert(str, SAFESTR_CONVERT_TITLECASE);
if (!safestr_equal(str, SAFESTR_TEMP(c_str), 0)) {
if (strcmp((char *)str, c_str)) {
printf("str: [%s]\nc_str: [%s]\n", (char *)str, c_str);
FAIL("Titlecase convert string's content is incorrect.");
}
FAIL("safestr_equal() failed to match two equal strings!");
}
/* safestr_free() */
safestr_free(clone);
safestr_free(str);
XXL_TRY_BEGIN {
passed = 0;
safestr_free(str);
} XXL_CATCH(SAFESTR_ERROR_BAD_ADDRESS) {
passed = 1;
} XXL_TRY_END;
if (!passed) FAIL("safestr_free failed to free 'str'");
XXL_TRY_BEGIN {
passed = 0;
safestr_free(clone);
} XXL_CATCH(SAFESTR_ERROR_BAD_ADDRESS) {
passed = 1;
} XXL_TRY_END;
if (!passed) FAIL("safestr_free failed to free 'clone'");
}
static void
test_comparison(void)
{
char *c_str;
safestr_t str1, str2;
str1 = safestr_create("/Volumes/Music/iTunes/iTunes Music/Fischerspooner/Exclusive/Emerge.aac", 0);
str2 = safestr_clone(str1, 0);
if (!safestr_equal(str1, str2, 0))
FAIL("safestr_equal(1) failed!");
if (safestr_compare(str1, str2, 0))
FAIL("safestr_compare(1) failed!");
safestr_convert(str2, SAFESTR_CONVERT_LOWERCASE);
if (!safestr_equal(str1, str2, SAFESTR_COMPARE_NOCASE))
FAIL("safestr_equal(2) failed!");
if (safestr_compare(str1, str2, SAFESTR_COMPARE_NOCASE))
FAIL("safestr_compare(2) failed!");
c_str = "/Volumes/Music/iTunes";
safestr_duplicate(&str2, SAFESTR_TEMP(c_str), 0);
if (safestr_length(str2) != strlen(c_str))
FAIL("String length after safestr_duplicate() doesn't match!");
if (!safestr_equal(str2, SAFESTR_TEMP(c_str), 0)) {
printf("str1: [%s]\nc_str: [%s]\n", (char *)str2, c_str);
FAIL("Duplicated string contents don't match!");
}
if (!safestr_equal(str1, str2, SAFESTR_COMPARE_LIMIT, safestr_length(str2)))
FAIL("Limited safestr_equal doesn't match!");
if (safestr_compare(str1, str2, SAFESTR_COMPARE_LIMIT, safestr_length(str2)))
FAIL("Limited safestr_compare doesn't match!");
safestr_free(str2);
safestr_free(str1);
}
static void
test_modify(void)
{
char *c_str;
safestr_t str1;
u_int32_t length;
c_str = "A brown fox jumped over the stupid dog.";
str1 = safestr_create(c_str, SAFESTR_TRUSTED);
if (!safestr_istrusted(str1))
FAIL("String is not trusted as expected!");
if (safestr_length(str1) != strlen(c_str))
FAIL("String lengths don't match after safestr_create()!");
safestr_replace(&str1, SAFESTR_TEMP("jumped"), SAFESTR_TEMP("jumps"));
c_str = "A brown fox jumps over the stupid dog.";
if (!safestr_equal(str1, SAFESTR_TEMP(c_str), 0)) {
printf("str1: [%s] length = %u\nc_str: [%s] length = %zu\n",
(char *)str1, safestr_length(str1), c_str, strlen(c_str));
FAIL("Strings don't match after safestr_replace()!");
}
if (safestr_istrusted(str1))
FAIL("String is trusted after safestr_replace() and shouldn't be!");
safestr_trust(str1);
if (!safestr_istrusted(str1))
FAIL("String is not trusted after safestr_trust() and should be!");
safestr_replace(&str1, SAFESTR_TEMP("stupid"), SAFESTR_TEMP_TRUSTED("lazy"));
if (!safestr_istrusted(str1))
FAIL("String isn't trusted after safestr_replace() and should be!");
safestr_untrust(str1);
if (safestr_istrusted(str1))
FAIL("String is trusted after safestr_untrust() and shouldn't be!");
safestr_trust(str1);
safestr_insert(&str1, 2, SAFESTR_TEMP_TRUSTED("quick and dirty "));
c_str = "A quick and dirty brown fox jumps over the lazy dog.";
if (!safestr_equal(str1, SAFESTR_TEMP(c_str), 0)) {
printf("str1: [%s]\nc_str: [%s]\n", (char *)str1, c_str);
FAIL("Strings don't match after safestr_insert()!");
}
if (!safestr_istrusted(str1))
FAIL("String isn't trusted after safestr_insert() and should be!");
safestr_delete(&str1, 8, 10);
c_str = "A quick brown fox jumps over the lazy dog.";
if (!safestr_equal(str1, SAFESTR_TEMP(c_str), 0)) {
printf("str1: [%s]\nc_str: [%s]\n", (char *)str1, c_str);
FAIL("Strings don't match after safestr_delete()!");
}
length = safestr_length(str1);
safestr_append(&str1, SAFESTR_TEMP(" Word."));
c_str = "A quick brown fox jumps over the lazy dog. Word.";
if (!safestr_equal(str1, SAFESTR_TEMP(c_str), 0)) {
printf("str1: [%s]\nc_str: [%s]\n", (char *)str1, c_str);
FAIL("Strings don't match after safestr_concatenate()!");
}
if (safestr_istrusted(str1))
FAIL("String is trusted after safestr_concatenate() and shouldn't be!");
safestr_delete(&str1, length, length);
c_str = "A quick brown fox jumps over the lazy dog.";
if (!safestr_equal(str1, SAFESTR_TEMP(c_str), 0)) {
printf("str1: [%s]\nc_str: [%s]\n", (char *)str1, c_str);
FAIL("Strings don't match after safestr_delete()! (2)");
}
safestr_free(str1);
}
static char *c_array[] = {
"A", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog.",
NULL
};
static void
test_arrays(void)
{
char *c_str;
u_int32_t c_length, i, safe_length;
safestr_t *safe_array, str;
for (c_length = 0; c_array[c_length]; c_length++);
safe_array = safestr_convertarray(c_array, SAFESTR_TRUSTED | SAFESTR_IMMUTABLE);
for (safe_length = 0; safe_array[safe_length]; safe_length++);
if (c_length != safe_length)
FAIL("safestr_convertarray() array size doesn't match original!");
for (i = 0; safe_array[i]; i++) {
if (!safestr_equal(safe_array[i], SAFESTR_TEMP(c_array[i]), 0))
FAIL("safestr_convertarray() array contents don't match original!");
}
str = safestr_join(safe_array, SAFESTR_TEMP_TRUSTED(" "));
c_str = "A quick brown fox jumps over the lazy dog.";
if (!safestr_equal(str, SAFESTR_TEMP(c_str), 0)) {
printf("str: [%s]\nc_str: [%s]\n", (char *)str, c_str);
FAIL("Strings don't match after safestr_join()!");
}
if (!safestr_istrusted(str))
FAIL("String isn't trusted after safestr_join() and should be!");
for (i = 0; safe_array[i]; safestr_free(safe_array[i++]));
free(safe_array);
safe_array = safestr_split(str, SAFESTR_TEMP(" "));
for (safe_length = 0; safe_array[safe_length]; safe_length++);
if (c_length != safe_length)
FAIL("safestr_split() array size doesn't match original!");
for (i = 0; safe_array[i]; i++) {
if (!safestr_equal(safe_array[i], SAFESTR_TEMP(c_array[i]), 0))
FAIL("safestr_split() array contents don't match original!");
}
for (i = 0; safe_array[i]; safestr_free(safe_array[i++]));
free(safe_array);
safe_array = safestr_split(str, SAFESTR_TEMP(""));
for (safe_length = 0; safe_array[safe_length]; safe_length++);
if (strlen(c_str) != safe_length)
FAIL("safestr_split() character array size doesn't match original!");
for (i = 0; safe_array[i]; i++) {
if (safestr_length(safe_array[i]) != 1)
FAIL("safestr_length() on character array element != 1!");
if (safestr_charat(safe_array[i], 0) != c_str[i])
FAIL("safestr_charat() on character array element != original!");
}
safestr_free(str);
for (i = 0; safe_array[i]; safestr_free(safe_array[i++]));
free(safe_array);
}
static void
test_misc(void)
{
char *c_str;
safestr_t slice, str;
u_int32_t idx;
c_str = "A quick brown fox jumps over the lazy dog.";
str = safestr_create(c_str, 0);
idx = safestr_search(str, SAFESTR_TEMP("fox"), 0);
if (idx != (u_int32_t)(strstr(c_str, "fox") - c_str))
FAIL("safestr_search() result not as expected!");
if (safestr_search(str, SAFESTR_TEMP("FOX"), SAFESTR_FIND_NOMATCHCASE) != idx)
FAIL("safestr_search() case insensitive search result erroneous!");
if (safestr_search(str, SAFESTR_TEMP("fox"), SAFESTR_FIND_REVERSE) != idx)
FAIL("safestr_search() reverse search result erroneous!");
if (safestr_search(str, SAFESTR_TEMP("foo"), 0) != SAFESTR_ERROR_NOTFOUND)
FAIL("safestr_search() found non-existant substring!");
if (safestr_search(str, SAFESTR_TEMP("fox"), SAFESTR_FIND_FROMCHAR, 10) != idx)
FAIL("safestr_search() w/FROMCHAR search result erroneous!");
c_str = "The house with the white fence is also painted white.";
safestr_copy(&str, SAFESTR_TEMP(c_str));
idx = safestr_search(str, SAFESTR_TEMP("white"), 0);
if (idx != (u_int32_t)(strstr(c_str, "white") - c_str))
FAIL("safestr_search() result not as expected! (2)");
idx = safestr_search(str, SAFESTR_TEMP("white"), SAFESTR_FIND_NTH, 2);
if (idx != (u_int32_t)(strstr(strstr(c_str, "white") + 5, "white") - c_str))
FAIL("safestr_search() result not as expected! (3)");
idx = safestr_search(str, SAFESTR_TEMP("white"), SAFESTR_FIND_FROMNTH, 1);
if (idx != (u_int32_t)(strstr(strstr(c_str, "white") + 5, "white") - c_str))
FAIL("safestr_search() result not as expected! (4)");
idx = safestr_search(str, SAFESTR_TEMP("white"), SAFESTR_FIND_REVERSE | SAFESTR_FIND_NTH, 2);
if (idx != (u_int32_t)(strstr(c_str, "white") - c_str))
FAIL("safestr_search() reverse not as expected!");
c_str = "white.";
idx = safestr_search(str, SAFESTR_TEMP("white"), SAFESTR_FIND_REVERSE);
slice = safestr_slice(str, idx, safestr_length(str));
if (!safestr_equal(slice, SAFESTR_TEMP(c_str), 0)) {
printf("slice: [%s]\nc_str: [%s]\n", (char *)slice, c_str);
FAIL("Sliced string is not correct!");
}
safestr_free(slice);
c_str = "house";
slice = safestr_slice(str, 4, 4 + strlen(c_str));
if (!safestr_equal(slice, SAFESTR_TEMP(c_str), 0)) {
printf("slice: [%s]\nc_str: [%s]\n", (char *)slice, c_str);
FAIL("Sliced string is not correct! (2)");
}
safestr_free(slice);
safestr_truncate(&str, 0);
if (safestr_length(str) != 0)
FAIL("String length is wrong after first safestr_truncate()!");
safestr_truncate(&str, 10);
if (safestr_length(str) != 10)
FAIL("String length is wrong after second safestr_truncate()!");
c_str = " ";
if (!safestr_equal(str, SAFESTR_TEMP(c_str), 0)) {
printf("str: [%s]\nc_str: [%s]\n", (char *)str, c_str);
FAIL("String contents are wrong after second safestr_truncate()!");
}
c_str = " \t foo\t\t\t \t\t\t";
safestr_copy(&str, SAFESTR_TEMP(c_str));
safestr_trim(str, SAFESTR_TRIM_LEADING);
if (!safestr_equal(str, SAFESTR_TEMP(c_str + 3), 0)) {
printf("str: [%s]\nc_str: [%s]\n", (char *)str, c_str + 3);
FAIL("String contents are wrong after leading space trim!");
}
safestr_copy(&str, SAFESTR_TEMP(c_str));
safestr_trim(str, SAFESTR_TRIM_TRAILING);
if (!safestr_equal(str, SAFESTR_TEMP(" \t foo"), 0)) {
printf("str: [%s]\nc_str: [ \t foo]\n", (char *)str);
FAIL("String contents are wrong after trailing space trim!");
}
safestr_copy(&str, SAFESTR_TEMP(c_str));
safestr_trim(str, SAFESTR_TRIM_BOTH);
if (!safestr_equal(str, SAFESTR_TEMP("foo"), 0)) {
printf("str: [%s]\nc_str: [foo]\n", (char *)str);
FAIL("String contents are wrong after leading AND trailing space trim!");
}
safestr_copy(&str, SAFESTR_TEMP("0xdeadbeef"));
if (safestr_toint32(str, 0) != (int32_t)0xdeadbeef) {
printf("safestr_toint32(\"0xdeadbeef\", 0) == %#08x\n", safestr_toint32(str, 0));
FAIL("safestr_toint32(\"0xdeadbeef\", 0) FAILED");
}
if (safestr_toint64(str, 0) != (int64_t)0xdeadbeef) {
printf("safestr_toint64(\"0xdeadbeef\", 0) == %#08llx\n", safestr_toint64(str, 0));
FAIL("safestr_toint64(\"0xdeadbeef\", 0) FAILED");
}
if (safestr_touint32(str, 0) != (u_int32_t)0xdeadbeef) {
printf("safestr_touint32(\"0xdeadbeef\", 0) == %#08x\n", safestr_touint32(str, 0));
FAIL("safestr_touint32(\"0xdeadbeef\", 0) FAILED");
}
if (safestr_touint64(str, 0) != (u_int64_t)0xdeadbeef) {
printf("safestr_touint64(\"0xdeadbeef\", 0) == %#08llx\n", safestr_touint64(str, 0));
FAIL("safestr_touint64(\"0xdeadbeef\", 0) FAILED");
}
safestr_copy(&str, SAFESTR_TEMP("0xDEADBEEF"));
if (safestr_toint32(str, 16) != (int32_t)0xDEADBEEF) {
printf("safestr_toint32(\"0xDEADBEEF\", 16) == %#08x\n", safestr_toint32(str, 16));
FAIL("safestr_toint32(\"0xDEADBEEF\", 16) FAILED");
}
if (safestr_toint64(str, 16) != (int64_t)0xDEADBEEF) {
printf("safestr_toint64(\"0xDEADBEEF\", 16) == %#08llx\n", safestr_toint64(str, 16));
FAIL("safestr_toint64(\"0xDEADBEEF\", 16) FAILED");
}
if (safestr_touint32(str, 16) != (u_int32_t)0xDEADBEEF) {
printf("safestr_touint32(\"0xDEADBEEF\", 16) == %#08x\n", safestr_touint32(str, 16));
FAIL("safestr_touint32(\"0xDEADBEEF\", 16) FAILED");
}
if (safestr_touint64(str, 16) != (u_int64_t)0xDEADBEEF) {
printf("safestr_touint64(\"0xDEADBEEF\", 16) == %#08llx\n", safestr_touint64(str, 16));
FAIL("safestr_touint64(\"0xDEADBEEF\", 16) FAILED");
}
safestr_copy(&str, SAFESTR_TEMP("0177"));
if (safestr_toint32(str, 8) != (int32_t)0177) {
printf("safestr_toint32(\"0177\", 8) == %#08x\n", safestr_toint32(str, 8));
FAIL("safestr_toint32(\"0177\", 8) FAILED");
}
if (safestr_toint64(str, 8) != (int64_t)0177) {
printf("safestr_toint64(\"0177\", 8) == %#08llx\n", safestr_toint64(str, 8));
FAIL("safestr_toint64(\"0177\", 8) FAILED");
}
if (safestr_touint32(str, 8) != (u_int32_t)0177) {
printf("safestr_touint32(\"0177\", 8) == %#08x\n", safestr_touint32(str, 8));
FAIL("safestr_touint32(\"0177\", 8) FAILED");
}
if (safestr_touint64(str, 8) != (u_int64_t)0177) {
printf("safestr_touint64(\"0177\", 8) == %#08llx\n", safestr_touint64(str, 8));
FAIL("safestr_touint64(\"0177\", 8) FAILED");
}
safestr_free(str);
}
typedef struct sprintf_int_t
{
char *fmt;
char *expect;
int value;
} sprintf_int_t;
static sprintf_int_t int_tests[] =
{
{ "%6d", " 42", 42 }, /* 7 */
{ "%6d", " -42", -42 }, /* 8 */
{ "%+6d", " +42", 42 }, /* 9 */
{ "%+6d", " -42", -42 }, /* 10 */
{ "%-6d", "42 ", 42 }, /* 11 */
{ "%-6d", "-42 ", -42 }, /* 12 */
{ "%-+6d", "+42 ", 42 }, /* 13 */
{ "%-+6d", "-42 ", -42 }, /* 14 */
{ "%12.6d", " 004217", 4217 }, /* 15 */
{ "%12.6d", " -004217", -4217 }, /* 16 */
{ "%+12.6d", " +004217", 4217 }, /* 17 */
{ "%+12.6d", " -004217", -4217 }, /* 18 */
{ "%-12.6d", "004217 ", 4217 }, /* 19 */
{ "%-12.6d", "-004217 ", -4217 }, /* 20 */
{ "%-+12.6d", "+004217 ", 4217 }, /* 21 */
{ "%-+12.6d", "-004217 ", -4217 }, /* 22 */
{ "%06d", "000042", 42 }, /* 23 */
{ "%06d", "-00042", -42 }, /* 24 */
{ "%0+6d", "+00042", 42 }, /* 25 */
{ "%0+6d", "-00042", -42 }, /* 26 */
{ "%012.6d", " 000042", 42 }, /* 27 */
{ "%012.6d", " -000042", -42 }, /* 28 */
{ "%0+12.6d", " +000042", 42 }, /* 29 */
{ "%0+12.6d", " -000042", -42 }, /* 30 */
{ "%o", "52", 42 }, /* 31 */
{ "%.o", "52", 42 }, /* 32 */
{ "%#.o", "052", 42 }, /* 33 */
{ "%x", "2a", 42 }, /* 34 */
{ "%X", "2A", 42 }, /* 35 */
{ "%.x", "2a", 42 }, /* 36 */
{ "%08x", "0000002a", 42 }, /* 37 */
{ "%#08x", "0x00002a", 42 }, /* 38 */
{ "%#8x", " 0x2a", 42 }, /* 39 */
{ "%#x", "0x2a", 42 }, /* 40 */
{ "%#.x", "0x2a", 42 }, /* 41 */
{ "%#.8x", "0x0000002a", 42 }, /* 42 */
{ "%c", "*", 42 }, /* 43 */
{ "%p", "0x00007a69", 31337 }, /* 44 */
{ NULL, NULL, 0 },
};
typedef struct sprintf_float_t
{
char *fmt;
char *expect;
double value;
} sprintf_float_t;
/* Good enough for now since we're just basically testing to make sure that
* the whole format string gets passed through to the underlying sprintf()
* function, which is really shitty since not all platforms have %a/%A
*/
static sprintf_float_t float_tests[] =
{
{ "%#e", "4.217000e+01", 42.17 }, /* 45 */
{ "%#f", "42.170000", 42.17 }, /* 46 */
{ "%#g", "42.1700", 42.17 }, /* 47 */
{ NULL, NULL, 0 },
};
#define SPRINTF_TEST(num) \
do { \
if (!safestr_equal(str, SAFESTR_TEMP(c_str), 0)) { \
printf("str: [%s] length = %u\nc_str: [%s] length = %zu\n", \
(char *)str, safestr_length(str), \
c_str, strlen(c_str)); \
FAIL("safestr_sprintf() test #" #num " FAILED"); \
} \
} while (0)
static void
test_sprintf(void)
{
int i;
char *c_str, msg[256];
safestr_t str;
sprintf_int_t *int_test;
sprintf_float_t *float_test;
str = safestr_alloc(0, 0);
/* String Tests */
c_str = "This is a simple test.";
safestr_sprintf(&str, SAFESTR_TEMP(c_str));
SPRINTF_TEST(1);
c_str = "Is the SafeStr library working?";
safestr_sprintf(&str, SAFESTR_TEMP("%s"), SAFESTR_TEMP(c_str));
SPRINTF_TEST(2);
c_str = "safestr ";
safestr_sprintf(&str, SAFESTR_TEMP("%-10s"), SAFESTR_TEMP("safestr"));
SPRINTF_TEST(3);
c_str = " safestr";
safestr_sprintf(&str, SAFESTR_TEMP("%10s"), SAFESTR_TEMP("safestr"));
SPRINTF_TEST(4);
c_str = "safe";
safestr_sprintf(&str, SAFESTR_TEMP("%.4s"), SAFESTR_TEMP("safestr"));
SPRINTF_TEST(5);
c_str = "";
safestr_sprintf(&str, SAFESTR_TEMP("%.s"), SAFESTR_TEMP("safestr"));
SPRINTF_TEST(6);
/* Integer Tests */
i = 7;
for (int_test = int_tests; int_test->fmt; int_test++, i++) {
safestr_sprintf(&str, SAFESTR_TEMP(int_test->fmt), int_test->value);
if (!safestr_equal(str, SAFESTR_TEMP(int_test->expect), 0)) {
printf("got: [%s] length = %u\nexpect: [%s] length = %zu\n",
(char *)str, safestr_length(str),
int_test->expect, strlen(int_test->expect));
sprintf(msg, "safestr_sprintf() test #%d FAILED", i);
FAIL(msg);
}
}
/* Floating Point Tests */
for (float_test = float_tests; float_test->fmt; float_test++, i++) {
safestr_sprintf(&str, SAFESTR_TEMP(float_test->fmt), float_test->value);
if (!safestr_equal(str, SAFESTR_TEMP(float_test->expect), 0)) {
printf("got: [%s] length = %u\nexpect: [%s] length = %zu\n",
(char *)str, safestr_length(str),
float_test->expect, strlen(float_test->expect));
sprintf(msg, "safestr_sprintf() test #%d FAILED", i);
FAIL(msg);
}
}
safestr_free(str);
}
static void
test_readline(void)
{
char c_str[256];
FILE *f;
safestr_t str;
/* First create a temporary file to read from with safestr_readline() */
f = fopen("safetest.txt", "w");
memset(c_str, 'x', 42); c_str[42] = '\0';
fprintf(f, "%s\n", c_str);
memset(c_str, 'x', 110); c_str[110] = '\0';
fprintf(f, "%s\n", c_str);
memset(c_str, 'x', 250); c_str[250] = '\0';
fprintf(f, "%s\n", c_str);
fclose(f);
/* Open the file we just created and read from it with safestr_readline() */
f = fopen("safetest.txt", "r");
memset(c_str, 'x', 42); c_str[42] = '\0';
str = safestr_readline(f);
if (!safestr_equal(str, SAFESTR_TEMP(c_str), 0)) {
fclose(f);
remove("safetest.txt");
printf("str: [%s]\nc_str: [%s]\n", (char *)str, c_str);
FAIL("safestr_readline() length of 42 failed!");
}
safestr_free(str);
memset(c_str, 'x', 110); c_str[110] = '\0';
str = safestr_readline(f);
if (!safestr_equal(str, SAFESTR_TEMP(c_str), 0)) {
fclose(f);
remove("safetest.txt");
printf("str: [%s]\nc_str: [%s]\n", (char *)str, c_str);
FAIL("safestr_readline() length of 110 failed!");
}
safestr_free(str);
memset(c_str, 'x', 250); c_str[250] = '\0';
str = safestr_readline(f);
if (!safestr_equal(str, SAFESTR_TEMP(c_str), 0)) {
fclose(f);
remove("safetest.txt");
printf("str: [%s]\nc_str: [%s]\n", (char *)str, c_str);
FAIL("safestr_readline() length of 250 failed!");
}
safestr_free(str);
/* cleanup */
fclose(f);
remove("safetest.txt");
}
int main(int argc, char *argv[])
{
char *tmp;
tmp = safestr_strdup(argv[0]);
if (strcmp(tmp, argv[0])) FAIL("safestr_strdup failed");
free(tmp);
test_alloc();
test_create();
test_comparison();
test_modify();
test_arrays();
test_misc();
test_sprintf();
test_readline();
#if 0
if (isatty(fileno(stdin))) {
safestr_t password;
password = safestr_getpassword(NULL, SAFESTR_TEMP("Enter a password: "));
printf("Got: [%s]\n", (char *)password);
safestr_free(password);
}
#endif
exit(0);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1