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