fix: Prevent segfault from dangling image pointers
Some checks failed
Build and Release / build (linux, ubuntu-latest) (push) Has been cancelled
Build and Release / build (macos, macos-latest) (push) Has been cancelled
Build and Release / release (push) Has been cancelled

Critical bugfix for async image loading:

Problem:
- When images are downloading and user navigates to new page,
  the old DocumentTree is destroyed
- Image download completion handlers still have pointers to old DomNodes
- Accessing freed memory caused SIGSEGV

Solution:
1. Cancel all image downloads when starting new page load
2. Validate DomNode pointers before use (check if still in current tree)
3. Safely skip images for nodes that no longer exist

This fixes crashes on sites like docs.nbtca.space where navigation
can happen while images are loading.

Tested: No more crashes, basic functionality intact
This commit is contained in:
m1ngsama 2025-12-28 14:33:35 +08:00
parent 45b340798d
commit 70f20a370e

View file

@ -218,6 +218,9 @@ public:
// 启动异步页面加载 // 启动异步页面加载
void start_async_load(const std::string& url, bool force_refresh = false) { void start_async_load(const std::string& url, bool force_refresh = false) {
// 取消任何正在进行的图片下载 (避免访问旧树的节点)
http_client.cancel_all_images();
// 检查缓存 // 检查缓存
auto cache_it = page_cache.find(url); auto cache_it = page_cache.find(url);
bool use_cache = !force_refresh && cache_it != page_cache.end() && bool use_cache = !force_refresh && cache_it != page_cache.end() &&
@ -326,7 +329,19 @@ public:
if (img_data.is_valid()) { if (img_data.is_valid()) {
// 设置到对应的DomNode // 设置到对应的DomNode
DomNode* img_node = static_cast<DomNode*>(task.user_data); DomNode* img_node = static_cast<DomNode*>(task.user_data);
// 验证节点仍然有效 (仍在当前树的images列表中)
bool node_valid = false;
if (img_node) { if (img_node) {
for (const auto* node : current_tree.images) {
if (node == img_node) {
node_valid = true;
break;
}
}
}
if (node_valid) {
img_node->image_data = img_data; img_node->image_data = img_data;
need_relayout = true; need_relayout = true;