From shinra@sodans.usata.org  Wed Jul 27 10:31:23 2011
Return-Path: <shinra@sodans.usata.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 0733A106566B
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 27 Jul 2011 10:31:23 +0000 (UTC)
	(envelope-from shinra@sodans.usata.org)
Received: from sodans.usata.org (sodans.usata.org [49.212.76.31])
	by mx1.freebsd.org (Postfix) with ESMTP id A1C6B8FC0A
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 27 Jul 2011 10:31:22 +0000 (UTC)
Received: by sodans.usata.org (Postfix, from userid 1010)
	id 16439119C09; Wed, 27 Jul 2011 19:22:51 +0900 (JST)
Message-Id: <20110727102251.16439119C09@sodans.usata.org>
Date: Wed, 27 Jul 2011 19:22:51 +0900 (JST)
From: AIDA Shinra <shinra@j10n.org>
Reply-To: AIDA Shinra <shinra@j10n.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [PATCH] Multiple bugs in BSD bc(1) and dc(1)
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         159227
>Category:       bin
>Synopsis:       [PATCH] Multiple bugs in BSD bc(1) and dc(1)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kevlo
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jul 27 10:40:08 UTC 2011
>Closed-Date:    Sun Mar 18 14:56:53 UTC 2012
>Last-Modified:  Sun Mar 18 14:56:53 UTC 2012
>Originator:     AIDA Shinra
>Release:        FreeBSD 7.3-RELEASE-p6 i386
>Organization:
>Environment:
System: FreeBSD sodans.usata.org 7.3-RELEASE-p6 FreeBSD 7.3-RELEASE-p6 #1: Mon Jun 27 01:58:42 JST 2011 wm3@sodans.usata.org:/usr/obj/usr/src/sys/KERNEL_SODANS i386


	I am testing current's bc and dc on FreeBSD 7.3.
>Description:
(1) Ctrl-Z hangs my bc up.

(2) An erroneous invocation of the editline. A NULL pointer is given to el_gets().

(3) Wrong scaling in the bc.library.

(4) length(0.000) returns 1 instead of 3. It will surprise people who expect length(x) >= scale(x).
While POSIX is silent about its result, the GNU bc returns 3.
	
>How-To-Repeat:
(1) Type Ctrl-Z.

(2) Following command causes a segmentation fault or bus error.
$ bc -c something.bc

(3) Here is the typescript.
$ ./bc -l
scale=2
l(1000)
dc: scale must be a nonnegative number
6.90
e(-10)
dc: scale must be a nonnegative number
0.00

(4) See the Description.

>Fix:

	Apply the attached patch.

--- bsdbc-bugfix.diff begins here ---
Index: bc.library
===================================================================
RCS file: /home/ncvs/src/usr.bin/bc/bc.library,v
retrieving revision 1.1
diff -u -r1.1 bc.library
--- bc.library	20 Jan 2010 21:30:52 -0000	1.1
+++ bc.library	17 Jul 2011 11:53:52 -0000
@@ -46,7 +46,9 @@
 	r = ibase
 	ibase = A
 	t = scale
-	scale = t + .434*x + 1
+	scale = 0
+	if (x > 0) scale = (0.435*x)/1
+	scale = scale + t + 1
 
 	w = 0
 	if (x < 0) {
@@ -95,26 +97,33 @@
 	t = scale
 
 	f = 1
-	scale = scale + scale(x) - length(x) + 1
-	s = scale
+	if (x < 1) {
+		s = scale(x)
+	} else {
+		s = length(x)-scale(x)
+	}
+	scale = 0
+	a = (2.31*s)/1 /* estimated integer part of the answer */
+	s = t + length(a) + 2 /* estimated length of the answer */
 	while (x > 2) {
-		s = s + (length(x) - scale(x))/2 + 1
-		if (s > 0) scale = s
+		scale=0
+		scale = (length(x) + scale(x))/2 + 1
+		if (scale < s) scale = s
 		x = sqrt(x)
 		f = f*2
 	}
 	while (x < .5) {
-		s = s + (length(x) - scale(x))/2 + 1
-		if (s > 0) scale = s
+		scale = 0
+		scale = scale(x)/2 + 1
+		if (scale < s) scale = s
 		x = sqrt(x)
 		f = f*2
 	}
 
-	scale = t + length(f) - scale(f) + 1
+	scale = t + length(f) + length(t + length(f)) + 1
 	u = (x - 1)/(x + 1)
-
-	scale = scale + 1.1*length(t) - 1.1*scale(t)
 	s = u*u
+	scale = t + 2
 	b = 2*f
 	c = b
 	d = 1
@@ -261,3 +270,4 @@
 		e = g
 	}
 }
+/* vim: set filetype=bc shiftwidth=8 noexpandtab: */
Index: bc.y
===================================================================
RCS file: /home/ncvs/src/usr.bin/bc/bc.y,v
retrieving revision 1.4
diff -u -r1.4 bc.y
--- bc.y	4 Feb 2010 18:43:05 -0000	1.4
+++ bc.y	17 Jul 2011 11:53:52 -0000
@@ -48,6 +48,7 @@
 #include <stdbool.h>
 #include <string.h>
 #include <unistd.h>
+#include <stdlib.h>
 
 #include "extern.h"
 #include "pathnames.h"
@@ -1093,7 +1094,7 @@
 	switch (signo) {
 	default:
 		for (;;) {
-			pid = waitpid(dc, &status, WCONTINUED);
+			pid = waitpid(dc, &status, WUNTRACED);
 			if (pid == -1) {
 				if (errno == EINTR)
 					continue;
@@ -1181,16 +1182,6 @@
 			dup(p[1]);
 			close(p[0]);
 			close(p[1]);
-			if (interactive) {
-				el = el_init("bc", stdin, stderr, stderr);
-				hist = history_init();
-				history(hist, &he, H_SETSIZE, 100);
-				el_set(el, EL_HIST, history, hist);
-				el_set(el, EL_EDITOR, "emacs");
-				el_set(el, EL_SIGNAL, 1);
-				el_set(el, EL_PROMPT, dummy_prompt);
-				el_source(el, NULL);
-			}
 		} else {
 			close(STDIN_FILENO);
 			dup(p[0]);
@@ -1200,6 +1191,16 @@
 			err(1, "cannot find dc");
 		}
 	}
+	if (interactive) {
+		el = el_init("bc", stdin, stderr, stderr);
+		hist = history_init();
+		history(hist, &he, H_SETSIZE, 100);
+		el_set(el, EL_HIST, history, hist);
+		el_set(el, EL_EDITOR, "emacs");
+		el_set(el, EL_SIGNAL, 1);
+		el_set(el, EL_PROMPT, dummy_prompt);
+		el_source(el, NULL);
+	}
 	yywrap();
 	return (yyparse());
 }
--- bsdbc-bugfix.diff ends here ---

--- bsddc-lengthfix.diff begins here ---
Index: bcode.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/dc/bcode.c,v
retrieving revision 1.5
diff -u -r1.5 bcode.c
--- bcode.c	10 Jun 2010 10:28:38 -0000	1.5
+++ bcode.c	17 Jul 2011 07:42:55 -0000
@@ -693,7 +693,7 @@
 	u_int i;
 
 	if (BN_is_zero(n->number))
-		return (1);
+		return (n->scale ? n->scale : 1);
 
 	int_part = new_number();
 	fract_part = new_number();
--- bsddc-lengthfix.diff ends here ---


>Release-Note:
>Audit-Trail:

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/159227: commit references a PR
Date: Thu, 15 Mar 2012 01:43:53 +0000 (UTC)

 Author: kevlo
 Date: Thu Mar 15 01:43:44 2012
 New Revision: 232994
 URL: http://svn.freebsd.org/changeset/base/232994
 
 Log:
   - Fix an erroneous invocation of the editline.
   - Fix wrong scaling in the bc.library.
   - Let length(0.000) conform to what gnu bc does.
   
   PR:	bin/159227
   Submitted by:	AIDA Shinra <shinra at j10n dot org>
 
 Modified:
   head/usr.bin/bc/bc.library
   head/usr.bin/bc/bc.y
   head/usr.bin/dc/bcode.c
 
 Modified: head/usr.bin/bc/bc.library
 ==============================================================================
 --- head/usr.bin/bc/bc.library	Wed Mar 14 23:55:25 2012	(r232993)
 +++ head/usr.bin/bc/bc.library	Thu Mar 15 01:43:44 2012	(r232994)
 @@ -46,7 +46,9 @@ define e(x) {
  	r = ibase
  	ibase = A
  	t = scale
 -	scale = t + .434*x + 1
 +	scale = 0
 +	if (x > 0) scale = (0.435*x)/1
 +	scale = scale + t + 1
  
  	w = 0
  	if (x < 0) {
 @@ -95,26 +97,33 @@ define l(x) {
  	t = scale
  
  	f = 1
 -	scale = scale + scale(x) - length(x) + 1
 -	s = scale
 +	if (x < 1) {
 +		s = scale(x)
 +	} else {
 +		s = length(x) - scale(x)
 +	}
 +	scale = 0
 +	a = (2.31*s)/1 /* estimated integer part of the answer */
 +	s = t + length(a) + 2 /* estimated length of the answer */
  	while (x > 2) {
 -		s = s + (length(x) - scale(x))/2 + 1
 -		if (s > 0) scale = s
 +		scale=0
 +		scale = (length(x) + scale(x))/2 + 1
 +		if (scale < s) scale = s
  		x = sqrt(x)
  		f = f*2
  	}
  	while (x < .5) {
 -		s = s + (length(x) - scale(x))/2 + 1
 -		if (s > 0) scale = s
 +		scale = 0
 +		scale = scale(x)/2 + 1
 +		if (scale < s) scale = s
  		x = sqrt(x)
  		f = f*2
  	}
  
 -	scale = t + length(f) - scale(f) + 1
 +	scale = t + length(f) + length(t + length(f)) + 1
  	u = (x - 1)/(x + 1)
 -
 -	scale = scale + 1.1*length(t) - 1.1*scale(t)
  	s = u*u
 +	scale = t + 2
  	b = 2*f
  	c = b
  	d = 1
 @@ -261,3 +270,4 @@ define j(n,x) {
  		e = g
  	}
  }
 +/* vim: set filetype=bc shiftwidth=8 noexpandtab: */
 
 Modified: head/usr.bin/bc/bc.y
 ==============================================================================
 --- head/usr.bin/bc/bc.y	Wed Mar 14 23:55:25 2012	(r232993)
 +++ head/usr.bin/bc/bc.y	Thu Mar 15 01:43:44 2012	(r232994)
 @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
  #include <stdbool.h>
  #include <string.h>
  #include <unistd.h>
 +#include <stdlib.h>
  
  #include "extern.h"
  #include "pathnames.h"
 @@ -1093,7 +1094,7 @@ sigchld(int signo)
  	switch (signo) {
  	default:
  		for (;;) {
 -			pid = waitpid(dc, &status, WCONTINUED);
 +			pid = waitpid(dc, &status, WUNTRACED);
  			if (pid == -1) {
  				if (errno == EINTR)
  					continue;
 @@ -1181,16 +1182,6 @@ main(int argc, char *argv[])
  			dup(p[1]);
  			close(p[0]);
  			close(p[1]);
 -			if (interactive) {
 -				el = el_init("bc", stdin, stderr, stderr);
 -				hist = history_init();
 -				history(hist, &he, H_SETSIZE, 100);
 -				el_set(el, EL_HIST, history, hist);
 -				el_set(el, EL_EDITOR, "emacs");
 -				el_set(el, EL_SIGNAL, 1);
 -				el_set(el, EL_PROMPT, dummy_prompt);
 -				el_source(el, NULL);
 -			}
  		} else {
  			close(STDIN_FILENO);
  			dup(p[0]);
 @@ -1200,6 +1191,16 @@ main(int argc, char *argv[])
  			err(1, "cannot find dc");
  		}
  	}
 +	if (interactive) {
 +		el = el_init("bc", stdin, stderr, stderr);
 +		hist = history_init();
 +		history(hist, &he, H_SETSIZE, 100);
 +		el_set(el, EL_HIST, history, hist);
 +		el_set(el, EL_EDITOR, "emacs");
 +		el_set(el, EL_SIGNAL, 1);
 +		el_set(el, EL_PROMPT, dummy_prompt);
 +		el_source(el, NULL);
 +	}
  	yywrap();
  	return (yyparse());
  }
 
 Modified: head/usr.bin/dc/bcode.c
 ==============================================================================
 --- head/usr.bin/dc/bcode.c	Wed Mar 14 23:55:25 2012	(r232993)
 +++ head/usr.bin/dc/bcode.c	Thu Mar 15 01:43:44 2012	(r232994)
 @@ -693,7 +693,7 @@ count_digits(const struct number *n)
  	u_int i;
  
  	if (BN_is_zero(n->number))
 -		return (1);
 +		return (n->scale ? n->scale : 1);
  
  	int_part = new_number();
  	fract_part = new_number();
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: delphij 
State-Changed-When: Fri Mar 16 00:32:03 UTC 2012 
State-Changed-Why:  
Bump state to "patched" wrt r232994. 


Responsible-Changed-From-To: freebsd-bugs->kevlo 
Responsible-Changed-By: delphij 
Responsible-Changed-When: Fri Mar 16 00:32:03 UTC 2012 
Responsible-Changed-Why:  
Assign to kevlo who committed the patch as MFC reminder. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=159227 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/159227: commit references a PR
Date: Sun, 18 Mar 2012 14:49:51 +0000 (UTC)

 Author: kevlo
 Date: Sun Mar 18 14:49:36 2012
 New Revision: 233119
 URL: http://svn.freebsd.org/changeset/base/233119
 
 Log:
   MFC r232994:
   - Fix an erroneous invocation of the editline.
   - Fix wrong scaling in the bc.library.
   - Let length(0.000) conform to what gnu bc does.
   
   PR:	bin/159227
   Submitted by:	AIDA Shinra <shinra at j10n dot org>
 
 Modified:
   stable/9/usr.bin/bc/bc.library
   stable/9/usr.bin/bc/bc.y
   stable/9/usr.bin/dc/bcode.c
 Directory Properties:
   stable/9/usr.bin/   (props changed)
 
 Modified: stable/9/usr.bin/bc/bc.library
 ==============================================================================
 --- stable/9/usr.bin/bc/bc.library	Sun Mar 18 13:54:57 2012	(r233118)
 +++ stable/9/usr.bin/bc/bc.library	Sun Mar 18 14:49:36 2012	(r233119)
 @@ -46,7 +46,9 @@ define e(x) {
  	r = ibase
  	ibase = A
  	t = scale
 -	scale = t + .434*x + 1
 +	scale = 0
 +	if (x > 0) scale = (0.435*x)/1
 +	scale = scale + t + 1
  
  	w = 0
  	if (x < 0) {
 @@ -95,26 +97,33 @@ define l(x) {
  	t = scale
  
  	f = 1
 -	scale = scale + scale(x) - length(x) + 1
 -	s = scale
 +	if (x < 1) {
 +		s = scale(x)
 +	} else {
 +		s = length(x) - scale(x)
 +	}
 +	scale = 0
 +	a = (2.31*s)/1 /* estimated integer part of the answer */
 +	s = t + length(a) + 2 /* estimated length of the answer */
  	while (x > 2) {
 -		s = s + (length(x) - scale(x))/2 + 1
 -		if (s > 0) scale = s
 +		scale=0
 +		scale = (length(x) + scale(x))/2 + 1
 +		if (scale < s) scale = s
  		x = sqrt(x)
  		f = f*2
  	}
  	while (x < .5) {
 -		s = s + (length(x) - scale(x))/2 + 1
 -		if (s > 0) scale = s
 +		scale = 0
 +		scale = scale(x)/2 + 1
 +		if (scale < s) scale = s
  		x = sqrt(x)
  		f = f*2
  	}
  
 -	scale = t + length(f) - scale(f) + 1
 +	scale = t + length(f) + length(t + length(f)) + 1
  	u = (x - 1)/(x + 1)
 -
 -	scale = scale + 1.1*length(t) - 1.1*scale(t)
  	s = u*u
 +	scale = t + 2
  	b = 2*f
  	c = b
  	d = 1
 @@ -261,3 +270,4 @@ define j(n,x) {
  		e = g
  	}
  }
 +/* vim: set filetype=bc shiftwidth=8 noexpandtab: */
 
 Modified: stable/9/usr.bin/bc/bc.y
 ==============================================================================
 --- stable/9/usr.bin/bc/bc.y	Sun Mar 18 13:54:57 2012	(r233118)
 +++ stable/9/usr.bin/bc/bc.y	Sun Mar 18 14:49:36 2012	(r233119)
 @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
  #include <stdbool.h>
  #include <string.h>
  #include <unistd.h>
 +#include <stdlib.h>
  
  #include "extern.h"
  #include "pathnames.h"
 @@ -1093,7 +1094,7 @@ sigchld(int signo)
  	switch (signo) {
  	default:
  		for (;;) {
 -			pid = waitpid(dc, &status, WCONTINUED);
 +			pid = waitpid(dc, &status, WUNTRACED);
  			if (pid == -1) {
  				if (errno == EINTR)
  					continue;
 @@ -1181,16 +1182,6 @@ main(int argc, char *argv[])
  			dup(p[1]);
  			close(p[0]);
  			close(p[1]);
 -			if (interactive) {
 -				el = el_init("bc", stdin, stderr, stderr);
 -				hist = history_init();
 -				history(hist, &he, H_SETSIZE, 100);
 -				el_set(el, EL_HIST, history, hist);
 -				el_set(el, EL_EDITOR, "emacs");
 -				el_set(el, EL_SIGNAL, 1);
 -				el_set(el, EL_PROMPT, dummy_prompt);
 -				el_source(el, NULL);
 -			}
  		} else {
  			close(STDIN_FILENO);
  			dup(p[0]);
 @@ -1200,6 +1191,16 @@ main(int argc, char *argv[])
  			err(1, "cannot find dc");
  		}
  	}
 +	if (interactive) {
 +		el = el_init("bc", stdin, stderr, stderr);
 +		hist = history_init();
 +		history(hist, &he, H_SETSIZE, 100);
 +		el_set(el, EL_HIST, history, hist);
 +		el_set(el, EL_EDITOR, "emacs");
 +		el_set(el, EL_SIGNAL, 1);
 +		el_set(el, EL_PROMPT, dummy_prompt);
 +		el_source(el, NULL);
 +	}
  	yywrap();
  	return (yyparse());
  }
 
 Modified: stable/9/usr.bin/dc/bcode.c
 ==============================================================================
 --- stable/9/usr.bin/dc/bcode.c	Sun Mar 18 13:54:57 2012	(r233118)
 +++ stable/9/usr.bin/dc/bcode.c	Sun Mar 18 14:49:36 2012	(r233119)
 @@ -693,7 +693,7 @@ count_digits(const struct number *n)
  	u_int i;
  
  	if (BN_is_zero(n->number))
 -		return (1);
 +		return (n->scale ? n->scale : 1);
  
  	int_part = new_number();
  	fract_part = new_number();
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: kevlo 
State-Changed-When: Sun Mar 18 14:55:44 UTC 2012 
State-Changed-Why:  
The patch MFC'd to stable/9, thanks. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=159227 
>Unformatted:
