Commit 9ab2645
authored
[20_13] Do not add duplicated values to copy_always to avoid stack overflow
<!-- Thank you for your contribution! -->
## What
Add check before adding new values to `edit_interface_rep::copy_always`
in function `edit_interface_rep::apply_changes()`.
New rectangle will be added to `copy_always` if `copy_always` is
empty/nil or the first item of `copy_always` is not equal to newly added
value.
## Why
Since `apply_changes()` will be called when the window receives any
event, `copy_always` will become very large and cause stack overflow
when it's cleared.
The `copy_always` is a linked list and when it's cleared, the destructor
is called from head to tail recursively, causing stack overflow.
## How to test your changes?
That's the potential risk: I can only test it on Windows with few
scenarios, I don't know the result in Linux, Mac.
already run `xmake run --yes -vD --group=tests` and `xmake run --yes -vD
--group=integration_tests`
The investigations below are all in Windows environment.
### Where is the code to clear `copy_always`?
In `edit_interface_rep::scroll_to()` and
`edit_interface_rep::set_extents()`, by using `copy_always = rectangles
()`.
### When will `copy_always` be cleared?
`scroll_to()` is called when the cursor is moved out of current view.
I can't add breakpoint in `set_extents()`, I don't know when will it
will be called.
### What's the purpose of `copy_always`?
The comment says it's used for wiping out cursor.
However I think it doesn't do anything now.
I comment out the code that uses it, get nothing wrong.
But removing it is more dangerous.
### Where is `copy_always` used?
In `edit_interface_rep::draw_pre()` and
`edit_interface_rep::draw_with_shadow()`.
In `draw_pre()`, it will go through all rectangles in `copy_always` and
call `win->put_shadow()`, but it doesn't draw anything at all.
Because in `qt_renderer_rep::put_shadow()`, `painter ==
static_cast<qt_renderer_rep*> (ren)->painter` is true and returns
directly.
In `draw_with_shadow()`, it's only used if `gui_interrupted()` returns
true, but `gui_interrupted()` doesn't return true in my machine.
These shadow functions are related to the double buffering, the behavior
may be different in other OS.
In summary, I don't think it's necessary to store all the old rectangles
in `copy_always`.
The latest ones `ocr`(old cursor) and `ncr`(new cursor) should be enough
for cursor drawing stuff.1 parent 0a2d37f commit 9ab2645
1 file changed
+7
-3
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
832 | 832 | | |
833 | 833 | | |
834 | 834 | | |
835 | | - | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
836 | 838 | | |
837 | 839 | | |
838 | 840 | | |
839 | 841 | | |
840 | 842 | | |
841 | 843 | | |
842 | | - | |
843 | | - | |
| 844 | + | |
| 845 | + | |
| 846 | + | |
| 847 | + | |
844 | 848 | | |
845 | 849 | | |
846 | 850 | | |
| |||
0 commit comments