Bug 17824

Summary: [PATCH] /usr/bin/column has arithmetic overflows
Product: Base System Reporter: jdg <jdg>
Component: binAssignee: Sheldon Hearn <sheldonh>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   

Description jdg 2000-04-06 10:10:01 UTC
I discovered that column gave divide-by-zero errors in certain
situations (specifically, if the number of display columns is c and
the widest item of data has width w, then letting w8 = 8*((w+8)/8)
(rounding down to the nearest int), the error will occur if w<c<w8).
The patch in the "Fix" section below corrects this bug.  (It's not
obvious because usually c=80, so we cannot have w<c<w8.)

Fix: [This patch won't work directly because of tab->space conversion.]



maxlength = (maxlength + TAB) & ~(TAB - 1);
        numcols = termwidth / maxlength;
+       if (!numcols) {
+               print();
+               exit(eval);
+       }
        endcol = maxlength;
        for (chcnt = col = 0, lp = list;; ++lp) {
                chcnt += printf("%s", *lp);
@@ -173,6 +177,10 @@

        maxlength = (maxlength + TAB) & ~(TAB - 1);
        numcols = termwidth / maxlength;
+       if (!numcols) {
+               print();
+               exit(eval);
+       }
        numrows = entries / numcols;
        if (entries % numcols)
                ++numrows;--hDopEm2EW28X6WgWt7dHRPlGcAiReMmdV10S1aLDsJyQN5zE
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

--- column.c.orig       Thu Mar 25 02:47:47 1999
+++ column.c    Wed Apr  5 23:42:31 2000
@@ -145,6 +145,10 @@
How-To-Repeat: polya:~ $ cat > /tmp/72
123456789012345678901234567890123456789012345678901234567890123456789012
polya:~ $ column -c 79 </tmp/72
Floating point exception
polya:~ $
Comment 1 Sheldon Hearn 2000-04-06 13:25:53 UTC
On Thu, 06 Apr 2000 02:06:54 MST, jdg@debian.org wrote:

>         maxlength = (maxlength + TAB) & ~(TAB - 1);
>         numcols = termwidth / maxlength;
> +       if (!numcols) {

I don't get it.  You still don't seem to be protecting against
divide-by-zero.  Shouldn't you be testing the value of the dividend
before dividing?

Ciao,
Sheldon.
Comment 2 Sheldon Hearn 2000-04-06 13:37:05 UTC
On Thu, 06 Apr 2000 14:25:53 +0200, Sheldon Hearn wrote:

> I don't get it.  You still don't seem to be protecting against
> divide-by-zero.  Shouldn't you be testing the value of the dividend
> before dividing?

Agh, I meant the divisor, of course.

Ciao,
Sheldon.
Comment 3 J.D.Gilbey 2000-04-06 17:26:51 UTC
On Thu, Apr 06, 2000 at 02:25:53PM +0200, Sheldon Hearn wrote:
> On Thu, 06 Apr 2000 02:06:54 MST, jdg@debian.org wrote:
> 
> >         maxlength = (maxlength + TAB) & ~(TAB - 1);
> >         numcols = termwidth / maxlength;
> > +       if (!numcols) {
> 
> I don't get it.  You still don't seem to be protecting against
> divide-by-zero.  Shouldn't you be testing the value of the dividend
> before dividing?

maxlength >= 0.  So, assuming that TAB is 8 (which it presumably is),
the first line of the code rounds maxlength up to the next multiple of
8, so maxlength >= 8 after this step.

However, it is possible that numcols is zero if termwidth is less than
the new maxlength, in which case we get a divide by zero in the next
line (numrows = numlines / numcols or something like that).  That's
why I test for numcols being zero and not maxlength.

   Julian

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

  Julian Gilbey, Dept of Maths, QMW, Univ. of London. J.D.Gilbey@qmw.ac.uk
        Debian GNU/Linux Developer,  see http://www.debian.org/~jdg
  Donate free food to the world's hungry: see http://www.thehungersite.com/
Comment 4 Sheldon Hearn 2000-04-06 21:47:56 UTC
On Thu, 06 Apr 2000 17:26:51 +0100, Julian Gilbey wrote:

> However, it is possible that numcols is zero if termwidth is less than
> the new maxlength, in which case we get a divide by zero in the next
> line (numrows = numlines / numcols or something like that).

Gotcha!  Thanks.

Ciao,
Sheldon.
Comment 5 Sheldon Hearn freebsd_committer freebsd_triage 2000-04-06 21:48:26 UTC
Responsible Changed
From-To: freebsd-bugs->sheldonh

I'll take this one. 

Comment 6 Sheldon Hearn freebsd_committer freebsd_triage 2000-08-08 13:52:45 UTC
State Changed
From-To: open->feedback

Are you happy with the OpenBSD fix for this? 

http://www.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/column/column.c.diff?r1=1.4&r2=1.5&cvsroot=openbsd
Comment 7 jdg 2000-12-04 10:10:18 UTC
On Tue, Aug 08, 2000 at 05:53:32AM -0700, sheldonh@freebsd.org wrote:
> Synopsis: [PATCH] /usr/bin/column has arithmetic overflows
> 
> State-Changed-From-To: open->feedback
> State-Changed-By: sheldonh
> State-Changed-When: Tue Aug 8 05:52:45 PDT 2000
> State-Changed-Why: 
> Are you happy with the OpenBSD fix for this?
> 
> 	http://www.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/column/column.c.diff?r1=1.4&r2=1.5&cvsroot=openbsd

No, you need to patch c_columnate as well in the same way, although I
prefer your patch to mine because of the tab->space business you
noticed.

   Julian

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

  Julian Gilbey, Dept of Maths, QMW, Univ. of London. J.D.Gilbey@qmw.ac.uk
        Debian GNU/Linux Developer,  see http://www.debian.org/~jdg
  Donate free food to the world's hungry: see http://www.thehungersite.com/
Comment 8 Sheldon Hearn freebsd_committer freebsd_triage 2001-11-27 18:26:52 UTC
State Changed
From-To: feedback->closed

Closed as per audit trail for bin/26283 .