Repository navigation
fix(core): reject an edit whose strings differ only in line ending style - #47088
devYRPauli wants to merge 2 commits into
Conversation
The identity guard runs on the raw input at line 135. The tool converts both strings to the file's line ending at lines 169-170, 34 lines later. Two strings that differ only in line ending style pass the raw guard and become the same text. The replacement is then the identity function. findOccurrences still returns one match, so the tool asks for edit approval, writes the file back unchanged, and reports one replacement with an empty patch. Run the same check again after the conversion. The raw check stays where it is. It fails before the file read and before any permission prompt, which is still the right place for the case it catches.
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
|
The following comment was made by an LLM, it may be inaccurate: Related PRs Found#46849 - This is NOT a duplicate but rather a companion fix on a different branch. As noted in the PR description:
Both PRs address the same root cause (rejecting edits where |
|
The body has The The copy that ran is the one on The |
The test drove a CRLF file only. The defect does not depend on the file's own line ending. An LF file with oldString spelled CRLF converts to the same text as an LF newString, so it takes the same no-op path. Measured on this head with the guard removed and the LF case asserted first: status completed, replacements 1, an empty patch, "Edited unix.txt (1 replacement)", and the file unchanged on disk.
|
Automated PR Cleanup Thank you for contributing to opencode. Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions. This PR was closed because it matched the following cleanup criteria:
PRs created within the last month are not affected by this cleanup. If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate. Thanks again for taking the time to contribute. |
|
This still reproduces on v2 at 2c33922. A focused harness executing the current edit function against LF and CRLF files reports one replacement, requests approval and writes unchanged content. The post-normalization guard rejects both cases before approval or writing. Could you reopen this PR? It targets v2; #46849 targets dev. |
Issue for this PR
Closes #45927
Type of change
What does this PR do?
packages/core/src/tool/plugin/edit.tsrejects an edit whereoldStringequalsnewString. That check runs on the raw input at line 135. The tool converts both strings to the file's line ending at lines 169-170.Two strings that differ only in line ending style pass the raw check. After the conversion they hold the same text, so the replacement does nothing.
findOccurrencesstill returns one match.The tool then asks for edit approval, writes the file back unchanged, and reports one replacement.
Measured on
v2at f94eefa, through the registered tool. The file is CRLF and holdsbefore\r\nrest\r\n. The call passesoldString: "before\r\nrest"andnewString: "before\nrest".The model reads one replacement and believes the edit landed. An LF file gives the same result, because the conversion rewrites a CRLF
oldStringto\nas well.This PR runs the same check again after the conversion. The raw check stays where it is. It fails before the file read and before any permission prompt, which is the right place for the case it catches.
After the change the tool returns an error and writes nothing.
#46849 fixes the same defect on
dev, where the tool lives atpackages/core/src/tool/edit.ts. The two diffs touch different files, so neither one covers the other branch.How did you verify your code works?
The new test is
rejects an edit whose strings differ only in line ending styleinpackages/core/test/tool-edit.test.ts. It drives the registered tool throughexecuteToolagainst a real CRLF file. It checks the error, the file content, the permission calls and the writes.The test fails on
v2before the change. The failure reportsstatus: "completed"withreplacements: 1and an empty patch.bun test test/tool-edit.test.tsfrompackages/core: 17 pass, 0 fail.bun run testfrompackages/core: 4040 pass, 39 skip, 3 fail. The failures arePluginSupervisor reloadtwice andWatcher lifecycleonce. All three fail the same way onorigin/v2with this branch reverted.bun typecheckfrompackages/coreis clean.bun run lint:effect-simplifications,oxlintandprettier --checkare clean on both files.I also moved the new guard below
permission.assertas a mutation check. The test failed, which shows the guard runs before the approval prompt.Screenshots / recordings
Not a UI change.
Checklist