Fix an off-by-one error in vfscanf (both libstdio and ape versions) whereby %n returns the wrong length if a string item (%s or %[) is terminated by EOF (or end-of-string in the case of sscanf). For a demonstration, see the test program below: term% testscanf %s%n xxx term% testscanf %[a]%n a Before the fix: sscanf("xxx", "%s%n", buf, &np) returns 1, np=4 sscanf("a", "%[a]%n", buf, &np) returns 1, np=2 After the fix: sscanf("xxx", "%s%n", buf, &np) returns 1, np=3 sscanf("a", "%[a]%n", buf, &np) returns 1, np=1 =============================================== #include #include #include void main(int argc, char **argv) { char buf[512]; int np, n; if(argc != 3) sysfatal("Usage: testscanf pattern string"); np = 0; n = sscanf(argv[2], argv[1], buf, &np); print("sscanf(\"%s\", \"%s\", buf, &np) returns %d, np=%d\n", argv[2], argv[1], n, np); exits(0); } Reference: /n/sources/patch/applied/scanf-n-eof Date: Thu May 20 12:18:09 CES 2010 Signed-off-by: miller@hamnavoe.com --- /sys/src/libstdio/vfscanf.c Thu May 20 12:17:51 2010 +++ /sys/src/libstdio/vfscanf.c Thu May 20 12:17:48 2010 @@ -290,6 +290,7 @@ nn=0; while(!isspace(c)){ if(c==EOF){ + nread--; if(nn==0) return 0; else goto Done; } @@ -348,6 +349,7 @@ for(;;){ wgetc(c, f, Done); if(c==EOF){ + nread--; if(nn==0) return 0; else goto Done; } --- /sys/src/ape/lib/ap/stdio/vfscanf.c Thu May 20 12:17:56 2010 +++ /sys/src/ape/lib/ap/stdio/vfscanf.c Thu May 20 12:17:53 2010 @@ -293,6 +293,7 @@ nn=0; while(!isspace(c)){ if(c==EOF){ + nread--; if(nn==0) return 0; else goto Done; } @@ -351,6 +352,7 @@ for(;;){ wgetc(c, f, Done); if(c==EOF){ + nread--; if(nn==0) return 0; else goto Done; }