Bug: Self-move-assignment in RE2::Set and FilteredRE2 causes use-after-destroy
- Dominant language
- C++
- Stars
- 9.8k
- Forks
- 1.2k
- PR merge metrics
- No merged PRs in 30d
Description
## Description
The move assignment operators in `RE2::Set` and `FilteredRE2` use a destroy-then-placement-new pattern:
```cpp
RE2::Set& RE2::Set::operator=(Set&& other) {
this->~Set();
(void) new (this) Set(std::move(other));
return *this;
}
```
This is unsafe when `this == &other` (self-move-assignment). The destructor runs first, which calls `Decref()` on internal `Regexp*` pointers and frees resources. Then the move constructor reads from the already-destroyed object. This is undefined behavior and can lead to double-free.
Self-move-assignment can happen through aliased references. For example:
```cpp
std::vector v = ...;
v[i] = std::move(v[j]); // if i == j
```
## Affected Code
- `re2/set.cc:52-56` (`RE2::Set::operator=(Set&&)`)
- `re2/filtered_re2.cc:45-48` (`FilteredRE2::operator=(FilteredRE2&&)`)
I can open PR to submit a fix.
Contributor guide
Assessment
This issue has not been assessed yet.