-
Notifications
You must be signed in to change notification settings - Fork 2.6k
fix: preserve HTML entities in diff/search/replace operations #8071
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,7 +11,6 @@ import { ToolUse, RemoveClosingTag, AskApproval, HandleError, PushToolResult } f | |
| import { formatResponse } from "../prompts/responses" | ||
| import { fileExistsAtPath } from "../../utils/fs" | ||
| import { RecordSource } from "../context-tracking/FileContextTrackerTypes" | ||
| import { unescapeHtmlEntities } from "../../utils/text-normalization" | ||
| import { EXPERIMENT_IDS, experiments } from "../../shared/experiments" | ||
|
|
||
| export async function applyDiffToolLegacy( | ||
|
|
@@ -25,9 +24,8 @@ export async function applyDiffToolLegacy( | |
| const relPath: string | undefined = block.params.path | ||
| let diffContent: string | undefined = block.params.diff | ||
|
|
||
| if (diffContent && !cline.api.getModel().id.includes("claude")) { | ||
| diffContent = unescapeHtmlEntities(diffContent) | ||
| } | ||
| // HTML entities should be preserved exactly as provided | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good change to preserve HTML entities. However, I notice that executeCommandTool.ts still uses unescapeHtmlEntities. Is this intentional? Shell commands might need actual characters like < and > for redirection, but it would be good to document why command execution needs different handling than file operations. |
||
| // to ensure accurate diff matching and prevent unintended changes | ||
|
|
||
| const sharedMessageProps: ClineSayTool = { | ||
| tool: "appliedDiff", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,7 +11,6 @@ import { ToolUse, RemoveClosingTag, AskApproval, HandleError, PushToolResult } f | |
| import { formatResponse } from "../prompts/responses" | ||
| import { fileExistsAtPath } from "../../utils/fs" | ||
| import { RecordSource } from "../context-tracking/FileContextTrackerTypes" | ||
| import { unescapeHtmlEntities } from "../../utils/text-normalization" | ||
| import { parseXmlForDiff } from "../../utils/xml" | ||
| import { EXPERIMENT_IDS, experiments } from "../../shared/experiments" | ||
| import { applyDiffToolLegacy } from "./applyDiffTool" | ||
|
|
@@ -421,13 +420,9 @@ Original error: ${errorMessage}` | |
| let successCount = 0 | ||
| let formattedError = "" | ||
|
|
||
| // Pre-process all diff items for HTML entity unescaping if needed | ||
| const processedDiffItems = !cline.api.getModel().id.includes("claude") | ||
| ? diffItems.map((item) => ({ | ||
| ...item, | ||
| content: item.content ? unescapeHtmlEntities(item.content) : item.content, | ||
| })) | ||
| : diffItems | ||
| // HTML entities should be preserved exactly as provided | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment style here is slightly different from the one in applyDiffTool.ts (2 lines vs 3 lines). Consider using consistent formatting across files for better readability. |
||
| // to ensure accurate diff matching and prevent unintended changes | ||
| const processedDiffItems = diffItems | ||
|
|
||
| // Apply all diffs at once with the array-based method | ||
| const diffResult = (await cline.diffStrategy?.applyDiff(originalContent, processedDiffItems)) ?? { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,7 +13,6 @@ import { stripLineNumbers, everyLineHasLineNumbers } from "../../integrations/mi | |
| import { getReadablePath } from "../../utils/path" | ||
| import { isPathOutsideWorkspace } from "../../utils/pathUtils" | ||
| import { detectCodeOmission } from "../../integrations/editor/detect-omission" | ||
| import { unescapeHtmlEntities } from "../../utils/text-normalization" | ||
| import { DEFAULT_WRITE_DELAY_MS } from "@roo-code/types" | ||
| import { EXPERIMENT_IDS, experiments } from "../../shared/experiments" | ||
|
|
||
|
|
@@ -83,9 +82,8 @@ export async function writeToFileTool( | |
| newContent = newContent.split("\n").slice(0, -1).join("\n") | ||
| } | ||
|
|
||
| if (!cline.api.getModel().id.includes("claude")) { | ||
| newContent = unescapeHtmlEntities(newContent) | ||
| } | ||
| // HTML entities should be preserved exactly as provided | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good to see HTML entities being preserved here as well. This ensures consistency across all file write operations. |
||
| // to ensure content is written exactly as intended | ||
|
|
||
| // Determine if the path is outside the workspace | ||
| const fullPath = relPath ? path.resolve(cline.cwd, removeClosingTag("path", relPath)) : "" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add a test case that specifically reproduces the original issue from #8069? The current test verifies that entities are preserved, but it would be helpful to have a test that demonstrates the actual bug scenario (e.g., applying a diff with < that was incorrectly becoming <).