From 54dfc341ce49d6f10466925d901be5ced25c5975 Mon Sep 17 00:00:00 2001 From: ARATA Mizuki Date: Fri, 19 Feb 2016 10:46:26 +0900 Subject: [PATCH 1/4] Add a test for wxFile::ReadAll() with an embedded NUL See #16490. --- tests/file/filetest.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/file/filetest.cpp b/tests/file/filetest.cpp index 31870164c3..fdad2d8e4a 100644 --- a/tests/file/filetest.cpp +++ b/tests/file/filetest.cpp @@ -116,6 +116,16 @@ void FileTestCase::DoRoundTripTest(const wxMBConv& conv) wxString dataReadBack(buf, conv, len); CPPUNIT_ASSERT_EQUAL( data, dataReadBack ); } + + { + wxFile fin(tf.GetName(), wxFile::read); + CPPUNIT_ASSERT( fin.IsOpened() ); + + wxString dataReadBack; + CPPUNIT_ASSERT( fin.ReadAll(&dataReadBack, conv) ); + + CPPUNIT_ASSERT_EQUAL( data, dataReadBack ); + } } #endif // wxUSE_UNICODE From 6e678e3a85b1808490dcacdb1eae0f7ee7b2f9f8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 6 Dec 2017 03:23:26 +0100 Subject: [PATCH 2/4] Improve output of test failures for unprintable characters Show non-printable characters when comparing strings more clearly if the comparison fails, this is notably useful for strings containing NULs as they were previously completely lost. --- include/wx/catch_cppunit.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/include/wx/catch_cppunit.h b/include/wx/catch_cppunit.h index 22ebcf12f9..66e660b158 100644 --- a/include/wx/catch_cppunit.h +++ b/include/wx/catch_cppunit.h @@ -73,6 +73,32 @@ namespace Catch return wxString(ucr).ToStdString(wxConvUTF8); } }; + + // While this conversion already works due to the existence of the stream + // insertion operator for wxString, define a custom one making it more + // obvious when strings containing non-printable characters differ. + template <> + struct StringMaker + { + static std::string convert(const wxString& wxs) + { + std::string s; + s.reserve(wxs.length()); + for ( wxString::const_iterator i = wxs.begin(); + i != wxs.end(); + ++i ) + { +#if wxUSE_UNICODE + if ( !iswprint(*i) ) + s += wxString::Format("\\u%04X", *i).ToStdString(); + else +#endif // wxUSE_UNICODE + s += *i; + } + + return s; + } + }; } // Use a different namespace for our mock ups of the real declarations in From 140d6fea88121a252e1e690b2e5ede43474af02f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 6 Dec 2017 03:38:39 +0100 Subject: [PATCH 3/4] Add wxString ctor from wxScopedCharBuffer and wxMBConv This is more convenient and less error prone than using the existing ctor taking char pointer and length as the buffer contains both. Also add the corresponding assign() overload for consistency. See #16490. --- include/wx/string.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/wx/string.h b/include/wx/string.h index b80998cc44..a4e682b8ff 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -1162,6 +1162,9 @@ public: wxString(const wxScopedWCharBuffer& buf) { assign(buf.data(), buf.length()); } + wxString(const wxScopedCharBuffer& buf, const wxMBConv& conv) + { assign(buf, conv); } + // NB: this version uses m_impl.c_str() to force making a copy of the // string, so that "wxString(str.c_str())" idiom for passing strings // between threads works @@ -2539,6 +2542,13 @@ public: { return assign(str.AsString()); } wxString& assign(const wxScopedCharBuffer& str) { return assign(str.data(), str.length()); } + wxString& assign(const wxScopedCharBuffer& buf, const wxMBConv& conv) + { + SubstrBufFromMB str(ImplStr(buf.data(), buf.length(), conv)); + m_impl.assign(str.data, str.len); + + return *this; + } wxString& assign(const wxScopedWCharBuffer& str) { return assign(str.data(), str.length()); } wxString& assign(const wxCStrData& str, size_t len) From 436d27baf09ecc666d1d3666c4bb54824821fe30 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 6 Dec 2017 03:40:02 +0100 Subject: [PATCH 4/4] Use correct length for the string returned from wxFile::ReadAll() This corrects f75387850b9672481d4d449403d973d92a8d3675 and just uses the newly added assign() overload taking the buffer directly: as the buffer already knows its length, this makes it unnecessary to pass it separately. Closes #16490. --- src/common/file.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/common/file.cpp b/src/common/file.cpp index 9da9aba608..0e976273dc 100644 --- a/src/common/file.cpp +++ b/src/common/file.cpp @@ -281,8 +281,7 @@ bool wxFile::ReadAll(wxString *str, const wxMBConv& conv) length -= nread; } - wxString strTmp(buf, conv, length); - str->swap(strTmp); + str->assign(buf, conv); return true; }