This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [PATCH] Fix *scanf's character range


On Mon, May 22, 2000 at 07:53:08AM -0400, Jonathan Kamens wrote:
> >  Date: Mon, 22 May 2000 12:20:28 +0200
> >  From: Jakub Jelinek <jakub@redhat.com>
> >  
> >  Actually, I have no idea why the test was added there even if it was e.g. f
> >  - 1 or whatever, because if the test wants to guard against f[-2] being
> >  after the opening [, then this is already guaranteed.
> 
> No, it isn't.  When the "tw = (char *) f" executes, "f" points at the
> first character after the opening '[', unless that character was ']'
> or '-'.  Therefore, "tw" points at the first character after the '['
> too.  That means that the first time through the loop, "fc" is set to
> that first character and "f" is pointing at the second character.
> Therefore, "f - 2" points at the opening "[", which we most certainly
> do not want.
> 
> I believe that the fix which I submitted to bugzilla is correct and
> yours is now -- the test you removed should not be removed, it should
> just be changed from "f - 2" to "f - 1".
> 
> I believe that your fix will cause the scanf format string "%10[--/]",
> which should imply a character range from hyphen to slash, to behave
> incorrectly.
> 
> Mind you, I'm not certain about all of this, since the code is
> somewhat complex and it is difficult to dream up good test cases for
> it, but I've read over the code several times and I think I'm right.

No, ']' and '-' after the opening '[' are handled separately before the
loop:

          fc = *f;
          if (fc == ']' || fc == '-')
            {
              /* If ] or - appears before any char in the set, it is not
                 the terminator or separator, but the first char in the
                 set.  */
              wp[fc] = 1;
              ++f;
            }

so even if fc is '-' in the first while cycle (e.g. for [--/]), then it will
be the second -, fc will be '-', f will point to "/]" and f-2 will be "--/]".
So I'm pretty sure f-2 never points to the opening '[' or before it in the
while loop if fc == '-'.

This programs works correctly with my patch btw:

bash$ cat /tmp/v.c
#include <stdio.h>

main()
{
  char buf[10] = {};
  int num;

  num = sscanf("-...-/X", "%9[--/]", buf);
  printf("num=%d, buf=\"%s\"\n", num, buf);
}
bash$ /tmp/v
num=1, buf="-...-/"

	Jakub

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]