msvcrt/file: stdio should clamp characters to 8 bits. (Bug 14192)

Michael Karcher wine at mkarcher.dialup.fu-berlin.de
Sat Aug 16 10:08:51 CDT 2008


fputc(ch,f) should write the value of (unsigned char)ch to the
file, and return the value written to the file (cast back to int),
so the result of fputc should always be positive.

Tested against native msvcrt as installed by winetricks vcrun6.

Thanks to Sebastian Leske for reporting this bug.
Thanks to Anastasius Focht to tracking it down.
---
 dlls/msvcrt/file.c       |    4 +-
 dlls/msvcrt/tests/file.c |   59 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index cd15e40..79f3a81 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -2539,7 +2539,7 @@ int CDECL MSVCRT_fputc(int c, MSVCRT_FILE* file)
       return res ? res : c;
     }
     else
-      return c;
+      return c & 0xFF;
   } else {
     return MSVCRT__flsbuf(c, file);
   }
@@ -2568,7 +2568,7 @@ int CDECL MSVCRT__flsbuf(int c, MSVCRT_FILE* file)
 	unsigned char cc=c;
         int len;
 	len = MSVCRT__write(file->_file, &cc, 1);
-        if (len == 1) return c;
+        if (len == 1) return c & 0xFF;
         file->_flag |= MSVCRT__IOERR;
         return MSVCRT_EOF;
   }
diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c
index ec22d81..45ffdce 100644
--- a/dlls/msvcrt/tests/file.c
+++ b/dlls/msvcrt/tests/file.c
@@ -334,6 +334,63 @@ static void test_fgetc( void )
   unlink(tempf);
 }
 
+static void test_fputc( void )
+{
+  char* tempf;
+  FILE *tempfh;
+  int  ret;
+
+  tempf=_tempnam(".","wne");
+  tempfh = fopen(tempf,"wb");
+  ret = fputc(0,tempfh);
+  ok(0 == ret, "fputc(0,tempfh) expected %x got %x\n", 0, ret);
+  ret = fputc(0xff,tempfh);
+  ok(0xff == ret, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret);
+  ret = fputc(0xffffffff,tempfh);
+  ok(0xff == ret, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret);
+  fclose(tempfh);
+
+  tempfh = fopen(tempf,"rb");
+  ret = fputc(0,tempfh);
+  ok(EOF == ret, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
+  fclose(tempfh);
+
+  unlink(tempf);
+}
+
+static void test_flsbuf( void )
+{
+  char* tempf;
+  FILE *tempfh;
+  int  ret;
+  int  bufmode;
+  int  bufmodes[] = {_IOFBF,_IONBF};
+
+  tempf=_tempnam(".","wne");
+  for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
+  {
+    tempfh = fopen(tempf,"wb");
+    setvbuf(tempfh,NULL,bufmodes[bufmode],2048);
+    ret = _flsbuf(0,tempfh);
+    ok(0 == ret, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
+                         bufmodes[bufmode], 0, ret);
+    ret = _flsbuf(0xff,tempfh);
+    ok(0xff == ret, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
+                         bufmodes[bufmode], 0, ret);
+    ret = _flsbuf(0xffffffff,tempfh);
+    ok(0xff == ret, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
+                         bufmodes[bufmode], 0, ret);
+    fclose(tempfh);
+  }
+
+  tempfh = fopen(tempf,"rb");
+  ret = _flsbuf(0,tempfh);
+  ok(EOF == ret, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
+  fclose(tempfh);
+
+  unlink(tempf);
+}
+
 static void test_fgetwc( void )
 {
 #define LLEN 512
@@ -1061,6 +1118,8 @@ START_TEST(file)
     test_readmode(FALSE); /* binary mode */
     test_readmode(TRUE);  /* ascii mode */
     test_fgetc();
+    test_fputc();
+    test_flsbuf();
     test_fgetwc();
     test_ctrlz();
     test_file_put_get();
-- 
1.5.5.4




More information about the wine-patches mailing list