wxWidget wxWebView调用Find带wxWEBVIEW_FIND_HIGHLIGHT_RESULT出现段错误
问题触发原因
- 核心根因是wxWidgets 3.0.x及部分3.1.x版本的GTK/WebKitGTK后端wxWebView的Find接口实现存在内存越界漏洞:接口内部统计匹配结果的缓冲区未做边界校验,当页面文本长度超过预设阈值时,会直接访问超出分配范围的内存地址,触发段错误。
- 现有代码存在隐性时序问题:wxWebView的SetPage是异步执行的,调用后页面并不会立刻完成加载渲染。小体积页面加载速度快,刚好在调用Find前完成渲染所以运行正常;大体积页面加载耗时更长,调用Find时渲染层数据结构还未完成初始化,也会触发非法内存访问崩溃。
修复/规避方案
- 方案1:升级wxWidgets版本
该问题在wxWidgets 3.1.5及之后的稳定版本已被官方修复,直接升级依赖库版本即可解决,无需修改业务代码。 - 方案2:修复调用时序(必做,不管升不升级都建议调整)
不要在SetPage调用后立刻执行Find操作,绑定wxEVT_WEBVIEW_LOADED事件,等页面加载完成的回调触发后再执行搜索逻辑,示例代码如下:
// 绑定页面加载完成事件 webView->Bind(wxEVT_WEBVIEW_LOADED, [=](wxWebViewEvent& event) { long lMatchCount = webView->Find("a", wxWEBVIEW_FIND_HIGHLIGHT_RESULT); if(lMatchCount == wxNOT_FOUND){ wxMessageBox("Search not found"); }else{ wxLogMessage("Matches: %ld ", lMatchCount); } }); // 再执行SetPage操作 webView->SetPage(/*你的HTML内容*/, "");
- 方案3:无法升级版本时的绕开方案
如果受环境限制无法升级wxWidgets版本,可以放弃原生Find接口,通过调用页面JS的window.find()方法实现搜索逻辑,绕开存在漏洞的原生实现,示例代码如下:
webView->Bind(wxEVT_WEBVIEW_LOADED, [=](wxWebViewEvent& event) { wxString js = R"( let matchCount = 0; while(window.find("a", false, false, true)) { matchCount++; } matchCount; )"; wxString res = webView->RunScript(js); long lMatchCount = 0; res.ToLong(&lMatchCount); // 后续处理匹配结果 });
内容的提问来源于stack exchange,提问作者Amod Gokhale
相关产品推荐
相关产品推荐

