wxWidgets 2.8.7, wxMAC_USE_CORE_GRAPHICS=1, wxUSE_UNICODE=1, Xcode
2.5, MacBook Pro (Intel), OS X 10.5.4
I'm initializing a Data Browser (wxListCtrl) with Unicode text, and
I'm getting this crash:
Program received signal: "EXC_BAD_ACCESS".
Call stack:
#0 0xffff0f14 in objc_msgSend_rtp
#1 0x1137cdb0 in ?? at listbox.h:119
#2 0x95308373 in __CFStringCreateImmutableFunnel3
#3 0x95309491 in CFStringCreateWithCharacters
#4 0x0f281fac in wxMacCFStringHolder::Assign at cfstring.cpp:658
#5 0x0f1b5f10 in wxMacDataBrowserListCtrlControl::DrawItem at
listctrl_mac.cpp:2677
#6 0x0f1b5875 in
wxMacDataBrowserListCtrlControl::DataBrowserDrawItemProc at
listctrl_mac.cpp:2567
I've traced the source of the problem to an invalid Unicode character
due to a bug in my own code. However, I don't think that an invalid
character should cause this kind of a crash.
Here's where the problem is triggered:
#0 0x0f27bd18 in encode_utf16 at strconv.cpp:109
#1 0x0f27d376 in wxMBConvUTF16LE::FromWChar at strconv.cpp:1141
#2 0x0f27c31f in wxMBConv::WC2MB at strconv.cpp:346
#3 0x0f281f46 in wxMacCFStringHolder::Assign at cfstring.cpp:654
What happens is, when encode_utf16 sees the invalid character, it
punts and returns wxCONV_FAILED, which gets propagated up as the
return value of wxMBConvUTF16straight::FromWChar and wxMBConv::WC2MB.
This value happens to be ((size_t)-1), or 0xFFFFFFFF, or 4294967295 in
decimal. Unfortunately, wxMacCFStringHolder::Assign doesn't check for
this special value, and assumes that wxMBConv::WC2MB has correctly
returned the length of the string in characters. So, it asks the
system to allocate a CFString with 4 billion bytes, which of course
fails.
One obvious fix would be to have wxMacCFStringHolder::Assign check for
wxCONV_FAILED and bail out. However, it seems to me that a better
failure mode for encode_utf16, wxMBConvUTF16LE::FromWChar,
wxMBConv::WC2MB, etc., would be to throw an exception rather than to
return -1. Then it would be more obvious what the problem is, and it
could be handled more cleanly.
(Of course, one could argue that CFStringCreateWithCharacters should
also fail more gracefully, but that's a post for a different forum.)
A cursory examination of the wxWidgets source reveals that this
problem is present in many other locations, including
wxMacCoreGraphicsContext::DrawText, wxMacCGContext::DrawText,
wxMacMLTEControl::SetTXNData, and wxTextDataObject::GetDataSize (the
latter of which may propagate the error further). Most of these
functions are calling malloc with the returned size, which is likely
to return NULL and lead to other problems. Interestingly, some other
functions, such as wxMacMLTEControl::GetStringValue, do account for a
wxCONV_FAILED return from wxMBConv::MB2WC, and raise a wxASSERT_MSG as
appropriate, but this check seems to be missing for most calls to
wxMBConv::WC2MB.
Thanks,
Dan
_______________________________________________
wx-users mailing list
[email protected]
http://lists.wxwidgets.org/mailman/listinfo/wx-users
On Thu, 17 Jul 2008 15:43:16 -0500 Dan Korn <[email protected]> wrote:
DK> Here's where the problem is triggered:
DK>
DK> #0 0x0f27bd18 in encode_utf16 at strconv.cpp:109
DK> #1 0x0f27d376 in wxMBConvUTF16LE::FromWChar at strconv.cpp:1141
DK> #2 0x0f27c31f in wxMBConv::WC2MB at strconv.cpp:346
DK> #3 0x0f281f46 in wxMacCFStringHolder::Assign at cfstring.cpp:654
DK>
DK> What happens is, when encode_utf16 sees the invalid character, it
DK> punts and returns wxCONV_FAILED, which gets propagated up as the
DK> return value of wxMBConvUTF16straight::FromWChar and wxMBConv::WC2MB.
DK> This value happens to be ((size_t)-1), or 0xFFFFFFFF, or 4294967295 in
DK> decimal. Unfortunately, wxMacCFStringHolder::Assign doesn't check for
DK> this special value,
It definitely should.
DK> One obvious fix would be to have wxMacCFStringHolder::Assign check for
DK> wxCONV_FAILED and bail out.
It would be great if you could contribute a patch (and ideally a test case
to tests/strings/unicode.cpp which is fixed by it). It's probably trivial
to fix but I can't test it myself.
DK> However, it seems to me that a better failure mode for encode_utf16,
DK> wxMBConvUTF16LE::FromWChar, wxMBConv::WC2MB, etc., would be to throw
DK> an exception rather than to return -1.
wxWidgets hadn't been designed around error handling using exceptions and
it's exceedingly difficult to add exceptions to the existing
exception-unsafe code. Without even mentioning that all these functions are
part of public API and so changing them would require changing all the user
code calling them too.
Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
_______________________________________________
wx-users mailing list
[email protected]
http://lists.wxwidgets.org/mailman/listinfo/wx-users