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.
| ... | ... | @@ -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('&') )
|
| ... | ... | @@ -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