Show warning when reading/writing ID3v2 frames not matching the tag version

This commit is contained in:
Martchus 2020-04-22 19:48:27 +02:00
parent c9e0f82519
commit 6c8f237087
3 changed files with 62 additions and 0 deletions

View File

@ -195,6 +195,15 @@ void Id3v2Frame::parse(BinaryReader &reader, std::uint32_t version, std::uint32_
}
}
// add a warning if a frame appears in an ID3v2 tag known not to support it
if (version <= 3 && Id3v2FrameIds::isOnlyId3v24Id(version < 3 ? Id3v2FrameIds::convertToLongId(id()) : id())) {
diag.emplace_back(DiagLevel::Warning,
argsToString("The frame is only supported in ID3v2.4 and newer but the tag's version is ID3v2.", version, '.'), context);
} else if (version > 3 && Id3v2FrameIds::isPreId3v24Id(id())) {
diag.emplace_back(DiagLevel::Warning,
argsToString("The frame is only supported in ID3v2.3 and older but the tag's version is ID3v2.", version, '.'), context);
}
// frame size mustn't be 0
if (m_dataSize <= 0) {
diag.emplace_back(DiagLevel::Warning, "The frame size is 0.", context);
@ -498,6 +507,19 @@ Id3v2FrameMaker::Id3v2FrameMaker(Id3v2Frame &frame, std::uint8_t version, Diagno
}
}
// add a warning if we're writing the frame for an ID3v2 tag known not to support it
if (version <= 3 && Id3v2FrameIds::isOnlyId3v24Id(version < 3 ? Id3v2FrameIds::convertToLongId(m_frameId) : m_frameId)) {
diag.emplace_back(DiagLevel::Warning,
argsToString("The frame is only supported in ID3v2.4 and newer but version of the tag being written is ID3v2.", version,
". The frame is written nevertheless but other tools might not be able to deal with it."),
context);
} else if (version > 3 && Id3v2FrameIds::isPreId3v24Id(m_frameId)) {
diag.emplace_back(DiagLevel::Warning,
argsToString("The frame is only supported in ID3v2.3 and older but version of the tag being written is ID3v2.", version,
". The frame is written nevertheless but other tools might not be able to deal with it."),
context);
}
// make actual data depending on the frame ID
try {
if (isTextFrame) {

View File

@ -144,6 +144,44 @@ std::uint32_t convertToLongId(std::uint32_t id)
}
}
/*!
* \brief Returns whether \a id is only supported in ID3v2.3.x and older and therefore can not be used in an ID3v2.4.x tag.
* \remarks
* - This function is intended to show warnings. Unknown IDs will be treated as supported everywhere.
* - Any short ID is obviously not ID3v2.4.x compatible. Only long IDs are considered here. Short IDs need to be converted to
* long IDs before passing them to this function.
*/
bool isPreId3v24Id(uint32_t id)
{
switch (id) {
case lYear:
case lOriginalYear:
case lRecordingDates:
case lDate:
case lTime:
return true;
default:
return false;
}
}
/*!
* \brief Returns whether \a id is only supported inID3v2.4.x and therefore can not be used in older versions.
* \remarks This function is intended to show warnings. Unknown IDs will be treated as supported everywhere.
*/
bool isOnlyId3v24Id(uint32_t id)
{
switch (id) {
case lRecordingTime:
case lReleaseTime:
case lOriginalReleaseTime:
case lTaggingTime:
return true;
default:
return false;
}
}
} // namespace Id3v2FrameIds
} // namespace TagParser

View File

@ -78,6 +78,8 @@ enum KnownValue : std::uint32_t {
TAG_PARSER_EXPORT std::uint32_t convertToShortId(std::uint32_t id);
TAG_PARSER_EXPORT std::uint32_t convertToLongId(std::uint32_t id);
TAG_PARSER_EXPORT bool isPreId3v24Id(std::uint32_t id);
TAG_PARSER_EXPORT bool isOnlyId3v24Id(std::uint32_t id);
/*!
* \brief Returns an indication whether the specified \a id is a long frame id.