Copy-paste a multimeasure rest on another one causes corruption after undo

• Feb 12, 2017 - 12:02
Reported version
P0 - Critical
S1 - Blocker

GIT commit ca4d9e9 / Windows7

1) Load this file: new test corruption.mscz
2) Generate parts (new all -> Ok)
3) View part
4) Range selection of the first MM rest (including the whole note, or not: same issue)
5) Copy-paste into the second MM rest
6) Undo -> press "M"

Result: corruption


This one occurs in last December.

- It works on this nightly of December 9 ("branch master"): 0d26707. And with the current 3.0 dev.

- It fails of this nightly of December 12 ("branch 2.0.1"), the first one - or one of the first - which was released if I recall well: e99be61

Difficult to well see between the "ex" 2.0.4, and the 2.1 dev., and the branch master, but possibly this commit might have introduced this issue ? :…

For fix: #141496: Copy-paste multimeasure rests containing a full measure, or not after cuting, causes corruption/crash

Status (old) active fixed
Status active fixed
Tags View Changes

Cannot reproduce the case. All rests are on the correct places.
Screen Shot 2018-04-06 at 11.53.35 AM.png

The other issue is that "M" shortcut doesn't work on my machine with MuseScoreNightly-2018-04-05-2004-master-82e81eb.dmg (MacOS).

Status (old) fixed active
Status fixed active

After rebooting Mac, I can reproduce the issue in the main score, not in the part view. Also, after the corruption happens, closing the scoreleads to the crash.

Again appear.
1. Empty score
2. Create 4 quarter notes in the first measure
3. Switch on MM rests
4. Select 1st measure
5. Press "R"
6. Select 1st measure again
7. Press "R"
8. Press "R" again
Result: last measure becomes weird
9. Undo until switching MM rests off happens
Result: Score is corrupted.


I'll add a bit to this discussion.
First, the discussed problem can lead not only to score corruption but also to a crash. To reproduce it do the following steps:
1) Create a score like it is described in steps 1—3 in the comment by Anatoly-os.
2) Select only three notes in range instead of the whole measure.
3) Press R two times.
Musescore will then crash.

Second, I am not really sure which is a good way to fix this. Score::pasteStaff function range-selects the pasted content after it has been actually pasted. However:
1) It is not possible to correctly determine what to select by finding the bounding segments by tick values (as it is currently done) since there are some types of segments which have zero tick length and still can be selected (e.g. Clefs).
2) Multi-measure rests are rebuilt a bit later during the layout so any selection that intersects the previous multi-measure rest range will behave unreliably (MM-rest layout process involves some segments deletion, changes in their structure etc.). This can lead to the selection being in invalid state (or at least in a state which was not intended and which is impossible to reproduce via a user interface), and this is probably the reason for the observed peculiarities in selection behavior such as disappearing selection when the pasted area is inside the previous location of the MM-rest and the described crashes.

So it is not currently clear for me how to ensure that the selection state is correct after all those operations without introducing changes to the code which are larger than it could be desired.

Status PR created fixed

Fixed in branch master, commit fa2c795d07

fix #173381, part 1: handle selection after MMRest reconstruction

Make selection made after paste operation be actually updated after
re-layout and, hence, after reconstructing multi-measure rests.
This is needed as reconstructing MMRests changes segments structure
of the score which leads selection to be in invalid state.
This commit adds also some tweaks to selection boundaries to work
around the fixed bug (which would not work alone without the
previously described changes).

Fixed in branch master, commit 30332b1aba

fix #173381, part 2: assign correct duration to the pasted rests

The added condition is needed as TDuration::fraction() returns
invalid fraction (0/0) if duration type is whole-measure.
Still that behavior for TDuration can be considered correct as
TDuration object does not have any information on its context,
including measure's length.