tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
rfc: *scanf() parse certain string incorrectly
Hello.
For first, a small test case:
#include <stdio.h>
int main()
{
/* set of "white space" symbols from isspace(3) */
char *str = "\f\n\r\t\v%z";
char c = 0;
sscanf(str, "%%%c", &c);
printf("char %c\n", c);
printf("code %d\n", (unsigned int) c);
return 0;
}
And of course results (linux/netbsd):
andy@FITFIESPPC176:~/tmp/base-ts$ ./scanf
char z
code 122
-bash-3.2$ ./scanf
char
code 0
Here is a cite from SUSv3 (a little bit unclear, as I think, but anyway):
"A directive that is a conversion specification defines a set of
matching input sequences, as described below for each conversion
character. A conversion specification shall be executed in the
following steps.
Input white-space characters (as specified by isspace()) shall be
skipped, unless the conversion specification includes a [, c, C, or n
conversion specifier."
And a small hack (This hack NOT covers all cases!):
diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c
index cdd17dc..4c1aeba 100644
--- a/lib/libc/stdio/vfscanf.c
+++ b/lib/libc/stdio/vfscanf.c
@@ -140,6 +140,12 @@ __svfscanf(FILE *fp, char const *fmt0, va_list ap)
return (ret);
}
+#define SCANF_SKIP_SPACE() \
+do { \
+ while ((fp->_r > 0 || __srefill(fp) == 0) && isspace(*fp->_p)) \
+ nread++, fp->_r--, fp->_p++; \
+} while (/*CONSTCOND*/ 0)
+
/*
* __svfscanf_unlocked - non-MT-safe version of __svfscanf
*/
@@ -198,6 +202,7 @@ __svfscanf_unlocked(FILE *fp, const char *fmt0, va_list ap)
again: c = *fmt++;
switch (c) {
case '%':
+ SCANF_SKIP_SPACE();
literal:
if (fp->_r <= 0 && __srefill(fp))
goto input_failure;
Results after applying the hack.
-bash-3.2$ LD_LIBRARY_PATH=~/current/obj/lib/libc ./scanf
char z
code 122
--
With Best Regards,
Andy Shevchenko
Home |
Main Index |
Thread Index |
Old Index