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
fix: Prevent rare overwrite of wrong line in Reading mode & results blocks #1663
fix: Prevent rare overwrite of wrong line in Reading mode & results blocks #1663
Conversation
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.
Thank you. The change is a lot simpler than I expected.
I'm curious why you used identicalTo
and not equality check of the original source line?
Both are fine - I'm just wondering what you spotted that I didn't! 😄
4bd096c
to
97497a7
Compare
Currently, the unique identifier (UID) for tasks are a source file, a section, and an index into the array of global-filter-matching tasks within that section. This diff does not change how tasks are uniquely identified. However, it does implement a guard when overwriting a task in some file to ensure the line that is being overwritten has similar content to the line that was used to create the Task in the first place. The world "similar" is used since the line is permitted to have different content, so long as that line represents a Task with identical data as per the definition of Task.identicalTo
97497a7
to
6b7cefa
Compare
Currently, the permissible format for a task on a line of the users' source file is different than what we render. Therefore, comparing the Tasks is the way to go! Screen.Recording.2023-02-14.at.10.47.43.PM.mov |
path: originalTask.path, | ||
precedingHeader: originalTask.precedingHeader, | ||
sectionStart: originalTask.sectionStart, | ||
sectionIndex: originalTask.sectionIndex, |
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.
I'm going to leave this as it is, but I feel that because these checks use values from the original task instead of the new line, they are very weak and do not add any value to the checking for whether the two task lines match.
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.
using these fields from originalTask makes sense.
we locate the line with path, sectionStart, and sectionIndex, therefore those are part of the new Task that gets created from the line. The only cause for concern here is precedingHeader as that may change in the interim.
is there something you're saying that I'm not understanding?
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.
is there something you're saying that I'm not understanding?
Maybe, or maybe vice versa. Maybe I'm not understanding. And unfortunately the earlier conversations are all hidden now, by being resolved.
I thought that the idea behind calling task.identicalTo()
was to check more fields in the two tasks, but it looks to me like one of the tasks is populated from fields from the other task.
So it looks to me like task.identicalTo()
is giving a false sense of extra value - and it would probably be safer and clearer to check task.originalMarkdown
.
I may later refactor the new code out to a helper function in a file that does not import Obsidian types, to be able to write some tests for it, and explore the behaviour better.
The only cause for concern here is precedingHeader as that may change in the interim.
Yes, that is a concern.
Another concern is a change behind the scenes somehow from this:
## header
- [ ] task 1
- [ ] task 2 - I am the task that will be completed
to this:
## header
- [ ] task 1
- [ ] some new task that was added - so the old 2nd task is now the 3rd task in the section
- [ ] task 2 - I am the task that will be completed
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.
have you read my comment here: #1663 (comment)?
it contains the answer to the purpose of task.identitcalTo
I could elaborate more if needed.
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.
Yes I did see that. I should have said that I don’t understand why the rendering of the task matters.
The line being overwritten should be identical to the original text read in to the task being edited.
If the two markdown lines differ in any way, including order of fields, something has gone wrong as the file has been edited in some way behind Tasks’ back, and I do not feel it is safe to overwrite the line.
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.
Ah! Yes, in that case .originalMarkdown
is the way to go. I was being lenient with my change and allowing even for the order of the fields to change. I think a factor at play was that I sort of forgot that we had .originalMarkdown
😅
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.
Hi @BluBloos Thank you, and I totally understand... I'll change it to use .originalMarkdown
when I tweak the error message...
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.
Thank you very much!
Aagghghh. obsidian-tasks/src/Commands/ToggleDone.ts Lines 77 to 91 in 6567449
|
What's the concern with the code you referenced? It's not really clear to me ... |
Ah, sorry, I may have shortened it down too much, maybe more context from the surrounding code is needed... It is in a function that looks to me like it is over-writing task lines in files without checking whether the correct line is being overwritten. |
I see. in this case I think checking if the correct line is being overwritten is not-so-relevant as |
Brilliant. Thank you! |
Description
In essence, when a task is toggled by the Tasks plugin, the code reads the file that contains the task to find the line to update.
Under certain circumstances (listed below) it may find and update the wrong line, overwriting a different task.
This change makes Tasks check, when in Reading mode and in Tasks results blocks, that the line it is about to overwrite actually contains the expected text. If it does not, the toggling action will halt, and a message will be written to the console.
Note: This change does not affect Live Preview. That is planned to be addressed in a separate pull request.
All of the detail needed should be in the commit messages.
Update: The key bit is:
Motivation and Context
As an interim fix to #688 so that the users' data is not overwritten.
Some additional notes:
ex)
How has this been tested?
Locally and within my personal vault.
I've tested the fix for the particular issue plus normal usage.
Screenshots (if appropriate)
Screen.Recording.2023-02-14.at.8.02.42.AM.mov
Types of changes
Changes visible to users:
fix
- non-breaking change which fixes an issue)feat
- non-breaking change which adds functionality)feat!!
orfix!!
- fix or feature that would cause existing functionality to not work as expected)docs
- improvements to any documentation content)vault
- improvements to the Tasks-Demo sample vault)Internal changes:
refactor
- non-breaking change which only improves the design or structure of existing code, and making no changes to its external behaviour)test
- additions and improvements to unit tests and the smoke tests)chore
- examples include GitHub Actions, issue templates)Checklist
yarn run lint
.Terms