Bug 306226
| Summary: | Fix -Wlifetime-safety-permissive warning in XPathNodeSet::findRootNode() | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | David Kilzer (:ddkilzer) <ddkilzer> |
| Component: | XML | Assignee: | David Kilzer (:ddkilzer) <ddkilzer> |
| Status: | RESOLVED FIXED | ||
| Severity: | Normal | CC: | webkit-bug-importer |
| Priority: | P2 | Keywords: | InRadar |
| Version: | WebKit Nightly Build | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
| See Also: | https://bugs.webkit.org/show_bug.cgi?id=306244 | ||
David Kilzer (:ddkilzer)
The compiler warning `-Wlifetime-safety-permissive` was triggered in `findRootNode()` when building with upstream clang in Source/WebCore/xml/XPathNodeSet.cpp:
```
OpenSource/Source/WebCore/xml/XPathNodeSet.cpp:191:20: error: object whose reference is captured does not live long enough [-Werror,-Wlifetime-safety-permissive]
191 | node = parent.get();
| ^~~~~~
OpenSource/Source/WebCore/xml/XPathNodeSet.cpp:191:31: note: destroyed here
191 | node = parent.get();
| ^
OpenSource/Source/WebCore/xml/XPathNodeSet.cpp:190:32: note: later used here
190 | while (RefPtr parent = node->parentNode())
| ^~~~
```
The issue is in the while loop where `RefPtr parent` is declared in the condition, causing it to be destroyed and reconstructed on every iteration. After `node = parent.get()` executes, `parent` is destroyed, but then `node->parentNode()` is called in the next iteration with `node` potentially pointing to a destroyed object.
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
David Kilzer (:ddkilzer)
The specific lifetime issue is fixed by changing from a `while` loop to a `for` loop pattern to avoid recreating the `RefPtr parent` variable on each iteration.
Current problematic code:
```
while (RefPtr parent = node->parentNode())
node = parent.get();
```
Proposed fix:
```
for (RefPtr parent = current->parentNode(); parent; parent = current->parentNode())
current = WTF::move(parent);
```
Why this works:
The `for` loop declares `parent` once and reuses it via assignment, maintaining object lifetime across iterations. When `current->parentNode()` is called in the increment expression, the previous `parent` value is still alive, preventing the lifetime safety issue.
Additional changes to support this fix:
1. Return `RefPtr<Node>` instead of `Node*` for proper lifetime management
2. Use `RefPtr<Node> current` throughout to maintain object lifetime
3. Replace `&node->document()` with `current->protectedDocument()` (returns `Ref<Document>`)
4. Properly transfer ownership with `WTF::move(parent)`
Radar WebKit Bug Importer
<rdar://problem/168880148>
David Kilzer (:ddkilzer)
Pull request: https://github.com/WebKit/WebKit/pull/57221
EWS
Committed 306240@main (7a9af69f9b93): <https://commits.webkit.org/306240@main>
Reviewed commits have been landed. Closing PR #57221 and removing active labels.