bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bash 2.05 porting fixes for hosts with 64-bit int


From: Paul Eggert
Subject: bash 2.05 porting fixes for hosts with 64-bit int
Date: Fri, 13 Apr 2001 01:54:56 -0700 (PDT)

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  <address@hidden>

        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)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]