Opened 10 years ago

Closed 5 years ago

#7435 closed Bugs (fixed)

Crash with format using UTF16 strings on MacOS X

Reported by: Franz Detro <franz.detro@…> Owned by: James E. King, III
Milestone: Component: format
Version: Boost 1.51.0 Severity: Problem
Keywords: Cc:

Description

Due to cross-platform issues with Microsoft Windows, we are using std::strings with unsigned shorts as UTF16 strings.

We experience crashes when using boost::format in combination with these strings.

Please find attach a simple fix which solves this issue for us. We are using this code since some years on Windows and Unix, too, without any negative side-effects.

It would be great if you could double-check this change and commit it to future boost versions.

Attachments (2)

format-imbue.diff (855 bytes ) - added by Franz Detro <franz.detro@…> 10 years ago.
internals.hpp.patch (1.2 KB ) - added by Joachim Faulhaber 10 years ago.

Download all attachments as: .zip

Change History (8)

by Franz Detro <franz.detro@…>, 10 years ago

Attachment: format-imbue.diff added

comment:1 by Steven Watanabe, 10 years ago

Looking around in the code it appears that stream_format_state::apply_on itself calls oss.imbue. It isn't clear to me why this is crashing, but it seems to me that if apply_on fails if the locale isn't set, the simplest solution is to set the locale first rather than setting it in put only for to overwrite it immediately.

comment:2 by Franz Detro <franz.detro@…>, 10 years ago

The fix wasn't done by me, but I know that the crash happens when boost::format is used during app startup (e.g. during the initialization of static members). This may be related to the usage of unsigned short as character type or due to initialization order problems.

If you have a better way to fix the issue, we're fine with this.

comment:3 by Joachim Faulhaber, 10 years ago

At the tagged code line, the program crashes. I does not crash, if os.imbue(*loc_default); is called before.

boost/format/internals.hpp(104):
    template<class Ch, class Tr>
    void stream_format_state<Ch,Tr>:: apply_on (basic_ios & os,
                      boost::io::detail::locale_t * loc_default) const {
        // set the state of this stream according to our params
        if(width_ != -1)
            os.width(width_);
        if(precision_ != -1)
            os.precision(precision_);
        if(fill_ != 0)
            os.fill(fill_); //<== crashes here
        os.flags(flags_);
        os.clear(rdstate_);
        os.exceptions(exceptions_);
#if !defined(BOOST_NO_STD_LOCALE)
        if(loc_)
            os.imbue(loc_.get());
        else if(loc_default)
            os.imbue(*loc_default);
#else
        (void) loc_default; // keep compiler quiet if we don't support locales
#endif        
    }

So we only need to move the bottom code (between #if and #end) to the beginning of the function. This change is done in the attached patch-file internals.hpp.patch. If there are no objections against this patch, I will apply it.

Last edited 10 years ago by Joachim Faulhaber (previous) (diff)

by Joachim Faulhaber, 10 years ago

Attachment: internals.hpp.patch added

comment:4 by James E. King, III, 5 years ago

Owner: changed from Samuel Krempp to James E. King, III
Status: newassigned

This was fixed in the 1.60.0 release: https://github.com/boostorg/format/commit/6fd5847729f07d6f31d37ac3b2d37e78b6689997

Once I have maintainer access I will uupdate the milestone accordingly.

comment:5 by James E. King, III, 5 years ago

Milestone: To Be DeterminedBoost 1.61.0

comment:6 by James E. King, III, 5 years ago

Milestone: Boost 1.61.0
Resolution: fixed
Status: assignedclosed

I can't set the milestone appropriately, but it was fixed some time ago, so I am marking it fixed.

Note: See TracTickets for help on using tickets.