From 227989f3e96d846023d36a797931875c57fbae6d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 12 Sep 2009 22:40:42 +0000 Subject: [PATCH] Write correct number of bytes in wxFile::Write(wxString). This function was broken for conversions using more than one byte per character (e.g. UTF-16 or UTF-32) and also even for UTF-8 for strings containing NUL bytes as it used strlen() to determine the number of bytes to write out instead of using the really needed number. Fix this by using the wxCharBuffer::length() method which always returns the correct value. Also add a wxFile unit test verifying that it can correctly read back a string written using any of UTF-8, UTF-16 or UTF-32. Closes #11192. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61898 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/file.cpp | 2 +- tests/Makefile.in | 4 ++ tests/file/filetest.cpp | 95 ++++++++++++++++++++++++++++++++++++++ tests/makefile.bcc | 4 ++ tests/makefile.gcc | 4 ++ tests/makefile.vc | 4 ++ tests/makefile.wat | 4 ++ tests/test.bkl | 1 + tests/test_test.dsp | 4 ++ tests/test_vc7_test.vcproj | 3 ++ tests/test_vc8_test.vcproj | 4 ++ tests/test_vc9_test.vcproj | 4 ++ 12 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 tests/file/filetest.cpp diff --git a/src/common/file.cpp b/src/common/file.cpp index 1063e45293..8aaa9ac05e 100644 --- a/src/common/file.cpp +++ b/src/common/file.cpp @@ -312,7 +312,7 @@ bool wxFile::Write(const wxString& s, const wxMBConv& conv) if ( !buf ) return false; - const size_t size = strlen(buf); // FIXME: use buf.length() when available + const size_t size = buf.length(); return Write(buf, size) == size; } diff --git a/tests/Makefile.in b/tests/Makefile.in index ac17216617..fcc3680ff7 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -65,6 +65,7 @@ TEST_OBJECTS = \ test_evthandler.o \ test_timertest.o \ test_exec.o \ + test_filetest.o \ test_filekind.o \ test_filenametest.o \ test_filesystest.o \ @@ -378,6 +379,9 @@ test_timertest.o: $(srcdir)/events/timertest.cpp $(TEST_ODEP) test_exec.o: $(srcdir)/exec/exec.cpp $(TEST_ODEP) $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/exec/exec.cpp +test_filetest.o: $(srcdir)/file/filetest.cpp $(TEST_ODEP) + $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/file/filetest.cpp + test_filekind.o: $(srcdir)/filekind/filekind.cpp $(TEST_ODEP) $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/filekind/filekind.cpp diff --git a/tests/file/filetest.cpp b/tests/file/filetest.cpp new file mode 100644 index 0000000000..dc3c286691 --- /dev/null +++ b/tests/file/filetest.cpp @@ -0,0 +1,95 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/file/filetest.cpp +// Purpose: wxFile unit test +// Author: Vadim Zeitlin +// Created: 2009-09-12 +// RCS-ID: $Id$ +// Copyright: (c) 2009 Vadim Zeitlin +/////////////////////////////////////////////////////////////////////////////// + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "testprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_FILE + +#include "wx/file.h" + +#include "testfile.h" + +// ---------------------------------------------------------------------------- +// test class +// ---------------------------------------------------------------------------- + +class FileTestCase : public CppUnit::TestCase +{ +public: + FileTestCase() { } + +private: + CPPUNIT_TEST_SUITE( FileTestCase ); + CPPUNIT_TEST( RoundTripUTF8 ); + CPPUNIT_TEST( RoundTripUTF16 ); + CPPUNIT_TEST( RoundTripUTF32 ); + CPPUNIT_TEST_SUITE_END(); + + void RoundTripUTF8() { DoRoundTripTest(wxConvUTF8); } + void RoundTripUTF16() { DoRoundTripTest(wxMBConvUTF16()); } + void RoundTripUTF32() { DoRoundTripTest(wxMBConvUTF32()); } + + void DoRoundTripTest(const wxMBConv& conv); + + wxDECLARE_NO_COPY_CLASS(FileTestCase); +}; + +// ---------------------------------------------------------------------------- +// CppUnit macros +// ---------------------------------------------------------------------------- + +CPPUNIT_TEST_SUITE_REGISTRATION( FileTestCase ); +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileTestCase, "FileTestCase" ); + +// ---------------------------------------------------------------------------- +// tests implementation +// ---------------------------------------------------------------------------- + +void FileTestCase::DoRoundTripTest(const wxMBConv& conv) +{ + TestFile tf; + + const wxString data = "Hello\0UTF"; + + { + wxFile fout(tf.GetName(), wxFile::write); + CPPUNIT_ASSERT( fout.IsOpened() ); + + CPPUNIT_ASSERT( fout.Write(data, conv) ); + } + + { + wxFile fin(tf.GetName(), wxFile::read); + CPPUNIT_ASSERT( fin.IsOpened() ); + + const wxFileOffset len = fin.Length(); + wxCharBuffer buf(len); + CPPUNIT_ASSERT_EQUAL( len, fin.Read(buf.data(), len) ); + + wxWCharBuffer wbuf(conv.cMB2WC(buf)); +#if wxUSE_UNICODE + CPPUNIT_ASSERT_EQUAL( data, wbuf ); +#else // !wxUSE_UNICODE + CPPUNIT_ASSERT + ( + memcmp(wbuf, L"Hello\0UTF", data.length()*sizeof(wchar_t)) == 0 + ); +#endif // wxUSE_UNICODE/!wxUSE_UNICODE + } +} + +#endif // wxUSE_FILE diff --git a/tests/makefile.bcc b/tests/makefile.bcc index bba737c6c9..77e128c2ba 100644 --- a/tests/makefile.bcc +++ b/tests/makefile.bcc @@ -49,6 +49,7 @@ TEST_OBJECTS = \ $(OBJS)\test_evthandler.obj \ $(OBJS)\test_timertest.obj \ $(OBJS)\test_exec.obj \ + $(OBJS)\test_filetest.obj \ $(OBJS)\test_filekind.obj \ $(OBJS)\test_filenametest.obj \ $(OBJS)\test_filesystest.obj \ @@ -410,6 +411,9 @@ $(OBJS)\test_timertest.obj: .\events\timertest.cpp $(OBJS)\test_exec.obj: .\exec\exec.cpp $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\exec\exec.cpp +$(OBJS)\test_filetest.obj: .\file\filetest.cpp + $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\file\filetest.cpp + $(OBJS)\test_filekind.obj: .\filekind\filekind.cpp $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\filekind\filekind.cpp diff --git a/tests/makefile.gcc b/tests/makefile.gcc index 9519ea74ae..08f2802a74 100644 --- a/tests/makefile.gcc +++ b/tests/makefile.gcc @@ -41,6 +41,7 @@ TEST_OBJECTS = \ $(OBJS)\test_evthandler.o \ $(OBJS)\test_timertest.o \ $(OBJS)\test_exec.o \ + $(OBJS)\test_filetest.o \ $(OBJS)\test_filekind.o \ $(OBJS)\test_filenametest.o \ $(OBJS)\test_filesystest.o \ @@ -391,6 +392,9 @@ $(OBJS)\test_timertest.o: ./events/timertest.cpp $(OBJS)\test_exec.o: ./exec/exec.cpp $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\test_filetest.o: ./file/filetest.cpp + $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\test_filekind.o: ./filekind/filekind.cpp $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< diff --git a/tests/makefile.vc b/tests/makefile.vc index 151f5f18e8..92c2b269a2 100644 --- a/tests/makefile.vc +++ b/tests/makefile.vc @@ -42,6 +42,7 @@ TEST_OBJECTS = \ $(OBJS)\test_evthandler.obj \ $(OBJS)\test_timertest.obj \ $(OBJS)\test_exec.obj \ + $(OBJS)\test_filetest.obj \ $(OBJS)\test_filekind.obj \ $(OBJS)\test_filenametest.obj \ $(OBJS)\test_filesystest.obj \ @@ -493,6 +494,9 @@ $(OBJS)\test_timertest.obj: .\events\timertest.cpp $(OBJS)\test_exec.obj: .\exec\exec.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\exec\exec.cpp +$(OBJS)\test_filetest.obj: .\file\filetest.cpp + $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\file\filetest.cpp + $(OBJS)\test_filekind.obj: .\filekind\filekind.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\filekind\filekind.cpp diff --git a/tests/makefile.wat b/tests/makefile.wat index c5bddaca9a..bdaba4b6d0 100644 --- a/tests/makefile.wat +++ b/tests/makefile.wat @@ -270,6 +270,7 @@ TEST_OBJECTS = & $(OBJS)\test_evthandler.obj & $(OBJS)\test_timertest.obj & $(OBJS)\test_exec.obj & + $(OBJS)\test_filetest.obj & $(OBJS)\test_filekind.obj & $(OBJS)\test_filenametest.obj & $(OBJS)\test_filesystest.obj & @@ -448,6 +449,9 @@ $(OBJS)\test_timertest.obj : .AUTODEPEND .\events\timertest.cpp $(OBJS)\test_exec.obj : .AUTODEPEND .\exec\exec.cpp $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< +$(OBJS)\test_filetest.obj : .AUTODEPEND .\file\filetest.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< + $(OBJS)\test_filekind.obj : .AUTODEPEND .\filekind\filekind.cpp $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< diff --git a/tests/test.bkl b/tests/test.bkl index 37a7cdb7f4..80c71cce9b 100644 --- a/tests/test.bkl +++ b/tests/test.bkl @@ -40,6 +40,7 @@ events/evthandler.cpp events/timertest.cpp exec/exec.cpp + file/filetest.cpp filekind/filekind.cpp filename/filenametest.cpp filesys/filesystest.cpp diff --git a/tests/test_test.dsp b/tests/test_test.dsp index b131c95274..031f525889 100644 --- a/tests/test_test.dsp +++ b/tests/test_test.dsp @@ -321,6 +321,10 @@ SOURCE=.\filesys\filesystest.cpp # End Source File # Begin Source File +SOURCE=.\file\filetest.cpp +# End Source File +# Begin Source File + SOURCE=.\fontmap\fontmaptest.cpp # End Source File # Begin Source File diff --git a/tests/test_vc7_test.vcproj b/tests/test_vc7_test.vcproj index d3d49db757..cc848ea3bf 100644 --- a/tests/test_vc7_test.vcproj +++ b/tests/test_vc7_test.vcproj @@ -668,6 +668,9 @@ + + diff --git a/tests/test_vc8_test.vcproj b/tests/test_vc8_test.vcproj index a554a86dc3..e8fccf8fbf 100644 --- a/tests/test_vc8_test.vcproj +++ b/tests/test_vc8_test.vcproj @@ -967,6 +967,10 @@ RelativePath=".\filesys\filesystest.cpp" > + + diff --git a/tests/test_vc9_test.vcproj b/tests/test_vc9_test.vcproj index 9753505ef0..55021dba01 100644 --- a/tests/test_vc9_test.vcproj +++ b/tests/test_vc9_test.vcproj @@ -939,6 +939,10 @@ RelativePath=".\filesys\filesystest.cpp" > + + -- 2.45.2