printf-format-fix.c revision ebe00087d3c7f9706d4acb9017eaad912404516c
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2002-2016 Dovecot authors, see the included COPYING file */
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainenstatic const char *
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainenfix_format_real(const char *fmt, const char *p, size_t *len_r)
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen /* we'll assume that there's only one %m in the format string.
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen this simplifies the code and there's really no good reason to have
3785910c303507db5f629684e6dde2cc7f83668eTimo Sirainen it multiple times. Callers can trap this case themselves. */
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen /* @UNSAFE */
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainenstatic const char *
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainenprintf_format_fix_noalloc(const char *format, size_t *len_r)
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen static const char *printf_skip_chars = "# -+'I.*0123456789hlLjzt";
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen /* as a tiny optimization keep the most commonly used conversion
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen modifiers first, so strchr() stops early. */
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen static const char *printf_allowed_conversions = "sudcioxXp%eEfFgGaA";
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen while (*p != '\0' && strchr(printf_skip_chars, *p) != NULL)
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen if (*p == '\0') {
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen i_panic("%% modifier missing in '%s'", format);
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen } else if (strchr(printf_allowed_conversions, *p) != NULL) {
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen /* allow & ignore */
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen switch (*p) {
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainenconst char *printf_format_fix_get_len(const char *format, size_t *len_r)
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *ret;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen ret = printf_format_fix_noalloc(format, len_r);
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainenconst char *printf_format_fix(const char *format)
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const char *ret;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen ret = printf_format_fix_noalloc(format, &len);
d4fe93a9c242d745e0cf2e6cc58d5caf265de2a0Timo Sirainenconst char *printf_format_fix_unsafe(const char *format)