summaryrefslogtreecommitdiff
path: root/libc/stdio/scanf.c
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2003-05-15 21:32:31 +0000
committerManuel Novoa III <mjn3@codepoet.org>2003-05-15 21:32:31 +0000
commita8938c2781a66b386eb0807f9149b871d03f4c6e (patch)
tree352f79ae33aa39a97b0d054278f305c170060978 /libc/stdio/scanf.c
parentd4a3dca05a9841ef68bca43b829b0b66624f1ae8 (diff)
Fix (hopefully) scanf behavior for nul bytes in the stream when processing
%c, %s, and %[ specifiers. Note that scanf is undergoing rewrite so I didn't bother optimizing this. I did run all my regression tests though. Set EOF correctly for fmemopen on readonly streams. I really need to check what glibc behavior is for the various open modes though.
Diffstat (limited to 'libc/stdio/scanf.c')
-rw-r--r--libc/stdio/scanf.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c
index 7c316cdf8..4fbf1cdfa 100644
--- a/libc/stdio/scanf.c
+++ b/libc/stdio/scanf.c
@@ -32,6 +32,9 @@
*
* Sep 6, 2002
* Patch from Tero_Lyytikäinen <tero@paravant.fi> to fix bug in matchchar case.
+ *
+ * May 15, 2003
+ * Hopefully fix handling of 0 bytes with %s, %c, and %[ specifiers.
*/
#define _ISOC99_SOURCE /* for LLONG_MAX primarily... */
@@ -122,10 +125,10 @@ int vsscanf(__const char *sp, __const char *fmt, va_list ap)
{
FILE string[1];
- string->filedes = -2; /* for debugging */
+ string->filedes = -2;
string->modeflags = (__FLAG_NARROW|__FLAG_READONLY);
string->bufstart = string->bufpos = (unsigned char *) ((void *) sp);
- string->bufgetc = (char *) ((unsigned) -1);
+ string->bufgetc = string->bufstart + strlen(sp);
#ifdef __STDIO_MBSTATE
__INIT_MBSTATE(&(string->state));
@@ -241,7 +244,7 @@ static int scan_getc(register struct scan_cookie *sc)
sc->width_flag = 1;
if (--sc->width < 0) {
sc->ungot_flag = 1;
- return 0;
+ return -1;
}
sc->ungot_flag = 0;
if (sc->ungot_char > 0) {
@@ -347,7 +350,7 @@ int vfscanf(FILE *fp, const char *format, va_list ap)
if (p-spec < 5) { /* [,c,s - string conversions */
invert = 0;
if (*p == 'c') {
- invert = 1;
+ invert = 0;
if (sc.width == INT_MAX) {
sc.width = 1;
}
@@ -399,12 +402,16 @@ int vfscanf(FILE *fp, const char *format, va_list ap)
b = buf;
}
cc = scan_getc(&sc);
- if (cc <= 0) {
+ if (cc < 0) {
scan_ungetc(&sc);
goto done; /* return EOF if cnt == 0 */
}
+ if (*p == 'c') {
+ goto c_spec;
+ }
i = 0;
- while ((cc>0) && (scanset[cc] != invert)) {
+ while ((cc>=0) && (scanset[cc] != invert)) {
+ c_spec:
i = 1; /* yes, we stored something */
*b = cc;
b += store;