[PATCH] Fix *scanf's character range
Jakub Jelinek
jakub@redhat.com
Mon May 22 05:49:00 GMT 2000
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
More information about the Libc-hacker
mailing list