Subject: bin/4254: numeric and format overflows in ftp status display
To: None <gnats-bugs@gnats.netbsd.org>
From: Matthias Drochner <drochner@zelz26.zel.kfa-juelich.de>
List: netbsd-bugs
Date: 10/10/1997 13:27:30
>Number:         4254
>Category:       bin
>Synopsis:       numeric and format overflows in ftp status display
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Oct 10 04:35:02 1997
>Last-Modified:
>Originator:     Matthias Drochner
>Organization:
	KFA Juelich
>Release:        NetBSD-current, Oct 10 1997
>Environment:
	NetBSD-current, Oct 10 1997
System: NetBSD zelz26 1.2G NetBSD 1.2G (GENERIC.KGDB) #130: Wed Oct 8 19:54:08 MEST 1997 drochner@zelz26:/mnt/sys/arch/i386/compile/GENERIC.KGDB i386


>Description:
	The cast from the estimated transfer time (calculated as double)
to the "int" used by the output code can overflow the numeric range. Even
if within the range, the number can become too large to fit into the
corresponding field in the status line.
>How-To-Repeat:
	Fetch a file from a Linux ftp server. Their ftp "SIZE" commands are
broken, leading to negative estimated times for me. In principle, slow network
connections can result in the same.
>Fix:
	Chech the value before casting.
One possible solution (avoiding "fmod()"):

Index: util.c
===================================================================
RCS file: /cvsroot/src/usr.bin/ftp/util.c,v
retrieving revision 1.14
diff -c -2 -r1.14 util.c
*** util.c	1997/09/21 01:06:32	1.14
--- util.c	1997/10/10 11:10:56
***************
*** 583,587 ****
  	off_t cursize, abbrevsize;
  	double elapsed;
! 	int ratio, barlength, i, remaining;
  	char buf[256];
  
--- 583,588 ----
  	off_t cursize, abbrevsize;
  	double elapsed;
! 	int ratio, barlength, i;
! 	double remaining;
  	char buf[256];
  
***************
*** 642,648 ****
  		    " - stalled -");
  	} else {
! 		remaining = (int)((filesize - restart_point) /
! 				  (bytes / elapsed) - elapsed);
! 		i = remaining / 3600;
  		if (i)
  			snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
--- 643,651 ----
  		    " - stalled -");
  	} else {
! 		remaining = (filesize - restart_point) /
! 		    (bytes / elapsed) - elapsed;
! 		if (remaining > 999 * 3600 + 59 * 60 + 59)
! 			remaining = 999 * 3600 + 59 * 60 + 59;
! 		i = (int)remaining / 3600;
  		if (i)
  			snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
***************
*** 651,655 ****
  			snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
  			    "   ");
! 		i = remaining % 3600;
  		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
  		    "%02d:%02d ETA", i / 60, i % 60);
--- 654,658 ----
  			snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
  			    "   ");
! 		i = (int)remaining % 3600;
  		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
  		    "%02d:%02d ETA", i / 60, i % 60);
>Audit-Trail:
>Unformatted: