Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

bash 2.05 porting fixes for hosts with 64-bit int

0 views
Skip to first unread message

Paul Eggert

unread,
Apr 13, 2001, 4:54:56 AM4/13/01
to
Configuration Information [Automatically generated, do not change]:
Machine: sparc
OS: solaris2.8
Compiler: gcc
Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='sparc' -DCONF_OSTYPE='solaris2.8' -DCONF_MACHTYPE='sparc-sun-solaris2.8' -DCONF_VENDOR='sun' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -I/opt/reb/include -g -O2 -Wall
uname output: SunOS shade.twinsun.com 5.8 Generic_108528-06 sun4u sparc SUNW,Ultra-1
Machine Type: sparc-sun-solaris2.8

Bash Version: 2.05
Patch Level: 0
Release Status: release

Description:
Bash 2.05 has hardcoded limits for the print length of
'int' and 'long' which are invalid for hosts that have
64-bit int or 128-bit long. Rather than bumping the harcoded
limit, the fix below fixes the problem permanently by computing
the limit automatically at compile-time.

Repeat-By:

Fix:

2001-04-13 Paul Eggert <egg...@twinsun.com>

Do not assume that an 'int' can be printed in 15 bytes, or
that a 'long' can be printed in 31 bytes. Instead, compute an
upper bound on the print width (at compile time) and use that
bound. This technique is taken from other GNU utilities.

* general.h: Include <limits.h> if HAVE_LIMITS_H.
(CHAR_BIT): Define if limits.h does not.
(TYPE_SIGNED, INT_STRLEN_BOUND): New macros, taken from other GNU
utilities.

* execute_cmd.c (mkfmt, print_formatted_time):
Use INT_STRLEN_BOUND rather than guessing at a bound.
* lib/sh/itos.c (itos): Likewise.
* pcomplete.c (bind_compfunc_variables): Likewise.
* print_cmd.c (cprintf): Likewise.
* subst.c (make_dev_fd_filename): Likewise.
* variables.c (set_ppid, uidset, make_vers_array,
sh_set_lines_and_columns): Likewise.

* execute_cmd.c, findcmd.c, test.c:
Do not include <limits.h>, as general.h now does this.

* lib/sh/itos.c (MAX_INT_LEN): Remove.

===================================================================
RCS file: general.h,v
retrieving revision 2.5
retrieving revision 2.5.0.1
diff -pu -r2.5 -r2.5.0.1
--- general.h 2001/02/14 21:53:05 2.5
+++ general.h 2001/04/13 08:15:26 2.5.0.1
@@ -38,6 +38,10 @@
# include <strings.h>
#endif /* !HAVE_STRING_H */

+#if defined (HAVE_LIMITS_H)
+# include <limits.h>
+#endif
+
/* Generic pointer type. */
#if defined (__STDC__)
# define PTR_T void *
@@ -94,6 +98,22 @@ extern char *strcpy ();
#define ISOCTAL(c) ((c) >= '0' && (c) <= '7')
#endif

+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+/* Nonzero if the integer type T is signed. */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+
+/* Bound on length of the string representing an integer value of type T.
+ Subtract one for the sign bit if T is signed;
+ 302 / 1000 is log10 (2) rounded up;
+ add one for integer division truncation;
+ add one more for a minus sign if t is signed. */
+#define INT_STRLEN_BOUND(t) \
+ ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
+ + 1 + TYPE_SIGNED (t))
+
/* Define exactly what a legal shell identifier consists of. */
#define legal_variable_starter(c) (isletter(c) || (c == '_'))
#define legal_variable_char(c) (isletter (c) || digit (c) || c == '_')
===================================================================
RCS file: execute_cmd.c,v
retrieving revision 2.5.0.2
retrieving revision 2.5.0.3
diff -pu -r2.5.0.2 -r2.5.0.3
--- execute_cmd.c 2001/04/13 00:46:05 2.5.0.2
+++ execute_cmd.c 2001/04/13 08:15:26 2.5.0.3
@@ -40,10 +40,6 @@
# include <unistd.h>
#endif

-#if defined (HAVE_LIMITS_H)
-# include <limits.h>
-#endif
-
#include "posixtime.h"

#if defined (HAVE_SYS_RESOURCE_H) && !defined (RLIMTYPE)
@@ -812,18 +808,18 @@ mkfmt (buf, prec, lng, sec, sec_fraction
int sec_fraction;
{
time_t min;
- char abuf[16];
+ char abuf[INT_STRLEN_BOUND (time_t) + 1];
int ind, aind;

ind = 0;
- abuf[15] = '\0';
+ abuf[sizeof (abuf) - 1] = '\0';

/* If LNG is non-zero, we want to decompose SEC into minutes and seconds. */
if (lng)
{
min = sec / 60;
sec %= 60;
- aind = 14;
+ aind = sizeof (abuf) - 2;
do
abuf[aind--] = (min % 10) + '0';
while (min /= 10);
@@ -834,7 +830,7 @@ mkfmt (buf, prec, lng, sec, sec_fraction
}

/* Now add the seconds. */
- aind = 14;
+ aind = sizeof (abuf) - 2;
do
abuf[aind--] = (sec % 10) + '0';
while (sec /= 10);
@@ -887,7 +883,7 @@ print_formatted_time (fp, format, rs, rs
int rsf, usf, ssf, cpu;
{
int prec, lng, len;
- char *str, *s, ts[32];
+ char *str, *s, ts[INT_STRLEN_BOUND (time_t) + sizeof ("mSS.FFFF")];
time_t sum;
int sum_frac;
int sindex, ssize;
===================================================================
RCS file: findcmd.c,v
retrieving revision 2.5
retrieving revision 2.5.0.1
diff -pu -r2.5 -r2.5.0.1
--- findcmd.c 2001/02/20 20:19:10 2.5
+++ findcmd.c 2001/04/13 08:15:26 2.5.0.1
@@ -34,10 +34,6 @@
# include <unistd.h>
#endif

-#if defined (HAVE_LIMITS_H)
-# include <limits.h>
-#endif
-
#include "bashansi.h"

#include "memalloc.h"
===================================================================
RCS file: lib/sh/itos.c,v
retrieving revision 2.5.0.1
retrieving revision 2.5.0.2
diff -pu -r2.5.0.1 -r2.5.0.2
--- lib/sh/itos.c 2001/04/13 07:08:33 2.5.0.1
+++ lib/sh/itos.c 2001/04/13 08:15:26 2.5.0.2
@@ -27,10 +27,6 @@
#include "bashansi.h"
#include "shell.h"

-/* Number of characters that can appear in a string representation
- of an integer. 32 is larger than the string rep of 2^^31 - 1. */
-#define MAX_INT_LEN 32
-
/* Integer to string conversion. The caller passes the buffer and
the size. This should check for buffer underflow, but currently
does not. */
@@ -65,7 +61,7 @@ char *
itos (i)
long i;
{
- char *p, lbuf[MAX_INT_LEN];
+ char *p, lbuf[INT_STRLEN_BOUND (long) + 1];

p = inttostr (i, lbuf, sizeof(lbuf));
return (savestring (p));
===================================================================
RCS file: pcomplete.c,v
retrieving revision 2.5
retrieving revision 2.5.0.1
diff -pu -r2.5 -r2.5.0.1
--- pcomplete.c 2001/02/14 21:59:55 2.5
+++ pcomplete.c 2001/04/13 08:15:26 2.5.0.1
@@ -825,7 +825,7 @@ bind_compfunc_variables (line, ind, lwor
WORD_LIST *lwords;
int cw, exported;
{
- char ibuf[32];
+ char ibuf[INT_STRLEN_BOUND (int) + 1];
char *value;
SHELL_VAR *v;

@@ -835,7 +835,7 @@ bind_compfunc_variables (line, ind, lwor
if (v && exported)
VSETATTR(v, att_exported);

- value = inttostr (ind, ibuf, 32);
+ value = inttostr (ind, ibuf, sizeof (ibuf));
v = bind_int_variable ("COMP_POINT", value);
if (v && exported)
VSETATTR(v, att_exported);
@@ -846,7 +846,7 @@ bind_compfunc_variables (line, ind, lwor
{
#ifdef ARRAY_VARS
v = bind_comp_words (lwords);
- value = inttostr (cw, ibuf, 32);
+ value = inttostr (cw, ibuf, sizeof (ibuf));
bind_int_variable ("COMP_CWORD", value);
#endif
}
===================================================================
RCS file: print_cmd.c,v
retrieving revision 2.5.0.1
retrieving revision 2.5.0.2
diff -pu -r2.5.0.1 -r2.5.0.2
--- print_cmd.c 2001/04/11 05:56:29 2.5.0.1
+++ print_cmd.c 2001/04/13 08:15:26 2.5.0.2
@@ -973,7 +973,7 @@ cprintf (format, arg1, arg2)
char *format, *arg1, *arg2;
{
register char *s;
- char char_arg[2], *argp, *args[2], intbuf[32];
+ char char_arg[2], *argp, *args[2], intbuf[INT_STRLEN_BOUND (int) + 1];
int arg_len, c, arg_index;

args[arg_index = 0] = arg1;
@@ -1063,7 +1063,7 @@ cprintf (control, va_alist)
#endif
{
register char *s;
- char char_arg[2], *argp, intbuf[32];
+ char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (int) + 1];
int digit_arg, arg_len, c;
va_list args;

===================================================================
RCS file: subst.c,v
retrieving revision 2.5.0.2
retrieving revision 2.5.0.3
diff -pu -r2.5.0.2 -r2.5.0.3
--- subst.c 2001/04/13 07:56:16 2.5.0.2
+++ subst.c 2001/04/13 08:15:26 2.5.0.3
@@ -3139,7 +3139,7 @@ static char *
make_dev_fd_filename (fd)
int fd;
{
- char *ret, intbuf[16], *p;
+ char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p;

ret = xmalloc (sizeof (DEV_FD_PREFIX) + 4);

===================================================================
RCS file: test.c,v
retrieving revision 2.5.0.1
retrieving revision 2.5.0.2
diff -pu -r2.5.0.1 -r2.5.0.2
--- test.c 2001/04/12 21:50:50 2.5.0.1
+++ test.c 2001/04/13 08:15:26 2.5.0.2
@@ -32,9 +32,7 @@

#include "bashtypes.h"

-#if defined (HAVE_LIMITS_H)
-# include <limits.h>
-#else
+#if !defined (HAVE_LIMITS_H)
# include <sys/param.h>
#endif

===================================================================
RCS file: variables.c,v
retrieving revision 2.5.0.2
retrieving revision 2.5.0.3
diff -pu -r2.5.0.2 -r2.5.0.3
--- variables.c 2001/04/13 07:56:16 2.5.0.2
+++ variables.c 2001/04/13 08:15:26 2.5.0.3
@@ -613,7 +613,7 @@ set_pwd ()
void
set_ppid ()
{
- char namebuf[32], *name;
+ char namebuf[INT_STRLEN_BOUND (pid_t) + 1], *name;
SHELL_VAR *temp_var;

name = inttostr (getppid (), namebuf, sizeof (namebuf));
@@ -627,7 +627,7 @@ set_ppid ()
static void
uidset ()
{
- char buff[32], *b;
+ char buff[INT_STRLEN_BOUND (uid_t) + 1], *b;
register SHELL_VAR *v;

b = inttostr (current_user.uid, buff, sizeof (buff));
@@ -655,7 +655,7 @@ make_vers_array ()
{
SHELL_VAR *vv;
ARRAY *av;
- char *s, d[32];
+ char *s, d[32], b[INT_STRLEN_BOUND (int) + 1];

makunbound ("BASH_VERSINFO", shell_variables);

@@ -667,9 +667,9 @@ make_vers_array ()
*s++ = '\0';
array_add_element (av, 0, d);
array_add_element (av, 1, s);
- s = inttostr (patch_level, d, sizeof (d));
+ s = inttostr (patch_level, b, sizeof (b));
array_add_element (av, 2, s);
- s = inttostr (build_version, d, sizeof (d));
+ s = inttostr (build_version, b, sizeof (b));
array_add_element (av, 3, s);
array_add_element (av, 4, release_status);
array_add_element (av, 5, MACHTYPE);
@@ -684,7 +684,7 @@ void
sh_set_lines_and_columns (lines, cols)
int lines, cols;
{
- char val[32], *v;
+ char val[INT_STRLEN_BOUND (int) + 1], *v;

v = inttostr (lines, val, sizeof (val));
bind_variable ("LINES", v);
@@ -3477,7 +3477,7 @@ set_pipestatus_array (ps)
SHELL_VAR *v;
ARRAY *a;
register int i;
- char *t, tbuf[16];
+ char *t, tbuf[INT_STRLEN_BOUND (int) + 1];

v = find_variable ("PIPESTATUS");
if (v == 0)

0 new messages