Mercurial > dovecot > core-2.2
view src/lib/printf-format-fix.c @ 22664:fea53c2725c0
director: Fix director_max_parallel_moves/kicks type
Should be uint, not time.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Thu, 09 Nov 2017 12:24:16 +0200 |
parents | 2e2563132d5f |
children | cb108f786fb4 |
line wrap: on
line source
/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */ #include "lib.h" #include "printf-format-fix.h" static const char * fix_format_real(const char *fmt, const char *p, size_t *len_r) { const char *errstr; char *buf; size_t len1, len2, len3; i_assert((size_t)(p - fmt) < INT_MAX); i_assert(p[0] == '%' && p[1] == 'm'); errstr = strerror(errno); /* we'll assume that there's only one %m in the format string. this simplifies the code and there's really no good reason to have it multiple times. Callers can trap this case themselves. */ len1 = p - fmt; len2 = strlen(errstr); len3 = strlen(p + 2); /* @UNSAFE */ buf = t_buffer_get(len1 + len2 + len3 + 1); memcpy(buf, fmt, len1); memcpy(buf + len1, errstr, len2); memcpy(buf + len1 + len2, p + 2, len3 + 1); *len_r = len1 + len2 + len3; return buf; } static const char * printf_format_fix_noalloc(const char *format, size_t *len_r) { static const char *printf_skip_chars = "# -+'I.*0123456789hlLjzt"; /* as a tiny optimization keep the most commonly used conversion modifiers first, so strchr() stops early. */ static const char *printf_allowed_conversions = "sudcioxXp%eEfFgGaA"; const char *ret, *p, *p2; p = ret = format; while ((p2 = strchr(p, '%')) != NULL) { p = p2+1; while (*p != '\0' && strchr(printf_skip_chars, *p) != NULL) p++; if (*p == '\0') { i_panic("%% modifier missing in '%s'", format); } else if (strchr(printf_allowed_conversions, *p) != NULL) { /* allow & ignore */ } else { switch (*p) { case 'n': i_panic("%%n modifier used"); case 'm': if (ret != format) i_panic("%%m used twice"); ret = fix_format_real(format, p-1, len_r); break; default: i_panic("Unsupported %%%c modifier", *p); } } p++; } if (ret == format) *len_r = p - format + strlen(p); return ret; } const char *printf_format_fix_get_len(const char *format, size_t *len_r) { const char *ret; ret = printf_format_fix_noalloc(format, len_r); if (ret != format) t_buffer_alloc(*len_r + 1); return ret; } const char *printf_format_fix(const char *format) { const char *ret; size_t len; ret = printf_format_fix_noalloc(format, &len); if (ret != format) t_buffer_alloc(len + 1); return ret; } const char *printf_format_fix_unsafe(const char *format) { size_t len; return printf_format_fix_noalloc(format, &len); }