google / google/re2

Bug: Self-move-assignment in RE2::Set and FilteredRE2 causes use-after-destroy

Open
#615 1 comment 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.