diff --git a/src/playlistparsers/asxparser.cpp b/src/playlistparsers/asxparser.cpp index b9c57a551..fad080324 100644 --- a/src/playlistparsers/asxparser.cpp +++ b/src/playlistparsers/asxparser.cpp @@ -47,6 +47,18 @@ SongList ASXParser::Load(QIODevice *device, const QString& playlist_path, const index += ex.matchedLength(); } + // Some playlists have unescaped & characters in URLs :( + ex.setPattern("(href\\s*=\\s*\")([^\"]+)\""); + index = 0; + while ((index = ex.indexIn(data, index)) != -1) { + QString url = ex.cap(2); + url.replace(QRegExp("&(?!amp;|quot;|apos;|lt;|gt;)"), "&"); + + QByteArray replacement = (ex.cap(1) + url + "\"").toLocal8Bit(); + data.replace(ex.cap(0).toLocal8Bit(), replacement); + index += replacement.length(); + } + QBuffer buffer(&data); buffer.open(QIODevice::ReadOnly); diff --git a/tests/asxparser_test.cpp b/tests/asxparser_test.cpp index 294ac01cf..c61cc902c 100644 --- a/tests/asxparser_test.cpp +++ b/tests/asxparser_test.cpp @@ -70,6 +70,29 @@ TEST_F(ASXParserTest, ParsesMoreThanOneTrackFromXML) { EXPECT_EQ(Song::Type_Stream, songs[1].filetype()); } +TEST_F(ASXParserTest, ParsesBrokenXmlEntities) { + QByteArray data = + "" + "DI.fm" + "Digitally Imported Radio" + "2006 Digitally Imported., Inc" + "" + " " + " " + " " + " Classic Trance" + " Digitally Imported Premium" + " " + ""; + + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + ASXParser parser(NULL); + SongList songs = parser.Load(&buffer); + ASSERT_EQ(1, songs.length()); + EXPECT_EQ("mms://72.26.204.105/classictrance128k?user=h&pass=xxxxxxxxxxxxxxx", songs[0].filename()); +} + TEST_F(ASXParserTest, SavesSong) { QByteArray data; QBuffer buffer(&data);