Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Sep 1998 09:32:12 +0100
From:      Niall Smart <nialls@euristix.ie>
To:        freebsd-gnats-submit@FreeBSD.ORG
Subject:   bin/7970: Bug in *scanf: %n is sometimes ignored.
Message-ID:  <98Sep18.095224bst.19713@gateway.euristix.ie>

next in thread | raw e-mail | index | archive | help

>Number:         7970
>Category:       bin
>Synopsis:       Bug in *scanf: %n is sometimes ignored.
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Sep 18 02:00:01 PDT 1998
>Last-Modified:
>Originator:     Niall Smart
>Organization:
None
>Release:        FreeBSD 3.0-CURRENT i386
>Environment:

>Description:

There is a bug in the implementation of __svfscanf which sometimes
causes the %n `conversion' to be ignored.  (%n is used to assign the
number of characters read from the input stream to its corresponding
argument)

The following code demonstrates the bug:

#include <stdio.h>

int
main()
{
        int     i;
        int     n = 12345678;

        sscanf("24\n", "%li %n", &i, &n);       
        
        printf("%d %d\n", i, n);
        
        return 0;
}

The output should be "4 2", but it is "4 12345678"; n is not
modified.  The bug arises when a whitespace is present in the
format string and __svfscanf hits EOF while skipping 
corresponding whitespace in the input stream, in this case
it jumps to input_failure and exits before seeing the %n 
subsequent in the format string.  Jumping to input_failure
would _usually_ be the correct move since most conversions
would require input (which is not available) so quitting then
would be an optimisation.  The solution is simply to have it
continue in its iteration over the format string, this is the
approach taken by OpenBSD and I have used their patch.

Credit for patch: Chris Torek <torek@bsdi.com>
                  Tod Miller  <millert@openbsd.org>

>How-To-Repeat:

See attached code.

>Fix:
        
*** src/lib/libc/stdio/vfscanf.c~       Tue Sep 15 17:52:48 1998
--- src/lib/libc/stdio/vfscanf.c        Tue Sep 15 17:57:04 1998
***************
*** 137,149 ****
                if (c == 0)
                        return (nassigned);
                if (isspace(c)) {
!                       for (;;) {
!                               if (fp->_r <= 0 && __srefill(fp))
!                                       goto input_failure;
!                               if (!isspace(*fp->_p))
!                                       break;
                                nread++, fp->_r--, fp->_p++;
-                       }
                        continue;
                }
                if (c != '%')
--- 137,144 ----
                if (c == 0)
                        return (nassigned);
                if (isspace(c)) {
!                       while ((fp->_r > 0 || __srefill(fp) == 0) && isspace(*fp->_p))
                                nread++, fp->_r--, fp->_p++;
                        continue;
                }
                if (c != '%')
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?98Sep18.095224bst.19713>