[Git][wxwidgets/wxwidgets][master] Fix out-of-bounds read on trailing backslash in wxRegEx::Replace()

1 view
Skip to first unread message

Vadim Zeitlin (@_VZ_)

unread,
Jun 1, 2026, 8:32:59 AM (6 days ago) Jun 1
to wx-commi...@googlegroups.com

Vadim Zeitlin pushed to branch master at wxWidgets / wxWidgets

Commits:

  • 9b0eb807
    by dxbjavid at 2026-06-01T14:09:19+02:00
    Fix out-of-bounds read on trailing backslash in wxRegEx::Replace()
    
    wxRegExImpl::Replace() scans replacement.c_str() and does *++p after a
    backslash. When the replacement ends in a lone backslash, that reads the
    terminating NUL, the else branch appends it, and the loop's p++ then
    steps one byte past the NUL so the *p condition reads out of bounds.
    
    Keep a trailing backslash verbatim and stop before the increment.
    
    Add a test checking that this doesn't result in ASAN errors any more.
    
    Closes #26541.
    

2 changed files:

Changes:

  • src/common/regex.cpp
    ... ... @@ -1158,6 +1158,13 @@ int wxRegExImpl::Replace(wxString *text,
    1158 1158
                             index = (size_t)wxStrtoul(p, &end, 10);
    
    1159 1159
                             p = end - 1; // -1 to compensate for p++ in the loop
    
    1160 1160
                         }
    
    1161
    +                    else if ( !*p )
    
    1162
    +                    {
    
    1163
    +                        // trailing backslash: keep it verbatim and stop here so
    
    1164
    +                        // the loop's p++ doesn't read past the terminating NUL
    
    1165
    +                        textNew += wxT('\\');
    
    1166
    +                        break;
    
    1167
    +                    }
    
    1161 1168
                         //else: backslash used as escape character
    
    1162 1169
                     }
    
    1163 1170
                     else if ( *p == wxT('&') )
    

  • tests/regex/wxregextest.cpp
    ... ... @@ -161,6 +161,10 @@ TEST_CASE("wxRegEx::Replace", "[regex][replace]")
    161 161
         CheckReplace(patn, "123foo456foo", "\\0\\0", "123foo456foo456foo", 1);
    
    162 162
         CheckReplace(patn, "foo123foo123", "bar", "barbar", 2);
    
    163 163
         CheckReplace(patn, "foo123_foo456_foo789", "bar", "bar_bar_bar", 3);
    
    164
    +
    
    165
    +    // A replacement string ending with a lone backslash used to read one byte
    
    166
    +    // past the end of the buffer; the backslash is now kept verbatim.
    
    167
    +    CheckReplace(patn, "foo123", "bar\\", "bar\\", 1);
    
    164 168
     }
    
    165 169
     
    
    166 170
     TEST_CASE("wxRegEx::QuoteMeta", "[regex][meta]")
    


View it on GitLab.
You're receiving this email because of your account on gitlab.com. Manage all notifications · Help Notification message regarding https://gitlab.com/wxwidgets/wxwidgets/-/commit/9b0eb807cd03eb9ba517b8d5371c91d811a7682b at 1780317148

Reply all
Reply to author
Forward
0 new messages