test-printf-format-fix.c revision 8bec19723b39071a1794e76dec35d151473cae5f
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2001-2014 Dovecot authors, see the included COPYING file */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen/* Unit tests for printf-format-fix helper */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "test-lib.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "printf-format-fix.h"
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include <string.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct format_fix_rewrites {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const char *input;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const char *output;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen size_t length;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen};
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void test_unchanged()
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen static const char *tests[] = {
a34bd633ab201f6a5ad1c00174fb8b0359031d00Timo Sirainen "Hello world",
a34bd633ab201f6a5ad1c00174fb8b0359031d00Timo Sirainen "Embedded %%, %u, %f, etc. are OK",
a34bd633ab201f6a5ad1c00174fb8b0359031d00Timo Sirainen "%%doesn't cause confusion in %%m and %%n",
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen };
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int i;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_begin("printf_format_fix(safe)");
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen for (i = 0; i < N_ELEMENTS(tests); ++i) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int len;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen T_BEGIN {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert_idx(printf_format_fix(tests[i])
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen == tests[i], i);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert_idx(printf_format_fix_get_len(tests[i], &len)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen == tests[i], i);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert_idx(len == strlen(tests[i]), i);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen } T_END;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_end();
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void test_ok_changes()
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen static const char *tests[] = {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen "OK to have a trailing %m",
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen "%m can appear at the start too",
d22301419109ed4a38351715e6760011421dadecTimo Sirainen "Even %m in the middle with a confusing %%m elsewhere is OK",
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen };
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int i;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const char *needle;
4542c94adb8910e0174c784754e737cec16af59cTimo Sirainen unsigned int needlen;
4542c94adb8910e0174c784754e737cec16af59cTimo Sirainen int old_errno = errno;
4542c94adb8910e0174c784754e737cec16af59cTimo Sirainen
4542c94adb8910e0174c784754e737cec16af59cTimo Sirainen test_begin("printf_format_fix(rewrites)");
4542c94adb8910e0174c784754e737cec16af59cTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen errno = EINVAL;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen needle = strerror(errno);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert(needle != NULL);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen needlen = strlen(needle);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen for (i = 0; i < N_ELEMENTS(tests); ++i) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int len;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen char const *chgd;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen char const *insert;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int offs;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen T_BEGIN {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen chgd = printf_format_fix(tests[i]);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert_idx(chgd != tests[i], i);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen insert = strstr(chgd, needle);
4542c94adb8910e0174c784754e737cec16af59cTimo Sirainen test_assert_idx(insert != NULL, i);
4542c94adb8910e0174c784754e737cec16af59cTimo Sirainen offs = insert - chgd;
4542c94adb8910e0174c784754e737cec16af59cTimo Sirainen test_assert_idx(memcmp(chgd, tests[i], offs) == 0, i);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert_idx(memcmp(chgd+offs, needle, needlen) == 0, i);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert_idx(strcmp(chgd+offs+needlen, tests[i]+offs+2) == 0, i);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen chgd = printf_format_fix_get_len(tests[i], &len);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert_idx(chgd != tests[i], i);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert_idx(len == strlen(chgd), i);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen insert = strstr(chgd, needle);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert_idx(insert != NULL, i);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen offs = insert - chgd;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert_idx(memcmp(chgd, tests[i], offs) == 0, i);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert_idx(memcmp(chgd+offs, needle, needlen) == 0, i);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_assert_idx(memcmp(chgd+offs+needlen, tests[i]+offs+2, len-needlen-offs) == 0, i);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen } T_END;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen errno = old_errno;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_end();
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen}
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainenvoid test_printf_format_fix()
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen{
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen test_unchanged();
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen test_ok_changes();
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen}
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen/* Want to test the panics too? go for it! */
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainenenum fatal_test_state fatal_printf_format_fix(int stage)
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen{
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen static const char *fatals[] = {
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen "no no no %n's",
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen "%m allowed once, but not twice: %m",
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen "%m must not obscure a later %n",
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen "definitely can't have a tailing %",
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen };
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen if((unsigned int)stage >= N_ELEMENTS(fatals)) {
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen test_end();
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen return FATAL_TEST_FINISHED;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if(stage == 0)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen test_begin("fatal_printf_format_fix");
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* let's crash! */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen (void)printf_format_fix(fatals[stage]);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return FATAL_TEST_FAILURE;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen