From eaab373af7827d5445bfb5171b1133914ae2e2ee Mon Sep 17 00:00:00 2001 From: Jason Spieth Date: Tue, 2 Dec 2008 19:45:13 +0000 Subject: [PATCH] ICU-6592 Integrated patch X-SVN-Rev: 25036 --- icu4c/source/io/ustdio.c | 14 ++++-- icu4c/source/test/iotest/filetst.c | 77 ++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/icu4c/source/io/ustdio.c b/icu4c/source/io/ustdio.c index 3958f1393a..e193249e6b 100644 --- a/icu4c/source/io/ustdio.c +++ b/icu4c/source/io/ustdio.c @@ -300,6 +300,7 @@ u_file_write_flush(const UChar *chars, /* Set up conversion parameters */ UErrorCode status = U_ZERO_ERROR; const UChar *mySource = chars; + const UChar *mySourceBegin; const UChar *mySourceEnd; char charBuffer[UFILE_CHARBUFFER_SIZE]; char *myTarget = charBuffer; @@ -334,6 +335,7 @@ u_file_write_flush(const UChar *chars, /* Perform the conversion in a loop */ do { + mySourceBegin = mySource; /* beginning location for this loop */ status = U_ZERO_ERROR; if(f->fConverter != NULL) { /* We have a valid converter */ ucnv_fromUnicode(f->fConverter, @@ -345,8 +347,14 @@ u_file_write_flush(const UChar *chars, flushIO, &status); } else { /*weiv: do the invariant conversion */ - u_UCharsToChars(mySource, myTarget, count); - myTarget += count; + int32_t convertChars = (int32_t) (mySourceEnd - mySource); + if (convertChars > UFILE_CHARBUFFER_SIZE) { + convertChars = UFILE_CHARBUFFER_SIZE; + status = U_BUFFER_OVERFLOW_ERROR; + } + u_UCharsToChars(mySource, myTarget, convertChars); + mySource += convertChars; + myTarget += convertChars; } numConverted = (int32_t)(myTarget - charBuffer); @@ -357,7 +365,7 @@ u_file_write_flush(const UChar *chars, numConverted, f->fFile); - written += numConverted; + written += (int32_t) (mySource - mySourceBegin); } myTarget = charBuffer; } diff --git a/icu4c/source/test/iotest/filetst.c b/icu4c/source/test/iotest/filetst.c index c13dea5514..117d470bff 100644 --- a/icu4c/source/test/iotest/filetst.c +++ b/icu4c/source/test/iotest/filetst.c @@ -18,6 +18,7 @@ #include "unicode/uloc.h" #include +#include const char *STANDARD_TEST_FILE = "iotest-c.txt"; @@ -1430,6 +1431,78 @@ static void TestUnicodeFormat(void) #endif } +static void TestFileWriteRetval(const char * a_pszEncoding) { + UChar * buffer; + UFILE * myFile; + int32_t count; + int32_t expected = 10000; /* test with large data to test internal buffer looping */ + UChar testChar = 0xBEEF; + + if (!*a_pszEncoding || 0 == strcmp(a_pszEncoding, "ASCII")) { + testChar = 'A'; /* otherwise read test will fail */ + } + + buffer = (UChar*) malloc(expected * sizeof(UChar)); + if (!buffer) { + log_err("Out of memory\n"); + return; + } + + /* write */ + myFile = u_fopen(STANDARD_TEST_FILE, "w", NULL, a_pszEncoding); + if (!myFile) { + free(buffer); + log_err("Test file can't be opened for write\n"); + return; + } + u_memset(buffer, testChar, expected); + count = u_file_write(buffer, expected, myFile); + u_fclose(myFile); + if (count != expected) { + free(buffer); + log_err("u_file_write returned incorrect number of characters written\n"); + return; + } + + free(buffer); + buffer = NULL; + + /* read */ + myFile = u_fopen(STANDARD_TEST_FILE, "r", NULL, a_pszEncoding); + if (!myFile) { + log_err("Test file can't be opened for read\n"); + return; + } + for (count = 0; count < expected; ++count) { + if (u_fgetc(myFile) != testChar) { + log_err("u_fgetc returned unexpected character\n"); + u_fclose(myFile); + return; + } + } + if (u_fgetc(myFile) != U_EOF) { + log_err("u_fgetc did not return expected EOF\n"); + u_fclose(myFile); + return; + } + u_fclose(myFile); +} + +static void TestFileWriteRetvalUTF16(void) { + TestFileWriteRetval("UTF-16"); +} + +static void TestFileWriteRetvalUTF8(void) { + TestFileWriteRetval("UTF-8"); +} + +static void TestFileWriteRetvalASCII(void) { + TestFileWriteRetval("ASCII"); +} + +static void TestFileWriteRetvalNONE(void) { + TestFileWriteRetval(""); +} U_CFUNC void addFileTest(TestNode** root) { @@ -1444,6 +1517,10 @@ addFileTest(TestNode** root) { addTest(root, &TestfgetsNewLineCount, "file/TestfgetsNewLineCount"); addTest(root, &TestFgetsLineBuffering, "file/TestFgetsLineBuffering"); addTest(root, &TestCodepage, "file/TestCodepage"); + addTest(root, &TestFileWriteRetvalUTF16, "file/TestFileWriteRetvalUTF16"); + addTest(root, &TestFileWriteRetvalUTF8, "file/TestFileWriteRetvalUTF8"); + addTest(root, &TestFileWriteRetvalASCII, "file/TestFileWriteRetvalASCII"); + addTest(root, &TestFileWriteRetvalNONE, "file/TestFileWriteRetvalNONE"); #if !UCONFIG_NO_FORMATTING addTest(root, &TestCodepageAndLocale, "file/TestCodepageAndLocale"); addTest(root, &TestFprintfFormat, "file/TestFprintfFormat");