From 2323c563e21bfaa74f768463d22c6ab18bc57636 Mon Sep 17 00:00:00 2001 From: MinnieTheMoocher Date: Sat, 10 Oct 2026 09:08:45 +0200 Subject: [PATCH] ASF: Support rating tags in asf/wma files (#1447) --- taglib/asf/asftag.cpp | 54 ++++++++++++++++++++ tests/data/wma_rating.wma | Bin 0 -> 736310 bytes tests/test_asf.cpp | 101 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 tests/data/wma_rating.wma diff --git a/taglib/asf/asftag.cpp b/taglib/asf/asftag.cpp index 1d37b83b..29a91d3b 100644 --- a/taglib/asf/asftag.cpp +++ b/taglib/asf/asftag.cpp @@ -299,6 +299,7 @@ namespace std::tuple("WM/ToolName", "TOOLNAME", ASF::Attribute::UnicodeType), std::tuple("WM/ToolVersion", "TOOLVERSION", ASF::Attribute::UnicodeType), std::tuple("WM/Provider", "PROVIDER", ASF::Attribute::UnicodeType), + std::tuple("WM/SharedUserRating", "RATING", ASF::Attribute::DWordType), std::tuple("WM/UniqueFileIdentifier", "UNIQUEFILEIDENTIFIER", ASF::Attribute::UnicodeType), std::tuple("WMFSDKVersion", "WMFSDKVERSION", ASF::Attribute::UnicodeType), std::tuple("WMFSDKNeeded", "WMFSDKNEEDED", ASF::Attribute::UnicodeType), @@ -381,8 +382,13 @@ PropertyMap ASF::Tag::properties() const props["COMMENT"] = d->comment; } + AttributeList sharedRatings, popularimeters; for(const auto &[k, attributes] : std::as_const(d->attributeListMap)) { if(const String key = translateKey(k); !key.isEmpty()) { + if(key == "RATING") { + sharedRatings = attributes; + continue; + } for(const auto &attr : attributes) { // The same attribute can occur in both the extended content // description object and the metadata (library) object, skip exact @@ -393,10 +399,38 @@ PropertyMap ASF::Tag::properties() const } } } + else if(k.upper() == "POPULARIMETER") { + popularimeters = attributes; + } else { props.addUnsupportedData(k); } } + + // Expose the rating through the standard RATING property. WM/SharedUserRating + // (the Windows Media rating, a DWORD on the 0-99 scale) takes precedence over + // the POPM-style POPULARIMETER attribute (email|rating|counter, 0-255). + if(!sharedRatings.isEmpty()) { + for(const auto &attr : sharedRatings) { + if(const String value = attributeToString(attr); + !props.value("RATING").contains(value)) { + props.insert("RATING", value); + } + } + } + else if(!popularimeters.isEmpty()) { + // A POPULARIMETER attribute stores a POPM-style value of the form + // "email|rating|counter". Extract the numeric rating field. + for(const auto &attr : popularimeters) { + if(const StringList parts = attr.toString().split("|"); + parts.size() == 3) { + if(const String &value = parts[1]; + !value.isEmpty() && !props.value("RATING").contains(value)) { + props.insert("RATING", value); + } + } + } + } return props; } @@ -431,6 +465,11 @@ PropertyMap ASF::Tag::setProperties(const PropertyMap &props) else if(prop == "COPYRIGHT") { d->copyright.clear(); } + else if(prop == "RATING") { + // Remove both rating sources to keep the round-trip lossless. + eraseAttribute(d->attributeListMap, "WM/SharedUserRating"); + eraseAttribute(d->attributeListMap, "POPULARIMETER"); + } else { eraseAttribute(d->attributeListMap, reverseKeyMap[prop].first); } @@ -441,6 +480,21 @@ PropertyMap ASF::Tag::setProperties(const PropertyMap &props) for(const auto &[prop, attributes] : props) { if(reverseKeyMap.contains(prop)) { const auto &[name, type] = reverseKeyMap[prop]; + if(name == "WM/SharedUserRating" && + !d->attributeListMap.contains("WM/SharedUserRating")) { + if(auto it = d->attributeListMap.find("POPULARIMETER"); + it != d->attributeListMap.end() && !it->second.isEmpty()) { + // Rebuild a POPULARIMETER value, replacing the rating field while keeping + // the email and counter. + const StringList parts = it->second.front().toString().split("|"); + eraseAttribute(d->attributeListMap, "POPULARIMETER"); + for(const auto &str : attributes) { + addAttribute("POPULARIMETER", + parts.size() == 3 ? parts[0] + "|" + str + "|" + parts[2] : str); + } + continue; + } + } eraseAttribute(d->attributeListMap, name); for(const auto &str : attributes) { switch(type) { diff --git a/tests/data/wma_rating.wma b/tests/data/wma_rating.wma new file mode 100644 index 0000000000000000000000000000000000000000..d2bcec04c049d978f27770a57238ae1606d1cb75 GIT binary patch literal 736310 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 literal 0 HcmV?d00001 diff --git a/tests/test_asf.cpp b/tests/test_asf.cpp index 94088d40..87afbe75 100644 --- a/tests/test_asf.cpp +++ b/tests/test_asf.cpp @@ -53,6 +53,8 @@ class TestASF : public CppUnit::TestFixture CPPUNIT_TEST(testProperties); CPPUNIT_TEST(testPropertiesAllSupported); CPPUNIT_TEST(testPropertiesRealFile); + CPPUNIT_TEST(testRating); + CPPUNIT_TEST(testRatingWma); CPPUNIT_TEST(testCaseInsensitiveAttributeNames); CPPUNIT_TEST(testRepeatedSave); CPPUNIT_TEST_SUITE_END(); @@ -392,6 +394,7 @@ public: tags["ISVBR"] = StringList("1"); tags["PEAKVALUE"] = StringList("32104"); tags["AVERAGELEVEL"] = StringList("2450"); + tags["RATING"] = StringList("80"); ScopedFileCopy copy("silence-1", ".wma"); { @@ -478,6 +481,7 @@ public: {"WM/PromotionURL", ASF::Attribute::UnicodeType}, {"WM/Provider", ASF::Attribute::UnicodeType}, {"WM/Publisher", ASF::Attribute::UnicodeType}, + {"WM/SharedUserRating", ASF::Attribute::DWordType}, {"WM/Script", ASF::Attribute::UnicodeType}, {"WM/SetSubTitle", ASF::Attribute::UnicodeType}, {"WM/SubTitle", ASF::Attribute::UnicodeType}, @@ -551,6 +555,103 @@ public: CPPUNIT_ASSERT_EQUAL(StringList(";"), tags["UNIQUEFILEIDENTIFIER"]); } + void testRating() + { + // The example of the bug report: a file carrying both a Windows Media + // rating and a foobar2000-style POPM attribute. + ScopedFileCopy copy("silence-1", ".wma"); + { + ASF::File f(copy.fileName().c_str()); + f.tag()->setAttribute("WM/SharedUserRating", 75U); + f.tag()->setAttribute("POPULARIMETER", String("player@example.com|128|0")); + f.save(); + } + { + const ASF::File f(copy.fileName().c_str()); + PropertyMap tags = f.properties(); + + // WM/SharedUserRating is exposed and takes precedence over POPULARIMETER. + CPPUNIT_ASSERT_EQUAL(StringList("75"), tags["RATING"]); + CPPUNIT_ASSERT(!tags.unsupportedData().contains("WM/SharedUserRating")); + CPPUNIT_ASSERT(!tags.unsupportedData().contains("POPULARIMETER")); + } + { + // Without WM/SharedUserRating, the numeric POPM rating is extracted. + ASF::File f(copy.fileName().c_str()); + f.tag()->removeItem("WM/SharedUserRating"); + f.save(); + } + { + ASF::File f(copy.fileName().c_str()); + const PropertyMap tags = f.properties(); + CPPUNIT_ASSERT_EQUAL(StringList("128"), tags["RATING"]); + + // Setting RATING keeps the existing POPULARIMETER convention while + // preserving the email and counter. + PropertyMap props = f.properties(); + props["RATING"] = StringList("200"); + f.setProperties(props); + CPPUNIT_ASSERT_EQUAL(String("player@example.com|200|0"), + f.tag()->attribute("POPULARIMETER").front().toString()); + f.save(); + } + { + const ASF::File f(copy.fileName().c_str()); + CPPUNIT_ASSERT_EQUAL(StringList("200"), f.properties()["RATING"]); + } + { + // Once WM/SharedUserRating exists, writes go to it. + ASF::File f(copy.fileName().c_str()); + f.tag()->setAttribute("WM/SharedUserRating", 99U); + PropertyMap props = f.properties(); + CPPUNIT_ASSERT_EQUAL(StringList("99"), props["RATING"]); + props["RATING"] = StringList("50"); + f.setProperties(props); + CPPUNIT_ASSERT_EQUAL(50U, + f.tag()->attribute("WM/SharedUserRating").front().toUInt()); + f.save(); + } + { + // Removing RATING removes both rating sources. + ASF::File f(copy.fileName().c_str()); + PropertyMap props = f.properties(); + props.erase("RATING"); + f.setProperties(props); + CPPUNIT_ASSERT(!f.tag()->contains("WM/SharedUserRating")); + CPPUNIT_ASSERT(!f.tag()->contains("POPULARIMETER")); + } + } + + void testRatingWma() + { + // Regression test on a real-world Windows Media file carrying both the + // Windows Media rating (WM/SharedUserRating, DWORD on the 0-99 scale) and + // a foobar2000-style POPULARIMETER attribute (email|rating|counter) whose + // numeric rating is higher. WM/SharedUserRating must win, and neither + // attribute may be dropped into the unsupported data. + const ASF::File f(TEST_FILE_PATH_C("wma_rating.wma")); + CPPUNIT_ASSERT(f.isValid()); + CPPUNIT_ASSERT(f.audioProperties()); + CPPUNIT_ASSERT(f.tag()); + + const PropertyMap tags = f.properties(); + CPPUNIT_ASSERT_EQUAL(StringList("75"), tags["RATING"]); + CPPUNIT_ASSERT(!tags.unsupportedData().contains("WM/SharedUserRating")); + CPPUNIT_ASSERT(!tags.unsupportedData().contains("POPULARIMETER")); + + // The two rating sources are present in the raw attribute map with the + // expected types: a 0-99 DWORD and a POPM-style string. + const ASF::AttributeListMap &map = f.tag()->attributeListMap(); + CPPUNIT_ASSERT(map.find("WM/SharedUserRating") != map.end()); + CPPUNIT_ASSERT_EQUAL(ASF::Attribute::DWordType, + map["WM/SharedUserRating"].front().type()); + CPPUNIT_ASSERT_EQUAL(75U, + map["WM/SharedUserRating"].front().toUInt()); + CPPUNIT_ASSERT(map.find("POPULARIMETER") != map.end()); + CPPUNIT_ASSERT_EQUAL(ASF::Attribute::UnicodeType, + map["POPULARIMETER"].front().type()); + } + void testCaseInsensitiveAttributeNames() { ScopedFileCopy copy("silence-1", ".wma");