test-printf-format-fix.c revision 85174bd658f999cb3aa145885fd85674f8595fbb
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2001-2017 Dovecot authors, see the included COPYING file */
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen/* Unit tests for printf-format-fix helper */
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen#include "test-lib.h"
5e6042124b6429d60b352eaf951ee67e0a311a8cTimo Sirainen#include "printf-format-fix.h"
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen#include <string.h>
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainenstruct format_fix_rewrites {
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen const char *input;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen const char *output;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen size_t length;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen};
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainenstatic void test_unchanged()
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen{
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen static const char *tests[] = {
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "Hello world",
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen "Embedded %%, %u, %f, %s, etc. are OK",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "Allow %#0- +s flags",
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen "duplicate flags in different args %0-123s %0-123s",
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen "Minimum length %9999s",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "Minimum length parameter %*s",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "Precision %.9999s",
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen "Precision %1.9999s",
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen "Precision parameter %1.*s %.*s",
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen "Length modifiers %hd %hhd %ld %lld %Lg %jd %zd %td",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "Specifiers %s %u %d %c %i %x %X %p %o %e %E %f %F %g %G %a %A",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "%%doesn't cause confusion in %%m and %%n",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen };
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen unsigned int i;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_begin("printf_format_fix(safe)");
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen for (i = 0; i < N_ELEMENTS(tests); ++i) {
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen size_t len;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen T_BEGIN {
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_assert_idx(printf_format_fix(tests[i])
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen == tests[i], i);
39224d71e56c50ccfbc0405eb1914281590064d6Timo Sirainen test_assert_idx(printf_format_fix_get_len(tests[i], &len)
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen == tests[i], i);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_assert_idx(len == strlen(tests[i]), i);
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen } T_END;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen }
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_end();
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen}
592270d9a3d666a1b687c146f6e1edf2aacd46e8Timo Sirainen
39224d71e56c50ccfbc0405eb1914281590064d6Timo Sirainenstatic void test_ok_changes()
39224d71e56c50ccfbc0405eb1914281590064d6Timo Sirainen{
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen static const char *tests[] = {
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "OK to have a trailing %m",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "%m can appear at the start too",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "Even %m in the middle with a confusing %%m elsewhere is OK",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen };
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen unsigned int i;
592270d9a3d666a1b687c146f6e1edf2aacd46e8Timo Sirainen const char *needle;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen unsigned int needlen;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen int old_errno = errno;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
592270d9a3d666a1b687c146f6e1edf2aacd46e8Timo Sirainen test_begin("printf_format_fix(rewrites)");
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
39224d71e56c50ccfbc0405eb1914281590064d6Timo Sirainen errno = EINVAL;
39224d71e56c50ccfbc0405eb1914281590064d6Timo Sirainen needle = strerror(errno);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen i_assert(needle != NULL);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen needlen = strlen(needle);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen for (i = 0; i < N_ELEMENTS(tests); ++i) {
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen size_t len;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen char const *chgd;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen char const *insert;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen unsigned int offs;
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen T_BEGIN {
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen chgd = printf_format_fix(tests[i]);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_assert_idx(chgd != tests[i], i);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen insert = strstr(chgd, needle);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_assert_idx(insert != NULL, i);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen offs = insert - chgd;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_assert_idx(memcmp(chgd, tests[i], offs) == 0, i);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_assert_idx(memcmp(chgd+offs, needle, needlen) == 0, i);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_assert_idx(strcmp(chgd+offs+needlen, tests[i]+offs+2) == 0, i);
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen chgd = printf_format_fix_get_len(tests[i], &len);
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen test_assert_idx(chgd != tests[i], i);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_assert_idx(len == strlen(chgd), i);
5e114f59ad9b9632bf7f3403d56bea17bd494e8eTimo Sirainen insert = strstr(chgd, needle);
5e114f59ad9b9632bf7f3403d56bea17bd494e8eTimo Sirainen test_assert_idx(insert != NULL, i);
5e114f59ad9b9632bf7f3403d56bea17bd494e8eTimo Sirainen offs = insert - chgd;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_assert_idx(memcmp(chgd, tests[i], offs) == 0, i);
5e114f59ad9b9632bf7f3403d56bea17bd494e8eTimo Sirainen test_assert_idx(memcmp(chgd+offs, needle, needlen) == 0, i);
5e114f59ad9b9632bf7f3403d56bea17bd494e8eTimo Sirainen test_assert_idx(memcmp(chgd+offs+needlen, tests[i]+offs+2, len-needlen-offs) == 0, i);
5e114f59ad9b9632bf7f3403d56bea17bd494e8eTimo Sirainen } T_END;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen }
5e114f59ad9b9632bf7f3403d56bea17bd494e8eTimo Sirainen
5e114f59ad9b9632bf7f3403d56bea17bd494e8eTimo Sirainen errno = old_errno;
5e114f59ad9b9632bf7f3403d56bea17bd494e8eTimo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_end();
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen}
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainenvoid test_printf_format_fix()
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen{
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_unchanged();
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_ok_changes();
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen}
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen/* Want to test the panics too? go for it! */
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainenenum fatal_test_state fatal_printf_format_fix(unsigned int stage)
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen{
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen static const char *fatals[] = {
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen "no no no %n's",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "no no no %-1234567890123n's with extra stuff",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "%m allowed once, but not twice: %m",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "%m must not obscure a later %n",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "definitely can't have a tailing %",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "Evil %**%n",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "Evil %*#%99999$s",
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen "No weird %% with %0%",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "No duplicate modifiers %00s",
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen "Minimum length can't be too long %10000s",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "Minimum length doesn't support %*1$s",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "Precision can't be too long %.10000s",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen "Precision can't be too long %1.10000s",
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen "Precision doesn't support %1.-1s",
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen };
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen if(stage >= N_ELEMENTS(fatals)) {
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_end();
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen return FATAL_TEST_FINISHED;
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen }
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen if(stage == 0)
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen test_begin("fatal_printf_format_fix");
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen /* let's crash! */
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen (void)printf_format_fix(fatals[stage]);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen return FATAL_TEST_FAILURE;
5e6042124b6429d60b352eaf951ee67e0a311a8cTimo Sirainen}
5e6042124b6429d60b352eaf951ee67e0a311a8cTimo Sirainen