Skip to content

Commit

Permalink
Merge pull request #296 from cardinot/bug_taglib
Browse files Browse the repository at this point in the history
Taglib segfaults - Null String
  • Loading branch information
kain88-de committed Aug 6, 2014
2 parents 215281a + 5026683 commit e9679ac
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 41 deletions.
89 changes: 48 additions & 41 deletions src/soundsource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,26 +223,33 @@ void SoundSource::setKey(QString key){
m_sKey = key;
}

QString SoundSource::toQString(TagLib::String tstring) const {
if (tstring == TagLib::String::null) {
return QString();
}
return TStringToQString(tstring);
}

bool SoundSource::processTaglibFile(TagLib::File& f) {
if (s_bDebugMetadata)
qDebug() << "Parsing" << getFilename();

if (f.isValid()) {
TagLib::Tag *tag = f.tag();
if (tag) {
QString title = TStringToQString(tag->title());
QString title = toQString(tag->title());
setTitle(title);

QString artist = TStringToQString(tag->artist());
QString artist = toQString(tag->artist());
setArtist(artist);

QString album = TStringToQString(tag->album());
QString album = toQString(tag->album());
setAlbum(album);

QString comment = TStringToQString(tag->comment());
QString comment = toQString(tag->comment());
setComment(comment);

QString genre = TStringToQString(tag->genre());
QString genre = toQString(tag->genre());
setGenre(genre);

int iYear = tag->year();
Expand Down Expand Up @@ -313,19 +320,19 @@ bool SoundSource::processID3v2Tag(TagLib::ID3v2::Tag* id3v2) {
TagLib::ID3v2::FrameList::ConstIterator it = id3v2->frameList().begin();
for(; it != id3v2->frameList().end(); it++) {
qDebug() << "ID3V2" << (*it)->frameID().data() << "-"
<< TStringToQString((*it)->toString());
<< toQString((*it)->toString());
}
}

TagLib::ID3v2::FrameList bpmFrame = id3v2->frameListMap()["TBPM"];
if (!bpmFrame.isEmpty()) {
QString sBpm = TStringToQString(bpmFrame.front()->toString());
QString sBpm = toQString(bpmFrame.front()->toString());
processBpmString("ID3v2", sBpm);
}

TagLib::ID3v2::FrameList keyFrame = id3v2->frameListMap()["TKEY"];
if (!keyFrame.isEmpty()) {
QString sKey = TStringToQString(keyFrame.front()->toString());
QString sKey = toQString(keyFrame.front()->toString());
setKey(sKey);
}
// Foobar2000-style ID3v2.3.0 tags
Expand All @@ -336,31 +343,31 @@ bool SoundSource::processID3v2Tag(TagLib::ID3v2::Tag* id3v2) {
dynamic_cast<TagLib::ID3v2::UserTextIdentificationFrame*>( *it );
if ( ReplayGainframe && ReplayGainframe->fieldList().size() >= 2 )
{
QString desc = TStringToQString( ReplayGainframe->description() ).toLower();
QString desc = toQString( ReplayGainframe->description() ).toLower();
if ( desc == "replaygain_album_gain" ){
QString sReplayGain = TStringToQString( ReplayGainframe->fieldList()[1]);
QString sReplayGain = toQString( ReplayGainframe->fieldList()[1]);
parseReplayGainString(sReplayGain);
}
if ( desc == "replaygain_track_gain" ){
QString sReplayGain = TStringToQString( ReplayGainframe->fieldList()[1]);
QString sReplayGain = toQString( ReplayGainframe->fieldList()[1]);
parseReplayGainString(sReplayGain);
}
}
}

TagLib::ID3v2::FrameList albumArtistFrame = id3v2->frameListMap()["TPE2"];
if (!albumArtistFrame.isEmpty()) {
QString sAlbumArtist = TStringToQString(albumArtistFrame.front()->toString());
QString sAlbumArtist = toQString(albumArtistFrame.front()->toString());
setAlbumArtist(sAlbumArtist);
}
TagLib::ID3v2::FrameList composerFrame = id3v2->frameListMap()["TCOM"];
if (!composerFrame.isEmpty()) {
QString sComposer = TStringToQString(composerFrame.front()->toString());
QString sComposer = toQString(composerFrame.front()->toString());
setComposer(sComposer);
}
TagLib::ID3v2::FrameList groupingFrame = id3v2->frameListMap()["TIT1"];
if (!groupingFrame.isEmpty()) {
QString sGrouping = TStringToQString(groupingFrame.front()->toString());
QString sGrouping = toQString(groupingFrame.front()->toString());
setGrouping(sGrouping);
}

Expand All @@ -371,36 +378,36 @@ bool SoundSource::processAPETag(TagLib::APE::Tag* ape) {
if (s_bDebugMetadata) {
for(TagLib::APE::ItemListMap::ConstIterator it = ape->itemListMap().begin();
it != ape->itemListMap().end(); ++it) {
qDebug() << "APE" << TStringToQString((*it).first) << "-" << TStringToQString((*it).second.toString());
qDebug() << "APE" << toQString((*it).first) << "-" << toQString((*it).second.toString());
}
}

if (ape->itemListMap().contains("BPM")) {
QString sBpm = TStringToQString(ape->itemListMap()["BPM"].toString());
QString sBpm = toQString(ape->itemListMap()["BPM"].toString());
processBpmString("APE", sBpm);
}

if (ape->itemListMap().contains("REPLAYGAIN_ALBUM_GAIN")) {
QString sReplayGain = TStringToQString(ape->itemListMap()["REPLAYGAIN_ALBUM_GAIN"].toString());
QString sReplayGain = toQString(ape->itemListMap()["REPLAYGAIN_ALBUM_GAIN"].toString());
parseReplayGainString(sReplayGain);
}

//Prefer track gain over album gain.
if (ape->itemListMap().contains("REPLAYGAIN_TRACK_GAIN")) {
QString sReplayGain = TStringToQString(ape->itemListMap()["REPLAYGAIN_TRACK_GAIN"].toString());
QString sReplayGain = toQString(ape->itemListMap()["REPLAYGAIN_TRACK_GAIN"].toString());
parseReplayGainString(sReplayGain);
}

if (ape->itemListMap().contains("Album Artist")) {
m_sAlbumArtist = TStringToQString(ape->itemListMap()["Album Artist"].toString());
m_sAlbumArtist = toQString(ape->itemListMap()["Album Artist"].toString());
}

if (ape->itemListMap().contains("Composer")) {
m_sComposer = TStringToQString(ape->itemListMap()["Composer"].toString());
m_sComposer = toQString(ape->itemListMap()["Composer"].toString());
}

if (ape->itemListMap().contains("Grouping")) {
m_sGrouping = TStringToQString(ape->itemListMap()["Grouping"].toString());
m_sGrouping = toQString(ape->itemListMap()["Grouping"].toString());
}

return true;
Expand All @@ -410,33 +417,33 @@ bool SoundSource::processXiphComment(TagLib::Ogg::XiphComment* xiph) {
if (s_bDebugMetadata) {
for (TagLib::Ogg::FieldListMap::ConstIterator it = xiph->fieldListMap().begin();
it != xiph->fieldListMap().end(); ++it) {
qDebug() << "XIPH" << TStringToQString((*it).first) << "-" << TStringToQString((*it).second.toString());
qDebug() << "XIPH" << toQString((*it).first) << "-" << toQString((*it).second.toString());
}
}

// Some tags use "BPM" so check for that.
if (xiph->fieldListMap().contains("BPM")) {
TagLib::StringList bpmString = xiph->fieldListMap()["BPM"];
QString sBpm = TStringToQString(bpmString.toString());
QString sBpm = toQString(bpmString.toString());
processBpmString("XIPH-BPM", sBpm);
}

// Give preference to the "TEMPO" tag which seems to be more standard
if (xiph->fieldListMap().contains("TEMPO")) {
TagLib::StringList bpmString = xiph->fieldListMap()["TEMPO"];
QString sBpm = TStringToQString(bpmString.toString());
QString sBpm = toQString(bpmString.toString());
processBpmString("XIPH-TEMPO", sBpm);
}

if (xiph->fieldListMap().contains("REPLAYGAIN_ALBUM_GAIN")) {
TagLib::StringList rgainString = xiph->fieldListMap()["REPLAYGAIN_ALBUM_GAIN"];
QString sReplayGain = TStringToQString(rgainString.toString());
QString sReplayGain = toQString(rgainString.toString());
parseReplayGainString(sReplayGain);
}

if (xiph->fieldListMap().contains("REPLAYGAIN_TRACK_GAIN")) {
TagLib::StringList rgainString = xiph->fieldListMap()["REPLAYGAIN_TRACK_GAIN"];
QString sReplayGain = TStringToQString(rgainString.toString());
QString sReplayGain = toQString(rgainString.toString());
parseReplayGainString(sReplayGain);
}

Expand All @@ -450,34 +457,34 @@ bool SoundSource::processXiphComment(TagLib::Ogg::XiphComment* xiph) {
*/
if (xiph->fieldListMap().contains("KEY")) {
TagLib::StringList keyStr = xiph->fieldListMap()["KEY"];
QString key = TStringToQString(keyStr.toString());
QString key = toQString(keyStr.toString());
setKey(key);
}
if (getKey().isEmpty() && xiph->fieldListMap().contains("INITIALKEY")) {
TagLib::StringList keyStr = xiph->fieldListMap()["INITIALKEY"];
QString key = TStringToQString(keyStr.toString());
QString key = toQString(keyStr.toString());
setKey(key);
}

if (xiph->fieldListMap().contains("ALBUMARTIST")) {
TagLib::StringList albumArtistString = xiph->fieldListMap()["ALBUMARTIST"];
m_sAlbumArtist = TStringToQString(albumArtistString.toString());
m_sAlbumArtist = toQString(albumArtistString.toString());
} else {
// try alternative field name
if (xiph->fieldListMap().contains("ALBUM_ARTIST")) {
TagLib::StringList albumArtistString = xiph->fieldListMap()["ALBUM_ARTIST"];
m_sAlbumArtist = TStringToQString(albumArtistString.toString());
m_sAlbumArtist = toQString(albumArtistString.toString());
}
}

if (xiph->fieldListMap().contains("COMPOSER")) {
TagLib::StringList composerString = xiph->fieldListMap()["COMPOSER"];
m_sComposer = TStringToQString(composerString.toString());
m_sComposer = toQString(composerString.toString());
}

if (xiph->fieldListMap().contains("GROUPING")) {
TagLib::StringList groupingString = xiph->fieldListMap()["GROUPING"];
m_sGrouping = TStringToQString(groupingString.toString());
m_sGrouping = toQString(groupingString.toString());
}

return true;
Expand All @@ -487,27 +494,27 @@ bool SoundSource::processMP4Tag(TagLib::MP4::Tag* mp4) {
if (s_bDebugMetadata) {
for(TagLib::MP4::ItemListMap::ConstIterator it = mp4->itemListMap().begin();
it != mp4->itemListMap().end(); ++it) {
qDebug() << "MP4" << TStringToQString((*it).first) << "-"
<< TStringToQString((*it).second.toStringList().toString());
qDebug() << "MP4" << toQString((*it).first) << "-"
<< toQString((*it).second.toStringList().toString());
}
}

// Get BPM
if (mp4->itemListMap().contains("tmpo")) {
QString sBpm = TStringToQString(
QString sBpm = toQString(
mp4->itemListMap()["tmpo"].toStringList().toString());
processBpmString("MP4", sBpm);
} else if (mp4->itemListMap().contains("----:com.apple.iTunes:BPM")) {
// This is an alternate way of storing BPM.
QString sBpm = TStringToQString(mp4->itemListMap()[
QString sBpm = toQString(mp4->itemListMap()[
"----:com.apple.iTunes:BPM"].toStringList().toString());
processBpmString("MP4", sBpm);
}

// Get Album Artist
if (mp4->itemListMap().contains("aART")) {
// this is technically a list of values -> concatenate into single string
QString albumArtist = TStringToQString(
QString albumArtist = toQString(
mp4->itemListMap()["aART"].toStringList().toString());
setAlbumArtist(albumArtist);
}
Expand All @@ -516,21 +523,21 @@ bool SoundSource::processMP4Tag(TagLib::MP4::Tag* mp4) {
if (mp4->itemListMap().contains("\251wrt")) {
// rryan 1/2012 I believe this is technically a list of composers. We
// don't support multiple composers in Mixxx, so just use them joined.
QString composer = TStringToQString(
QString composer = toQString(
mp4->itemListMap()["\251wrt"].toStringList().toString());
setComposer(composer);
}

// Get Grouping
if (mp4->itemListMap().contains("\251grp")) {
QString grouping = TStringToQString(
QString grouping = toQString(
mp4->itemListMap()["\251grp"].toStringList().toString());
setGrouping(grouping);
}

// Get KEY (conforms to Rapid Evolution)
if (mp4->itemListMap().contains("----:com.apple.iTunes:KEY")) {
QString key = TStringToQString(
QString key = toQString(
mp4->itemListMap()["----:com.apple.iTunes:KEY"].toStringList().toString());
setKey(key);
}
Expand All @@ -541,7 +548,7 @@ bool SoundSource::processMP4Tag(TagLib::MP4::Tag* mp4) {
// TODO(XXX) find tracks with this property and check what it looks
// like.

//QString replaygain = TStringToQString(mp4->itemListMap()["----:com.apple.iTunes:replaygain_track_gain"].toStringList().toString());
//QString replaygain = toQString(mp4->itemListMap()["----:com.apple.iTunes:replaygain_track_gain"].toStringList().toString());
}

return true;
Expand Down
4 changes: 4 additions & 0 deletions src/soundsource.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ class SoundSource
void processBpmString(QString tagName, QString sBpm);
void parseReplayGainString(QString sReplayGain);

// Taglib strings can be NULL and using it could cause some segfaults,
// so in this case it will return a QString()
QString toQString(TagLib::String tstring) const;

/** File name */
QString m_qFilename;

Expand Down

0 comments on commit e9679ac

Please sign in to comment.