|
|
BASH PATCH REPORT =================
Bash-Release: 3.2 Patch-ID: bash32-005
Bug-Reported-by: Stuart Shelton <stuart@openobjects.com> Bug-Reference-ID: <453F7CC8.6030907@openobjects.com> Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2006-10/msg00127.html
Bug-Description:
A missing extern declaration for `asprintf' caused `double' arguments to be passed as `0', leading to incorrect results. Additionally, a bug in the replacement asprintf/snprintf function caused an infinite loop when passed 0 arguments to the floating point conversions under some circumstances.
Patch:
*** bash-3.2/builtins/printf.def Mon Sep 18 08:48:42 2006 --- builtins/printf.def Tue Oct 31 08:19:44 2006
*************** *** 49,54 **** --- 49,60 ----
# define INT_MIN (-2147483647-1) #endif + #if defined (PREFER_STDARG)
+ # include <stdarg.h>
+ #else
+ # include <varargs.h>
+ #endif
+
#include <stdio.h> #include <chartypes.h> *************** *** 151,156 **** --- 157,166 ----
#define SKIP1 "#'-+ 0" #define LENMODS "hjlLtz" + #ifndef HAVE_ASPRINTF
+ extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
+ #endif
+
static void printf_erange __P((char *)); static int printstr __P((char *, char *, int, int, int)); static int tescape __P((char *, char *, int *));
*** bash-3.2/lib/sh/snprintf.c Thu Apr 6 09:48:40 2006 --- lib/sh/snprintf.c Sat Oct 28 00:00:13 2006
*************** *** 471,476 **** --- 476,483 ----
10^x ~= r * log_10(200) = 2; * log_10(250) = 2; + *
+ * NOTE: do not call this with r == 0 -- an infinite loop results.
*/ static int log_10(r) *************** *** 576,583 **** { integral_part[0] = '0'; integral_part[1] = '\0'; ! fraction_part[0] = '0';
! fraction_part[1] = '\0';
if (fract) *fract = fraction_part; return integral_part; --- 583,593 ----
{ integral_part[0] = '0'; integral_part[1] = '\0'; ! /* The fractional part has to take the precision into account */
! for (ch = 0; ch < precision-1; ch++)
! fraction_part[ch] = '0';
! fraction_part[ch] = '0';
! fraction_part[ch+1] = '\0';
if (fract) *fract = fraction_part; return integral_part; *************** *** 805,810 **** --- 815,821 ----
PUT_CHAR(*tmp, p); tmp++; } +
PAD_LEFT(p); } *************** *** 972,982 **** if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp))) tmp = t; /* calculate the padding. 1 for the dot */ p->width = p->width - ((d > 0. && p->justify == RIGHT) ? 1:0) - ((p->flags & PF_SPACE) ? 1:0) - ! strlen(tmp) - p->precision - 1;
PAD_RIGHT(p); PUT_PLUS(d, p, 0.); PUT_SPACE(d, p, 0.); --- 983,1003 ----
if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp))) tmp = t; + if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
+ {
+ /* smash the trailing zeros unless altform */
+ for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
+ tmp2[i] = '\0';
+ if (tmp2[0] == '\0')
+ p->precision = 0;
+ }
+
/* calculate the padding. 1 for the dot */ p->width = p->width - ((d > 0. && p->justify == RIGHT) ? 1:0) - ((p->flags & PF_SPACE) ? 1:0) - ! strlen(tmp) - p->precision -
! ((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0); /* radix char */
PAD_RIGHT(p); PUT_PLUS(d, p, 0.); PUT_SPACE(d, p, 0.); *************** *** 991,1001 **** if (p->precision != 0 || (p->flags & PF_ALTFORM)) PUT_CHAR(decpoint, p); /* put the '.' */ - if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
- /* smash the trailing zeros unless altform */
- for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
- tmp2[i] = '\0';
-
for (; *tmp2; tmp2++) PUT_CHAR(*tmp2, p); /* the fraction */ --- 1012,1017 ----
*************** *** 1011,1024 **** char *tmp, *tmp2; int j, i; ! if (chkinfnan(p, d, 1) || chkinfnan(p, d, 2))
return; /* already printed nan or inf */ GETLOCALEDATA(decpoint, thoussep, grouping); DEF_PREC(p); ! j = log_10(d);
! d = d / pow_10(j); /* get the Mantissa */
! d = ROUND(d, p);
tmp = dtoa(d, p->precision, &tmp2); /* 1 for unit, 1 for the '.', 1 for 'e|E', --- 1027,1045 ----
char *tmp, *tmp2; int j, i; ! if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)))
return; /* already printed nan or inf */ GETLOCALEDATA(decpoint, thoussep, grouping); DEF_PREC(p); ! if (d == 0.)
! j = 0;
! else
! {
! j = log_10(d);
! d = d / pow_10(j); /* get the Mantissa */
! d = ROUND(d, p);
! }
tmp = dtoa(d, p->precision, &tmp2); /* 1 for unit, 1 for the '.', 1 for 'e|E', *************** *** 1076,1081 **** --- 1097,1103 ----
PUT_CHAR(*tmp, p); tmp++; } +
PAD_LEFT(p); } #endif *************** *** 1358,1364 **** STAR_ARGS(data); DEF_PREC(data); d = GETDOUBLE(data); ! i = log_10(d);
/* * for '%g|%G' ANSI: use f if exponent * is in the range or [-4,p] exclusively --- 1380,1386 ----
STAR_ARGS(data); DEF_PREC(data); d = GETDOUBLE(data); ! i = (d != 0.) ? log_10(d) : -1;
/* * for '%g|%G' ANSI: use f if exponent * is in the range or [-4,p] exclusively *** bash-3.2/patchlevel.h Thu Apr 13 08:31:04 2006 --- patchlevel.h Mon Oct 16 14:22:54 2006
*************** *** 26,30 **** looks for to find the patch level (for the sccs version string). */ ! #define PATCHLEVEL 4
#endif /* _PATCHLEVEL_H_ */ --- 26,30 ----
looks for to find the patch level (for the sccs version string). */ ! #define PATCHLEVEL 5
#endif /* _PATCHLEVEL_H_ */
|