direct-io.hg

view patches/linux-2.6.16.33/vsnprintf.patch @ 12988:e080700efa56

[TOOLS] Fix the build. Clearly demarcate PPC-specific stuff.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Dec 13 10:23:53 2006 +0000 (2006-12-13)
parents 6c2c7ff6265a
children 98dadb3df5ca
line source
1 commit f796937a062c7aeb44cd0e75e1586c8543634a7d
2 Author: Jeremy Fitzhardinge <jeremy@xensource.com>
3 Date: Sun Jun 25 05:49:17 2006 -0700
5 [PATCH] Fix bounds check in vsnprintf, to allow for a 0 size and NULL buffer
7 This change allows callers to use a 0-byte buffer and a NULL buffer pointer
8 with vsnprintf, so it can be used to determine how large the resulting
9 formatted string will be.
11 Previously the code effectively treated a size of 0 as a size of 4G (on
12 32-bit systems), with other checks preventing it from actually trying to
13 emit the string - but the terminal \0 would still be written, which would
14 crash if the buffer is NULL.
16 This change changes the boundary check so that 'end' points to the putative
17 location of the terminal '\0', which is only written if size > 0.
19 vsnprintf still allows the buffer size to be set very large, to allow
20 unbounded buffer sizes (to implement sprintf, etc).
22 [akpm@osdl.org: fix long-vs-longlong confusion]
23 Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
24 Signed-off-by: Chris Wright <chrisw@sous-sol.org>
25 Signed-off-by: Andrew Morton <akpm@osdl.org>
26 Signed-off-by: Linus Torvalds <torvalds@osdl.org>
28 diff --git a/lib/vsprintf.c b/lib/vsprintf.c
29 index b07db5c..f595947 100644
30 --- a/lib/vsprintf.c
31 +++ b/lib/vsprintf.c
32 @@ -187,49 +187,49 @@ static char * number(char * buf, char *
33 size -= precision;
34 if (!(type&(ZEROPAD+LEFT))) {
35 while(size-->0) {
36 - if (buf <= end)
37 + if (buf < end)
38 *buf = ' ';
39 ++buf;
40 }
41 }
42 if (sign) {
43 - if (buf <= end)
44 + if (buf < end)
45 *buf = sign;
46 ++buf;
47 }
48 if (type & SPECIAL) {
49 if (base==8) {
50 - if (buf <= end)
51 + if (buf < end)
52 *buf = '0';
53 ++buf;
54 } else if (base==16) {
55 - if (buf <= end)
56 + if (buf < end)
57 *buf = '0';
58 ++buf;
59 - if (buf <= end)
60 + if (buf < end)
61 *buf = digits[33];
62 ++buf;
63 }
64 }
65 if (!(type & LEFT)) {
66 while (size-- > 0) {
67 - if (buf <= end)
68 + if (buf < end)
69 *buf = c;
70 ++buf;
71 }
72 }
73 while (i < precision--) {
74 - if (buf <= end)
75 + if (buf < end)
76 *buf = '0';
77 ++buf;
78 }
79 while (i-- > 0) {
80 - if (buf <= end)
81 + if (buf < end)
82 *buf = tmp[i];
83 ++buf;
84 }
85 while (size-- > 0) {
86 - if (buf <= end)
87 + if (buf < end)
88 *buf = ' ';
89 ++buf;
90 }
91 @@ -272,7 +272,8 @@ int vsnprintf(char *buf, size_t size, co
92 /* 'z' changed to 'Z' --davidm 1/25/99 */
93 /* 't' added for ptrdiff_t */
95 - /* Reject out-of-range values early */
96 + /* Reject out-of-range values early. Large positive sizes are
97 + used for unknown buffer sizes. */
98 if (unlikely((int) size < 0)) {
99 /* There can be only one.. */
100 static int warn = 1;
101 @@ -282,16 +283,17 @@ int vsnprintf(char *buf, size_t size, co
102 }
104 str = buf;
105 - end = buf + size - 1;
106 + end = buf + size;
108 - if (end < buf - 1) {
109 - end = ((void *) -1);
110 - size = end - buf + 1;
111 + /* Make sure end is always >= buf */
112 + if (end < buf) {
113 + end = ((void *)-1);
114 + size = end - buf;
115 }
117 for (; *fmt ; ++fmt) {
118 if (*fmt != '%') {
119 - if (str <= end)
120 + if (str < end)
121 *str = *fmt;
122 ++str;
123 continue;
124 @@ -357,17 +359,17 @@ int vsnprintf(char *buf, size_t size, co
125 case 'c':
126 if (!(flags & LEFT)) {
127 while (--field_width > 0) {
128 - if (str <= end)
129 + if (str < end)
130 *str = ' ';
131 ++str;
132 }
133 }
134 c = (unsigned char) va_arg(args, int);
135 - if (str <= end)
136 + if (str < end)
137 *str = c;
138 ++str;
139 while (--field_width > 0) {
140 - if (str <= end)
141 + if (str < end)
142 *str = ' ';
143 ++str;
144 }
145 @@ -382,18 +384,18 @@ int vsnprintf(char *buf, size_t size, co
147 if (!(flags & LEFT)) {
148 while (len < field_width--) {
149 - if (str <= end)
150 + if (str < end)
151 *str = ' ';
152 ++str;
153 }
154 }
155 for (i = 0; i < len; ++i) {
156 - if (str <= end)
157 + if (str < end)
158 *str = *s;
159 ++str; ++s;
160 }
161 while (len < field_width--) {
162 - if (str <= end)
163 + if (str < end)
164 *str = ' ';
165 ++str;
166 }
167 @@ -426,7 +428,7 @@ int vsnprintf(char *buf, size_t size, co
168 continue;
170 case '%':
171 - if (str <= end)
172 + if (str < end)
173 *str = '%';
174 ++str;
175 continue;
176 @@ -449,11 +451,11 @@ int vsnprintf(char *buf, size_t size, co
177 break;
179 default:
180 - if (str <= end)
181 + if (str < end)
182 *str = '%';
183 ++str;
184 if (*fmt) {
185 - if (str <= end)
186 + if (str < end)
187 *str = *fmt;
188 ++str;
189 } else {
190 @@ -483,14 +485,13 @@ int vsnprintf(char *buf, size_t size, co
191 str = number(str, end, num, base,
192 field_width, precision, flags);
193 }
194 - if (str <= end)
195 - *str = '\0';
196 - else if (size > 0)
197 - /* don't write out a null byte if the buf size is zero */
198 - *end = '\0';
199 - /* the trailing null byte doesn't count towards the total
200 - * ++str;
201 - */
202 + if (size > 0) {
203 + if (str < end)
204 + *str = '\0';
205 + else
206 + *end = '\0';
207 + }
208 + /* the trailing null byte doesn't count towards the total */
209 return str-buf;
210 }