From 73052bd1063b5c268b6888e3b3e56a060491b370 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 30 Jun 2014 01:00:16 +0000 Subject: [PATCH] Check for conversion failure correctly in wx[F]File::Write(). Check for the length of the buffer to determine whether the conversion failed instead of checking whether it's NULL because this is currently never the case because of the code in wxString::AsCharBuf() which returns "" and not NULL in case of conversion failure. This at least eliminates silent data loss when saving data that can't be converted to the current locale encoding. Closes #16348. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_3_0_BRANCH@76793 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + src/common/ffile.cpp | 23 +++++++++++++++++------ src/common/file.cpp | 23 +++++++++++++++++------ 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index fd699e54be..5436bc93f3 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -579,6 +579,7 @@ Major new features in this release All: +- Fix silent data loss in wx[F]File::Write(wxString) if conversion fails. - Make wxString::FromCDouble() work when the global C++ locale is not the C one. wxMSW: diff --git a/src/common/ffile.cpp b/src/common/ffile.cpp index 64dc25e3f1..962242ebe8 100644 --- a/src/common/ffile.cpp +++ b/src/common/ffile.cpp @@ -153,17 +153,28 @@ size_t wxFFile::Write(const void *pBuf, size_t nCount) bool wxFFile::Write(const wxString& s, const wxMBConv& conv) { - const wxWX2MBbuf buf = s.mb_str(conv); - if ( !buf ) - return false; + // Writing nothing always succeeds -- and simplifies the check for + // conversion failure below. + if ( s.empty() ) + return true; + + const wxWX2MBbuf buf = s.mb_str(conv); #if wxUSE_UNICODE - const size_t size = buf.length(); + const size_t size = buf.length(); + + if ( !size ) + { + // This means that the conversion failed as the original string wasn't + // empty (we explicitly checked for this above) and in this case we + // must fail too to indicate that we can't save the data. + return false; + } #else - const size_t size = s.length(); + const size_t size = s.length(); #endif - return Write(buf, size) == size; + return Write(buf, size) == size; } bool wxFFile::Flush() diff --git a/src/common/file.cpp b/src/common/file.cpp index b2a5aca736..9d5571d5ef 100644 --- a/src/common/file.cpp +++ b/src/common/file.cpp @@ -356,17 +356,28 @@ size_t wxFile::Write(const void *pBuf, size_t nCount) bool wxFile::Write(const wxString& s, const wxMBConv& conv) { - const wxWX2MBbuf buf = s.mb_str(conv); - if ( !buf ) - return false; + // Writing nothing always succeeds -- and simplifies the check for + // conversion failure below. + if ( s.empty() ) + return true; + + const wxWX2MBbuf buf = s.mb_str(conv); #if wxUSE_UNICODE - const size_t size = buf.length(); + const size_t size = buf.length(); + + if ( !size ) + { + // This means that the conversion failed as the original string wasn't + // empty (we explicitly checked for this above) and in this case we + // must fail too to indicate that we can't save the data. + return false; + } #else - const size_t size = s.length(); + const size_t size = s.length(); #endif - return Write(buf, size) == size; + return Write(buf, size) == size; } // flush