>Number:         159227
>Category:       bin
>Synopsis:       [PATCH] Multiple bugs in BSD bc(1) and dc(1)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jul 27 10:40:08 UTC 2011
>Closed-Date:
>Last-Modified:
>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 
w...@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:
>Unformatted:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to