fix: escape </script> in webview content; add structured logging - #125
Conversation
Patch files can contain </script> (e.g. when patching HTML files). JSON.stringify does not escape this, so the HTML parser would close the <script> tag early, causing a silent syntax error that prevents all JavaScript from executing — resulting in a blank view with non-functional tab and button clicks. Fix: escape '</' as '<\/' (and '<!--' as '<\!--') in the serialised content before embedding it in the script block. These replacements keep the JavaScript string value identical at runtime while being opaque to the HTML parser. Also: - Add logInfo/logWarn methods alongside the existing logError - Add webview-side logInfo/logWarn/logError helpers that forward to the VS Code output channel via postMessage - Handle 'log' and 'warn' message types in resolveCustomTextEditor - Wrap contentChanged apply-edit in try/catch with logging - Add lifecycle logging: editor open, asset resolution, view mode changes, document updates, theme changes, and all renderDiff failure paths - Guard renderDiff against a null diffOutput element Co-authored-by: unknowIfGuestInDream <57802425+unknowIfGuestInDream@users.noreply.github.com>
</script> in webview content; add structured logging
|
@copilot 请完整校验插件代码,解决问题 |
…afe bindEvents; catch init errors Co-authored-by: unknowIfGuestInDream <57802425+unknowIfGuestInDream@users.noreply.github.com>
经过完整代码审查,本次提交(
如果以上修复后问题仍然存在,请提供所使用补丁文件的前几行内容,以便进一步排查。 |
|
@copilot |
…ient script Co-authored-by: unknowIfGuestInDream <57802425+unknowIfGuestInDream@users.noreply.github.com>
Co-authored-by: unknowIfGuestInDream <57802425+unknowIfGuestInDream@users.noreply.github.com>
Found and fixed the real root cause. The entire webview client script is embedded inside a TypeScript template literal, so single Fix: reworded the comment and changed the replacement to |
|
@copilot |
Move the ~350-line webview client script and all CSS out of the TypeScript template literal into standalone media/patchViewer.js and media/patchViewer.css loaded via webview.asWebviewUri(). The browser now receives them verbatim, so "\n"/"</script>" escape sequences can no longer be mangled by the literal — fixing the blank Visual tab and unresponsive Content tab. Initial patch content is passed via a non-executable JSON data block with every "<" escaped as \u003c, so "</script>" payloads cannot abort the viewer. Tests now validate the shipped script parses and that content round-trips exactly. Co-authored-by: unknowIfGuestInDream <57802425+unknowIfGuestInDream@users.noreply.github.com>
…test Remove the nonce from the non-executable `type="application/json"` initial-content block (CSP script-src does not apply to data blocks) and document why. Clarify the test comment explaining why the "<" -> "\u003c" escaping makes the extraction regex safe against "</script>" payloads. Co-authored-by: unknowIfGuestInDream <57802425+unknowIfGuestInDream@users.noreply.github.com>
已重构内容显示实现。根因是整个 webview 客户端脚本(约 350 行 JS)和 CSS 都被内联在 TypeScript 模板字符串里, 现在把 webview 脚本和样式抽取为独立静态文件 已端到端验证:Visual 正常渲染 diff、Content 标签可点击切换、拆分/统一视图切换、文档实时更新重渲染均正常;编译、lint 与全部 7 个测试通过。见提交 7ac69e4。 |
…ication in `postMessage` handler' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Signed-off-by: 梦里不知身是客 <liang.tang.cx@gmail.com>
|
@copilot |
Co-authored-by: unknowIfGuestInDream <57802425+unknowIfGuestInDream@users.noreply.github.com>
Co-authored-by: unknowIfGuestInDream <57802425+unknowIfGuestInDream@users.noreply.github.com>
你指出的正是根因。 已在 23a3857 修复:
diff2html 的使用方式( |
Patch files that touch HTML/template files frequently contain the literal string
</script>. Embedding such content via bareJSON.stringify()inside a<script>block lets the HTML parser close the tag early, silently aborting the entire inline script — no event listeners are registered, nothing renders, and all buttons are dead (as shown in the screenshot above).Changes
Critical fix — safe content serialisation (
getHtmlForWebview)JSON.stringifydoes not escape</. Added post-processing before the content is spliced into the template:<\/is semantically identical in JavaScript — the escaping is purely for the HTML parser.Structured logging
logInfo()andlogWarn()toPatchEditorProvideralongside the existinglogError(); all write timestamped entries to the Patch Reader output channel.logInfo/logWarn/logErrorhelpers that forward viavscode.postMessage; the extension now handles'log'and'warn'message types in addition to'error'.renderDiff().contentChangedapply-edit path wrapped intry/catchwith logging.renderDiff()guards against anulldiffOutputelement instead of throwing uncaught.