]>
Commit | Line | Data |
---|---|---|
24acfa14 MT |
1 | BASH PATCH REPORT |
2 | ================= | |
3 | ||
4 | Bash-Release: 3.2 | |
5 | Patch-ID: bash32-005 | |
6 | ||
7 | Bug-Reported-by: Stuart Shelton <stuart@openobjects.com> | |
8 | Bug-Reference-ID: <453F7CC8.6030907@openobjects.com> | |
9 | Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2006-10/msg00127.html | |
10 | ||
11 | Bug-Description: | |
12 | ||
13 | A missing extern declaration for `asprintf' caused `double' arguments to be | |
14 | passed as `0', leading to incorrect results. Additionally, a bug in the | |
15 | replacement asprintf/snprintf function caused an infinite loop when passed | |
16 | 0 arguments to the floating point conversions under some circumstances. | |
17 | ||
18 | Patch: | |
19 | ||
20 | *** ../bash-3.2/builtins/printf.def Mon Sep 18 08:48:42 2006 | |
21 | --- builtins/printf.def Tue Oct 31 08:19:44 2006 | |
22 | *************** | |
23 | *** 49,54 **** | |
24 | --- 49,60 ---- | |
25 | # define INT_MIN (-2147483647-1) | |
26 | #endif | |
27 | ||
28 | + #if defined (PREFER_STDARG) | |
29 | + # include <stdarg.h> | |
30 | + #else | |
31 | + # include <varargs.h> | |
32 | + #endif | |
33 | + | |
34 | #include <stdio.h> | |
35 | #include <chartypes.h> | |
36 | ||
37 | *************** | |
38 | *** 151,156 **** | |
39 | --- 157,166 ---- | |
40 | #define SKIP1 "#'-+ 0" | |
41 | #define LENMODS "hjlLtz" | |
42 | ||
43 | + #ifndef HAVE_ASPRINTF | |
44 | + extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); | |
45 | + #endif | |
46 | + | |
47 | static void printf_erange __P((char *)); | |
48 | static int printstr __P((char *, char *, int, int, int)); | |
49 | static int tescape __P((char *, char *, int *)); | |
50 | ||
51 | ||
52 | *** ../bash-3.2/lib/sh/snprintf.c Thu Apr 6 09:48:40 2006 | |
53 | --- lib/sh/snprintf.c Sat Oct 28 00:00:13 2006 | |
54 | *************** | |
55 | *** 471,476 **** | |
56 | --- 476,483 ---- | |
57 | 10^x ~= r | |
58 | * log_10(200) = 2; | |
59 | * log_10(250) = 2; | |
60 | + * | |
61 | + * NOTE: do not call this with r == 0 -- an infinite loop results. | |
62 | */ | |
63 | static int | |
64 | log_10(r) | |
65 | *************** | |
66 | *** 576,583 **** | |
67 | { | |
68 | integral_part[0] = '0'; | |
69 | integral_part[1] = '\0'; | |
70 | ! fraction_part[0] = '0'; | |
71 | ! fraction_part[1] = '\0'; | |
72 | if (fract) | |
73 | *fract = fraction_part; | |
74 | return integral_part; | |
75 | --- 583,593 ---- | |
76 | { | |
77 | integral_part[0] = '0'; | |
78 | integral_part[1] = '\0'; | |
79 | ! /* The fractional part has to take the precision into account */ | |
80 | ! for (ch = 0; ch < precision-1; ch++) | |
81 | ! fraction_part[ch] = '0'; | |
82 | ! fraction_part[ch] = '0'; | |
83 | ! fraction_part[ch+1] = '\0'; | |
84 | if (fract) | |
85 | *fract = fraction_part; | |
86 | return integral_part; | |
87 | *************** | |
88 | *** 805,810 **** | |
89 | --- 815,821 ---- | |
90 | PUT_CHAR(*tmp, p); | |
91 | tmp++; | |
92 | } | |
93 | + | |
94 | PAD_LEFT(p); | |
95 | } | |
96 | ||
97 | *************** | |
98 | *** 972,982 **** | |
99 | if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp))) | |
100 | tmp = t; | |
101 | ||
102 | /* calculate the padding. 1 for the dot */ | |
103 | p->width = p->width - | |
104 | ((d > 0. && p->justify == RIGHT) ? 1:0) - | |
105 | ((p->flags & PF_SPACE) ? 1:0) - | |
106 | ! strlen(tmp) - p->precision - 1; | |
107 | PAD_RIGHT(p); | |
108 | PUT_PLUS(d, p, 0.); | |
109 | PUT_SPACE(d, p, 0.); | |
110 | --- 983,1003 ---- | |
111 | if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp))) | |
112 | tmp = t; | |
113 | ||
114 | + if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0) | |
115 | + { | |
116 | + /* smash the trailing zeros unless altform */ | |
117 | + for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--) | |
118 | + tmp2[i] = '\0'; | |
119 | + if (tmp2[0] == '\0') | |
120 | + p->precision = 0; | |
121 | + } | |
122 | + | |
123 | /* calculate the padding. 1 for the dot */ | |
124 | p->width = p->width - | |
125 | ((d > 0. && p->justify == RIGHT) ? 1:0) - | |
126 | ((p->flags & PF_SPACE) ? 1:0) - | |
127 | ! strlen(tmp) - p->precision - | |
128 | ! ((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0); /* radix char */ | |
129 | PAD_RIGHT(p); | |
130 | PUT_PLUS(d, p, 0.); | |
131 | PUT_SPACE(d, p, 0.); | |
132 | *************** | |
133 | *** 991,1001 **** | |
134 | if (p->precision != 0 || (p->flags & PF_ALTFORM)) | |
135 | PUT_CHAR(decpoint, p); /* put the '.' */ | |
136 | ||
137 | - if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0) | |
138 | - /* smash the trailing zeros unless altform */ | |
139 | - for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--) | |
140 | - tmp2[i] = '\0'; | |
141 | - | |
142 | for (; *tmp2; tmp2++) | |
143 | PUT_CHAR(*tmp2, p); /* the fraction */ | |
144 | ||
145 | --- 1012,1017 ---- | |
146 | *************** | |
147 | *** 1011,1024 **** | |
148 | char *tmp, *tmp2; | |
149 | int j, i; | |
150 | ||
151 | ! if (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)) | |
152 | return; /* already printed nan or inf */ | |
153 | ||
154 | GETLOCALEDATA(decpoint, thoussep, grouping); | |
155 | DEF_PREC(p); | |
156 | ! j = log_10(d); | |
157 | ! d = d / pow_10(j); /* get the Mantissa */ | |
158 | ! d = ROUND(d, p); | |
159 | tmp = dtoa(d, p->precision, &tmp2); | |
160 | ||
161 | /* 1 for unit, 1 for the '.', 1 for 'e|E', | |
162 | --- 1027,1045 ---- | |
163 | char *tmp, *tmp2; | |
164 | int j, i; | |
165 | ||
166 | ! if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2))) | |
167 | return; /* already printed nan or inf */ | |
168 | ||
169 | GETLOCALEDATA(decpoint, thoussep, grouping); | |
170 | DEF_PREC(p); | |
171 | ! if (d == 0.) | |
172 | ! j = 0; | |
173 | ! else | |
174 | ! { | |
175 | ! j = log_10(d); | |
176 | ! d = d / pow_10(j); /* get the Mantissa */ | |
177 | ! d = ROUND(d, p); | |
178 | ! } | |
179 | tmp = dtoa(d, p->precision, &tmp2); | |
180 | ||
181 | /* 1 for unit, 1 for the '.', 1 for 'e|E', | |
182 | *************** | |
183 | *** 1076,1081 **** | |
184 | --- 1097,1103 ---- | |
185 | PUT_CHAR(*tmp, p); | |
186 | tmp++; | |
187 | } | |
188 | + | |
189 | PAD_LEFT(p); | |
190 | } | |
191 | #endif | |
192 | *************** | |
193 | *** 1358,1364 **** | |
194 | STAR_ARGS(data); | |
195 | DEF_PREC(data); | |
196 | d = GETDOUBLE(data); | |
197 | ! i = log_10(d); | |
198 | /* | |
199 | * for '%g|%G' ANSI: use f if exponent | |
200 | * is in the range or [-4,p] exclusively | |
201 | --- 1380,1386 ---- | |
202 | STAR_ARGS(data); | |
203 | DEF_PREC(data); | |
204 | d = GETDOUBLE(data); | |
205 | ! i = (d != 0.) ? log_10(d) : -1; | |
206 | /* | |
207 | * for '%g|%G' ANSI: use f if exponent | |
208 | * is in the range or [-4,p] exclusively | |
209 | *** ../bash-3.2/patchlevel.h Thu Apr 13 08:31:04 2006 | |
210 | --- patchlevel.h Mon Oct 16 14:22:54 2006 | |
211 | *************** | |
212 | *** 26,30 **** | |
213 | looks for to find the patch level (for the sccs version string). */ | |
214 | ||
215 | ! #define PATCHLEVEL 4 | |
216 | ||
217 | #endif /* _PATCHLEVEL_H_ */ | |
218 | --- 26,30 ---- | |
219 | looks for to find the patch level (for the sccs version string). */ | |
220 | ||
221 | ! #define PATCHLEVEL 5 | |
222 | ||
223 | #endif /* _PATCHLEVEL_H_ */ |