Home Dashboard Directory Help
Search

tr1 regex crashes in debug builds due to illegal use of iterator by Leo Davidson


Status: 

Closed
 as Fixed Help for as Fixed


1
0
Sign in
to vote
Type: Bug
ID: 645641
Opened: 2/21/2011 12:54:08 AM
Access Restriction: Public
0
Workaround(s)
view
0
User(s) can reproduce this bug

Description

This issue affects both VS2008 and VS2010.

The following code will cause a crash in Debug builds:

    std::wstring strRE(L"[\\");
    std::tr1::wregex rx(strRE);

The crash is due to this code in the regex header:

    bool _Parser<_FwdIt, _Elem, _RxTraits>::_CharacterClassEscape(bool _Addit)
    {    // check for character class escape
    typename _RxTraits::char_class_type _Cls;
    _FwdIt _Ch0 = _Pat;
    if ((_Cls = _Traits.lookup_classname(_Pat, ++_Ch0)) == 0)
        return (false);

On entry, _Pat is an iterator pointing at the end of the string. i.e. _Pat == strRE.end(). The code creates a copy of the iterator and then advances it past the end of the string. In debug builds that triggers a C-runtime invalid parameter exception.

i.e. _Pat points to the end of the string (the null if it was a traditional C-style string) while _Ch0 points one past that location (to random memory).

(It looks like _Pat is dereferenced within lookup_classname, too; I thought dereferencing the end of a string was illegal under the stricter iterator rules in VS2010 but maybe I'm confused with something else.)

The crash does not happen in Release builds as they apparently don't check the string iterator bounds in this situation.

Proposed fix:

You could fix the code above by changing the lookup_classname line to:

    if (_Pat == _End || (_Cls = _Traits.lookup_classname(_Pat, ++_Ch0)) == 0)
        return (false);

Note that the quoted code is from the VS2008 headers. The VS2010 headers may be slightly different. The same bug is present in both versions, however.

Workaround:

    std::wstring strRE(L"[\\");
    std::tr1::wregex rx(strRE.c_str());

That code avoids the crash, since it passes a c-style string instead of a std::wstring, and that avoids using checked iterators. The wregex constructor now correctly throws a regex_error exception (since the regex is invalid) rather than crashing the program entirely.

The code still advances a pointer past the null, and then passes a pair of iterators (pointers) where the first is on the null and the second is beyond it (i.e. completely invalid), but nothing ever dereferences the invalid pointer so it gets away with it. Still a bug, IMO, but one that doesn't cause a crash anymore.

Hopefully the workaround helps people since it seems fixes for bugs like this take years to be released and are never provided for people who cannot move everything to the latest IDE version when the fix finally comes out. :(
Details
Sign in to post a comment.
Posted by Leo Davidson on 3/15/2011 at 1:49 AM
Thanks Stephan!
Posted by Microsoft on 3/14/2011 at 4:39 PM
Hi,

Thanks for reporting this bug. We really appreciated your detailed analysis. We've fixed this bug, and the fix will be available in VC11. We also found and fixed a separate bug affecting this code:

string s("\\");
regex r(s, regex::basic);

If you have any further questions, feel free to E-mail me at stl@microsoft.com .

Stephan T. Lavavej
Visual C++ Libraries Developer
Posted by Microsoft on 2/21/2011 at 10:58 PM
Thank you for submitting feedback on Visual Studio 2010 and .NET Framework. Your issue has been routed to the appropriate VS development team for review. We will contact you if we require any additional information.
Posted by Microsoft on 2/21/2011 at 1:12 AM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.