Merge pull request #5643 from dmitrio95/mscx-read-crash

Fix a crash on MSCZ reading, add a way of handling such errors
This commit is contained in:
anatoly-os 2020-04-16 13:34:06 +03:00 committed by GitHub
commit a5c92e2040
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 17 additions and 2 deletions

View file

@ -1950,6 +1950,10 @@ void Measure::read(XmlReader& e, int staffIdx)
else else
qDebug("illegal measure size <%s>", qPrintable(e.attribute("len"))); qDebug("illegal measure size <%s>", qPrintable(e.attribute("len")));
irregular = true; irregular = true;
if (_len.numerator() <= 0 || _len.denominator() <= 0) {
e.raiseError(QObject::tr("MSCX error at line %1: invalid measure length: %2").arg(e.lineNumber()).arg(_len.toString()));
return;
}
score()->sigmap()->add(tick().ticks(), SigEvent(_len, _timesig)); score()->sigmap()->add(tick().ticks(), SigEvent(_len, _timesig));
score()->sigmap()->add((tick() + ticks()).ticks(), SigEvent(_timesig)); score()->sigmap()->add((tick() + ticks()).ticks(), SigEvent(_timesig));
} }

View file

@ -200,7 +200,10 @@ bool Score::read(XmlReader& e)
qDebug("%s: xml read error at line %lld col %lld: %s", qDebug("%s: xml read error at line %lld col %lld: %s",
qPrintable(e.getDocName()), e.lineNumber(), e.columnNumber(), qPrintable(e.getDocName()), e.lineNumber(), e.columnNumber(),
e.name().toUtf8().data()); e.name().toUtf8().data());
MScore::lastError = QObject::tr("XML read error at line %1, column %2: %3").arg(e.lineNumber()).arg(e.columnNumber()).arg(e.name().toString()); if (e.error() == QXmlStreamReader::CustomError)
MScore::lastError = e.errorString();
else
MScore::lastError = QObject::tr("XML read error at line %1, column %2: %3").arg(e.lineNumber()).arg(e.columnNumber()).arg(e.name().toString());
return false; return false;
} }
@ -332,8 +335,11 @@ Score::FileError MasterScore::read301(XmlReader& e)
score->setMscVersion(mscVersion()); score->setMscVersion(mscVersion());
addMovement(score); addMovement(score);
} }
if (!score->read(e)) if (!score->read(e)) {
if (e.error() == QXmlStreamReader::CustomError)
return FileError::FILE_CRITICALLY_CORRUPTED;
return FileError::FILE_BAD_FORMAT; return FileError::FILE_BAD_FORMAT;
}
} }
else if (tag == "Revision") { else if (tag == "Revision") {
Revision* revision = new Revision; Revision* revision = new Revision;

View file

@ -411,6 +411,7 @@ class Score : public QObject, public ScoreElement {
FILE_TOO_NEW, FILE_TOO_NEW,
FILE_OLD_300_FORMAT, FILE_OLD_300_FORMAT,
FILE_CORRUPTED, FILE_CORRUPTED,
FILE_CRITICALLY_CORRUPTED,
FILE_USER_ABORT, FILE_USER_ABORT,
FILE_IGNORE_ERROR FILE_IGNORE_ERROR
}; };

View file

@ -200,6 +200,10 @@ static bool readScoreError(const QString& name, Score::FileError error, bool ask
detailedMsg = MScore::lastError; detailedMsg = MScore::lastError;
canIgnore = true; canIgnore = true;
break; break;
case Score::FileError::FILE_CRITICALLY_CORRUPTED:
msg = QObject::tr("File \"%1\" is critically corrupted and cannot be processed.").arg(name);
detailedMsg = MScore::lastError;
break;
case Score::FileError::FILE_OLD_300_FORMAT: case Score::FileError::FILE_OLD_300_FORMAT:
msg += QObject::tr("It was last saved with a developer version of 3.0.\n"); msg += QObject::tr("It was last saved with a developer version of 3.0.\n");
canIgnore = true; canIgnore = true;