aboutsummaryrefslogtreecommitdiff
path: root/package/bash/bash32-005
blob: 8972d76fb9900e16d757f1d03f98e60c5bc5f971 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
			     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
--- bash-3.2/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
--- bash-3.2/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
--- bash-3.2/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_ */