NetBSD-Bugs archive

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

lib/46935: editline(3) (libedit): faulty errno handling, faulty reuse of val in wrong context



>Number:         46935
>Category:       lib
>Synopsis:       editline(3) (libedit): faulty errno handling, faulty reuse of 
>val in wrong context
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Sep 10 20:00:01 +0000 2012
>Originator:     Steffen Nurpmeso
>Release:        netbsd-6-base
>Organization:
>Environment:
None - seen on HEAD and netbsd-6-base
>Description:
While i had the chance to work on FreeBSD PR bin/169773 [1] some
bugs in read.c were revealed.
Now that i've looked at the NetBSD version there seem to be rather
the same problem(s).

[1] http://www.freebsd.org/cgi/query-pr.cgi?pr=169773&cat=
>How-To-Repeat:
Look at the source.
>Fix:
Diff against netbsd-6-base as of 2012-08-31.
The EILSEQ case may not be correct (in respect to value).
I'm not running NetBSD (for real) at the moment, so someone
with a glue should look at that.  It has not been tested,
not even compiled (due to above reason).

diff --git a/src/lib/libedit/read.c b/src/lib/libedit/read.c
index 8fcf6eb..38d586c 100644
--- a/src/lib/libedit/read.c
+++ b/src/lib/libedit/read.c
@@ -321,6 +321,7 @@ read_char(EditLine *el, Char *cp)
  again:
        el->el_signal->sig_no = 0;
        while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) {
+               int e = errno;
                switch (el->el_signal->sig_no) {
                case SIGCONT:
                        FUN(el,set)(el, EL_REFRESH);
@@ -331,9 +332,10 @@ read_char(EditLine *el, Char *cp)
                default:
                        break;
                }
-               if (!tried && read__fixio(el->el_infd, errno) == 0)
+               if (!tried && read__fixio(el->el_infd, e) == 0)
                        tried = 1;
                else {
+                       errno = e;
                        *cp = '\0';
                        return -1;
                }
@@ -347,6 +349,7 @@ read_char(EditLine *el, Char *cp)
                if ((bytes = ct_mbtowc(cp, cbuf, cbp)) == -1) {
                        ct_mbtowc_reset;
                        if (cbp >= MB_LEN_MAX) { /* "shouldn't happen" */
+                               errno = EILSEQ;
                                *cp = '\0';
                                return -1;
                        }
@@ -427,6 +430,8 @@ FUN(el,getc)(EditLine *el, Char *cp)
        (void) fprintf(el->el_errfile, "Reading a character\n");
 #endif /* DEBUG_READ */
        num_read = (*el->el_read.read_char)(el, cp);
+       if (num_read < 0)
+               el->el_errno = errno;
 #ifdef WIDECHAR
        if (el->el_flags & NARROW_READ)
                *cp = *(char *)(void *)cp;
@@ -572,6 +577,7 @@ FUN(el,gets)(EditLine *el, int *nread)
 #endif /* DEBUG_EDIT */
                /* if EOF or error */
                if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
+                       num = -1;
 #ifdef DEBUG_READ
                        (void) fprintf(el->el_errfile,
                            "Returning from el_gets %d\n", num);



Home | Main Index | Thread Index | Old Index