Skip to content
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 GH#16363: Accidentals in chord symbols rendered incorrectly when using custom XML file #22541

Merged
merged 1 commit into from
Jul 25, 2024

Conversation

Jojo-Schmitz
Copy link
Contributor

Resolves: #16363

@Jojo-Schmitz Jojo-Schmitz force-pushed the broken-chord-symbols branch 3 times, most recently from bdab1b0 to 0690feb Compare April 23, 2024 13:43
if (!code.startsWith(u"0x") && !code.startsWith(u"0") && !code.startsWith('&') && !code.endsWith(';')) {
// fix broken chord lists, see https://github.com/musescore/MuseScore/issues/16363
code = u"0x" + code;
}
bool ok = true;
char32_t val = code.toUInt(&ok, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If code.startsWith('&') is true, then this would fail anyway. Does this case occur at all?
If not, let's not check for it, because that only makes the code noisy
If yes, we should add proper handling for that case.

However, I'm not very confident whether I like this approach; it means that our String::number method behaves differently from QString::number, which seems a potential source of confusion.
Wouldn't the problem be fixed instantly if you do

Suggested change
char32_t val = code.toUInt(&ok, 0);
char32_t val = code.toUInt(&ok, 16);

and drop all other changes? Or is it not certain that it will be a base16 number?

Copy link
Contributor Author

@Jojo-Schmitz Jojo-Schmitz Apr 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If code.startsWith('&') is true, then this would fail anyway. Does this case occur at all? If not, let's not check for it, because that only makes the code noisy If yes, we should add proper handling for that case.

We don't have full control over the content of a chords.xml, it could contain ♭ (@MarcSabatella even recommeded the latter in the issue as a workaround, #16363 (comment)).

The toUInt(..., 0) would fail on it (as would a toUInt(..., 16)), but return the string unchanged, as far as I understand.

Be generous in what you accept, but strict in what you generate ;-) (and that's why toUInt(..., 0) exists)

However, I'm not very confident whether I like this approach; it means that our String::number method behaves differently from QString::number, which seems a potential source of confusion. Wouldn't the problem be fixed instantly if you do
...
and drop all other changes? Or is it not certain that it will be a base16 number?

The problem isn't that toUInt()doesn't return a hex number, but that this number as a string doesn't look like one to the writer because of the missing "0x".
Also, as said above, it might be an octal number od a string with an HTML entity, we don't have full control over the content of these files.

But we can leave the String::number() as it was and just do it like in the 1st commit and prepend the "0x" there,
after all we do know though that we write as hex there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can understand your concerns reg. different behavoir of String::number() vs. QString::number(), so reverted that 2nd commit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And we may not need the read fix at all, as save/close/open fixes the issue too, its just nice to have, isn't it?

Copy link
Contributor Author

@Jojo-Schmitz Jojo-Schmitz Apr 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW: this would work too:

                        int base = 0; // guess, based on content
                        if (!code.startsWith(u"0") && !(code.startsWith(u"&#") && code.endsWith(u";"))) {
                            // fix broken chord lists, see https://github.com/musescore/MuseScore/issues/16363
                            base = 16; // force hex
                        }
                        bool ok = true;
                        char32_t val = code.toUInt(&ok, base);

And it does read that ♭ too, not a © though, toUInt() (or rather rather std::strtol()) probably just ignores all the non-alpha-numerical chars and (rightfully) interprets the rest as decimal.

@Jojo-Schmitz Jojo-Schmitz force-pushed the broken-chord-symbols branch 6 times, most recently from 7fcc2b6 to 8b69c04 Compare April 29, 2024 10:07
@Jojo-Schmitz
Copy link
Contributor Author

Came up again in https://musescore.org/en/node/364348

@Jojo-Schmitz
Copy link
Contributor Author

Came up again in https://musescore.org/en/node/365531

@Jojo-Schmitz
Copy link
Contributor Author

Seems time to get this one merged as well?

@cbjeukendrup
Copy link
Contributor

Yes, but I want/need to look into this a bit more closely, because I haven't quite understood exactly what's going on. At the moment I don't have time for that, but in a week, the academic year is over, which should improve that 😉

@Jojo-Schmitz
Copy link
Contributor Author

Jojo-Schmitz commented Jun 23, 2024

OK, then there's an alternative fix now too ;-)
(Actually pushed by accident, but hey, just let me know whether it is good or not)

@Jojo-Schmitz
Copy link
Contributor Author

Came up again in https://musescore.org/en/node/365770

@Jojo-Schmitz
Copy link
Contributor Author

Yes, but I want/need to look into this a bit more closely, because I haven't quite understood exactly what's going on. At the moment I don't have time for that, but in a week, the academic year is over, which should improve that 😉

Would now be the time? ;-)

@cbjeukendrup
Copy link
Contributor

It is, undeniably. I had to gather some courage but I'm on it right now :)

@cbjeukendrup
Copy link
Contributor

cbjeukendrup commented Jul 25, 2024

Alright, I found the problem. Literally the only change that's needed is:
Scherm­afbeelding 2024-07-25 om 03 03 00

Why is this needed? It was removed in https://github.com/musescore/MuseScore/pull/11892/files#diff-34fc1099345fb1b9e716cbe1602692db544d21858204ce45642aa36e99f779af. (Found using Git Blame with "blame prior to change …" a couple of times)
Why was it removed? My guess: Human Error.

Why are other changes not needed?

  • Explicitly setting the base is not necessary because String::toUInt uses std::strtol which behaves pretty much exactly the same as QString's toUInt. Passing a base of 0 decides based on whether the string is prefixed with 0x, 0b, 0 or nothing. So reading files containing 0x Just Works.
  • What about ♭ or ♭ notation? That also Just Works, because that is already substituted by the XML reader (I suppose; or at least, somewhere earlier in the pipeline). So instead of receiving ♭, we receive a symbol. That can obviously not be converted to a number, so we hit this case:
    if (!ok) {
        cs.code = 0;
        cs.value = code;
    } else if (Char::requiresSurrogates(val)) {
    (the bottom one, I suppose).
    Also, note that in this notation, &#nnnn; interprets nnnn as a decimal number, while &#xnnnn; (without leading 0) interprets nnnn as a hexadecimal. This is standard, and works out of the box, apparently even with our XML reader.

While this does prevent new scores from breaking, it doesn't fix already-broken scores.
I propose we don't do anything about this, for the following reasons:

  • it would make the code even more complicated
  • deciding between "a hex number with 0x", "a potentially-but-not-necessarily multi-byte character", "a decimal number" (that might be seen in a user-made chords file), and "a hex number that misses 0x", is basically impossible, especially because of the ambiguity between the latter two.
  • these broken chords xml files that MS4 wrote, never survived very long, because of a different bug I just discovered (and fixed)... see Fix that custom ChordList was not written to file anymore after reopening and resaving #23759

@Jojo-Schmitz
Copy link
Contributor Author

Jojo-Schmitz commented Jul 25, 2024

Hmm I'm confused now, it was me removing that u"0x" + , along with a comment // write hex numbers with a "0x" prefix, so they can convert back properly on read, in my 2nd commit (alternative fix) of this PR here.

Or are you saying that your #22541 basically makes this PR here obsolete, as it fixes the issue on the next write?

@cbjeukendrup
Copy link
Contributor

No, #23759 fixes an entirely different problem, namely that the chordlist was not written anymore at all after reopen-resave.

The u"0x" + was not there before this PR; as I said, it was accidentally lost in https://github.com/musescore/MuseScore/pull/11892/files#diff-34fc1099345fb1b9e716cbe1602692db544d21858204ce45642aa36e99f779af.
Your first commit added the u"0x" + back (along with a comment). And that turns out to be the correct solution, as I found when researching this yesterday.
But your first commit also does something with &#…; notation, and as I pointed out, that is unnecessary, so that change should be dropped.

In your second commit, you basically undid both these changes, and implemented an alternative fix at String::toUInt level. I think this alternative is not preferable; I'd like to prevent confusions and keep our String in sync with Qt's behaviour.

So what you need to do is:

  • drop the alternative fix (second commit), because the initial one was correct
  • drop the &#…; change from the first commit, because that is unnecessary

I hope that clarifies it!

@Jojo-Schmitz
Copy link
Contributor Author

Ah, I see now!

@Jojo-Schmitz
Copy link
Contributor Author

Done

@cbjeukendrup cbjeukendrup merged commit 7f55299 into musescore:master Jul 25, 2024
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[MU4 Issue] Accidentals in chord symbols rendered incorrectly when using custom XML file
2 participants