annotate src/lib/printf-format-fix.c @ 23007:36e01285b5b8

lib: buffer - Improve header comment for buffer_insert() and buffer_delete().
author Stephan Bosch <stephan.bosch@dovecot.fi>
date Mon, 18 Mar 2019 00:52:37 +0100
parents dcec0ced2c50
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
22713
cb108f786fb4 Updated copyright notices to include the year 2018.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
1 /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
5679
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "printf-format-fix.h"
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5
5681
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
6 static const char *
21322
5ab8dc1a4a6f global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
7 fix_format_real(const char *fmt, const char *p, size_t *len_r)
5679
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 {
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9 const char *errstr;
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 char *buf;
21322
5ab8dc1a4a6f global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
11 size_t len1, len2, len3;
5681
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
12
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
13 i_assert((size_t)(p - fmt) < INT_MAX);
17528
06f90ecbfb70 lib: make printf_format_fix safer against shadowed %m behaviour
Phil Carmody <phil@dovecot.fi>
parents: 17130
diff changeset
14 i_assert(p[0] == '%' && p[1] == 'm');
5679
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16 errstr = strerror(errno);
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17
5681
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
18 /* we'll assume that there's only one %m in the format string.
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
19 this simplifies the code and there's really no good reason to have
17528
06f90ecbfb70 lib: make printf_format_fix safer against shadowed %m behaviour
Phil Carmody <phil@dovecot.fi>
parents: 17130
diff changeset
20 it multiple times. Callers can trap this case themselves. */
5681
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
21 len1 = p - fmt;
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
22 len2 = strlen(errstr);
5698
8be3bb396e3f Fix for %m handling
Timo Sirainen <tss@iki.fi>
parents: 5681
diff changeset
23 len3 = strlen(p + 2);
5679
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24
5681
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
25 /* @UNSAFE */
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
26 buf = t_buffer_get(len1 + len2 + len3 + 1);
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
27 memcpy(buf, fmt, len1);
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
28 memcpy(buf + len1, errstr, len2);
5698
8be3bb396e3f Fix for %m handling
Timo Sirainen <tss@iki.fi>
parents: 5681
diff changeset
29 memcpy(buf + len1 + len2, p + 2, len3 + 1);
5679
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30
5681
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
31 *len_r = len1 + len2 + len3;
5679
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 return buf;
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33 }
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34
22725
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
35 static bool verify_length(const char **p)
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
36 {
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
37 if (**p == '*') {
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
38 /* We don't bother supporting "*m$" - it's not used
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
39 anywhere and seems a bit dangerous. */
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
40 *p += 1;
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
41 } else if (**p >= '1' && **p <= '9') {
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
42 /* Limit to 4 digits - we'll never want more than that.
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
43 Some implementations might not handle long digits
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
44 correctly, or maybe even could be used for DoS due
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
45 to using too much CPU. */
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
46 unsigned int i = 0;
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
47 do {
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
48 *p += 1;
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
49 if (++i > 4)
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
50 return FALSE;
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
51 } while (**p >= '0' && **p <= '9');
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
52 }
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
53 return TRUE;
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
54 }
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
55
5681
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
56 static const char *
21322
5ab8dc1a4a6f global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
57 printf_format_fix_noalloc(const char *format, size_t *len_r)
5679
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58 {
22723
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
59 /* NOTE: This function is overly strict in what it accepts. Some
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
60 format strings that are valid (and safe) in C99 will cause a panic
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
61 here. This is because we don't really need to support the weirdest
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
62 special cases, and we're also being extra careful not to pass
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
63 anything to the underlying libc printf, which might treat the string
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
64 differently than us and unexpectedly handling it as %n. For example
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
65 "%**%n" with glibc. */
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
66
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
67 /* Allow only the standard C99 flags. There are also <'> and <I> flags,
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
68 but we don't really need them. And at worst if they're not supported
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
69 by the underlying printf, they could potentially be used to work
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
70 around our restrictions. */
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
71 const char printf_flags[] = "#0- +";
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
72 /* As a tiny optimization keep the most commonly used conversion
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
73 specifiers first, so strchr() stops early. */
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
74 static const char *printf_specifiers = "sudcixXpoeEfFgGaA";
21338
bc57c62167fc lib: Optimize printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21322
diff changeset
75 const char *ret, *p, *p2;
22723
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
76 char *flag;
5679
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
77
21338
bc57c62167fc lib: Optimize printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21322
diff changeset
78 p = ret = format;
bc57c62167fc lib: Optimize printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21322
diff changeset
79 while ((p2 = strchr(p, '%')) != NULL) {
22723
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
80 const unsigned int start_pos = p2 - format;
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
81
21338
bc57c62167fc lib: Optimize printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21322
diff changeset
82 p = p2+1;
22723
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
83 if (*p == '%') {
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
84 /* we'll be strict and allow %% only when there are no
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
85 optinal flags or modifiers. */
21339
8d49b6ed7bab lib: Fix %n detection in printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21338
diff changeset
86 p++;
22723
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
87 continue;
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
88 }
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
89 /* 1) zero or more flags. We'll add a further restriction that
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
90 each flag can be used only once, since there's no need to
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
91 use them more than once, and some implementations might
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
92 add their own limits. */
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
93 bool printf_flags_seen[N_ELEMENTS(printf_flags)] = { FALSE, };
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
94 while (*p != '\0' &&
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
95 (flag = strchr(printf_flags, *p)) != NULL) {
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
96 unsigned int flag_idx = flag - printf_flags;
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
97
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
98 if (printf_flags_seen[flag_idx]) {
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
99 i_panic("Duplicate %% flag '%c' starting at #%u in '%s'",
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
100 *p, start_pos, format);
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
101 }
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
102 printf_flags_seen[flag_idx] = TRUE;
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
103 p++;
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
104 }
21340
4efaa627264d lib: Allow only known %chars in printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21339
diff changeset
105
22723
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
106 /* 2) Optional minimum field width */
22725
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
107 if (!verify_length(&p)) {
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
108 i_panic("Too large minimum field width starting at #%u in '%s'",
878a4f623242 lib: printf_format_fix*() - Move minimum field width check to its own function
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22724
diff changeset
109 start_pos, format);
22723
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
110 }
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
111
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
112 /* 3) Optional precision */
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
113 if (*p == '.') {
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
114 p++;
22726
dcec0ced2c50 lib: printf_format_fix*() - Support '*' in precision
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22725
diff changeset
115 if (!verify_length(&p)) {
dcec0ced2c50 lib: printf_format_fix*() - Support '*' in precision
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22725
diff changeset
116 i_panic("Too large precision starting at #%u in '%s'",
dcec0ced2c50 lib: printf_format_fix*() - Support '*' in precision
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22725
diff changeset
117 start_pos, format);
22723
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
118 }
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
119 }
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
120
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
121 /* 4) Optional length modifier */
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
122 switch (*p) {
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
123 case 'h':
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
124 if (*++p == 'h')
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
125 p++;
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
126 break;
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
127 case 'l':
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
128 if (*++p == 'l')
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
129 p++;
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
130 break;
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
131 case 'L':
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
132 case 'j':
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
133 case 'z':
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
134 case 't':
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
135 p++;
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
136 break;
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
137 }
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
138
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
139 /* 5) conversion specifier */
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
140 if (*p == '\0' || strchr(printf_specifiers, *p) == NULL) {
21340
4efaa627264d lib: Allow only known %chars in printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21339
diff changeset
141 switch (*p) {
4efaa627264d lib: Allow only known %chars in printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21339
diff changeset
142 case 'n':
4efaa627264d lib: Allow only known %chars in printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21339
diff changeset
143 i_panic("%%n modifier used");
4efaa627264d lib: Allow only known %chars in printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21339
diff changeset
144 case 'm':
4efaa627264d lib: Allow only known %chars in printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21339
diff changeset
145 if (ret != format)
4efaa627264d lib: Allow only known %chars in printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21339
diff changeset
146 i_panic("%%m used twice");
4efaa627264d lib: Allow only known %chars in printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21339
diff changeset
147 ret = fix_format_real(format, p-1, len_r);
4efaa627264d lib: Allow only known %chars in printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21339
diff changeset
148 break;
22723
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
149 case '\0':
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
150 i_panic("Missing %% specifier starting at #%u in '%s'",
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
151 start_pos, format);
21340
4efaa627264d lib: Allow only known %chars in printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21339
diff changeset
152 default:
22723
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
153 i_panic("Unsupported 0x%02x specifier starting at #%u in '%s'",
781ee592b295 lib: printf_format_fix*() - Be over-strict in what format strings are allowed
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22713
diff changeset
154 *p, start_pos, format);
21340
4efaa627264d lib: Allow only known %chars in printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21339
diff changeset
155 }
5679
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
156 }
21338
bc57c62167fc lib: Optimize printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21322
diff changeset
157 p++;
5679
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
158 }
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
159
17528
06f90ecbfb70 lib: make printf_format_fix safer against shadowed %m behaviour
Phil Carmody <phil@dovecot.fi>
parents: 17130
diff changeset
160 if (ret == format)
21338
bc57c62167fc lib: Optimize printf_format_fix_noalloc()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21322
diff changeset
161 *len_r = p - format + strlen(p);
17528
06f90ecbfb70 lib: make printf_format_fix safer against shadowed %m behaviour
Phil Carmody <phil@dovecot.fi>
parents: 17130
diff changeset
162 return ret;
5681
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
163 }
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
164
21322
5ab8dc1a4a6f global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
165 const char *printf_format_fix_get_len(const char *format, size_t *len_r)
5681
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
166 {
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
167 const char *ret;
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
168
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
169 ret = printf_format_fix_noalloc(format, len_r);
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
170 if (ret != format)
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
171 t_buffer_alloc(*len_r + 1);
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
172 return ret;
5679
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
173 }
74e06273985b Renamed printf_string_fix_format() to printf_format_fix() and moved it to
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
174
5681
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
175 const char *printf_format_fix(const char *format)
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
176 {
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
177 const char *ret;
21322
5ab8dc1a4a6f global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
178 size_t len;
5681
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
179
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
180 ret = printf_format_fix_noalloc(format, &len);
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
181 if (ret != format)
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
182 t_buffer_alloc(len + 1);
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
183 return ret;
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
184 }
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
185
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
186 const char *printf_format_fix_unsafe(const char *format)
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
187 {
21322
5ab8dc1a4a6f global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
188 size_t len;
5681
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
189
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
190 return printf_format_fix_noalloc(format, &len);
09415e6a0892 Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents: 5679
diff changeset
191 }