Check PropertyMap keys format-specifically instead of globally.

Instead of statically forbidding certain keys in PropertyMap, now the
setProperties() implementations of the different formats check if the
keys are valid for that particular specification and include them in
the returned PropertyMap otherwise.
This should remove an unneccessary complification for programmers since
now there's only one step, namely calling setProperties(), where
problems might occur.
Also the previous implementation leads to problems with invalid keys:
because taglib doesn't use exceptions, something like

  map.insert("FORBIDDEN KEY", "some value");

would lead to the value being inserted under String::null, which
smells like the source of strange bugs.
This commit is contained in:
Michael Helmling
2012-07-30 20:52:30 +02:00
parent fc3fc10f60
commit 4140c5f2eb
14 changed files with 143 additions and 72 deletions

View File

@ -35,6 +35,7 @@ SET(test_runner_SRCS
test_bytevectorlist.cpp
test_bytevectorstream.cpp
test_string.cpp
test_propertymap.cpp
test_fileref.cpp
test_id3v1.cpp
test_id3v2.cpp

View File

@ -19,6 +19,7 @@ class TestAPETag : public CppUnit::TestFixture
CPPUNIT_TEST(testIsEmpty2);
CPPUNIT_TEST(testPropertyInterface1);
CPPUNIT_TEST(testPropertyInterface2);
CPPUNIT_TEST(testInvalidKeys);
CPPUNIT_TEST_SUITE_END();
public:
@ -76,12 +77,27 @@ public:
APE::Item item3 = APE::Item("TRACKNUMBER", "29");
tag.setItem("TRACKNUMBER", item3);
properties = tag.properties();
CPPUNIT_ASSERT_EQUAL(2u, properties["TRACKNUMBER"].size());
CPPUNIT_ASSERT_EQUAL(uint(2), properties["TRACKNUMBER"].size());
CPPUNIT_ASSERT_EQUAL(String("17"), properties["TRACKNUMBER"][0]);
CPPUNIT_ASSERT_EQUAL(String("29"), properties["TRACKNUMBER"][1]);
}
void testInvalidKeys()
{
PropertyMap properties;
properties["A"] = String("invalid key: one character");
properties["MP+"] = String("invalid key: forbidden string");
properties["A B~C"] = String("valid key: space and tilde");
properties["ARTIST"] = String("valid key: normal one");
APE::Tag tag;
PropertyMap unsuccessful = tag.setProperties(properties);
CPPUNIT_ASSERT_EQUAL(uint(2), unsuccessful.size());
CPPUNIT_ASSERT(unsuccessful.contains("A"));
CPPUNIT_ASSERT(unsuccessful.contains("MP+"));
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestAPETag);

View File

@ -0,0 +1,32 @@
#include <cppunit/extensions/HelperMacros.h>
#include <tpropertymap.h>
class TestPropertyMap : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestPropertyMap);
CPPUNIT_TEST(testInvalidKeys);
CPPUNIT_TEST_SUITE_END();
public:
void testInvalidKeys()
{
TagLib::PropertyMap map1;
CPPUNIT_ASSERT(map1.isEmpty());
map1["ÄÖÜ"].append("test");
CPPUNIT_ASSERT_EQUAL(map1.size(), 1u);
TagLib::PropertyMap map2;
map2["ÄÖÜ"].append("test");
CPPUNIT_ASSERT(map1 == map2);
CPPUNIT_ASSERT(map1.contains(map2));
map2["ARTIST"] = TagLib::String("Test Artist");
CPPUNIT_ASSERT(map1 != map2);
CPPUNIT_ASSERT(map2.contains(map1));
map2["ÄÖÜ"].append("test 2");
CPPUNIT_ASSERT(!map2.contains(map1));
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestPropertyMap);

View File

@ -2,6 +2,7 @@
#include <string>
#include <stdio.h>
#include <xiphcomment.h>
#include <tpropertymap.h>
#include <tdebug.h>
#include "utils.h"
@ -15,6 +16,7 @@ class TestXiphComment : public CppUnit::TestFixture
CPPUNIT_TEST(testSetYear);
CPPUNIT_TEST(testTrack);
CPPUNIT_TEST(testSetTrack);
CPPUNIT_TEST(testInvalidKeys);
CPPUNIT_TEST_SUITE_END();
public:
@ -59,6 +61,19 @@ public:
CPPUNIT_ASSERT_EQUAL(String("3"), cmt.fieldListMap()["TRACKNUMBER"].front());
}
void testInvalidKeys()
{
PropertyMap map;
map[""] = String("invalid key: empty string");
map["A=B"] = String("invalid key: contains '='");
map["A~B"] = String("invalid key: contains '~'");
Ogg::XiphComment cmt;
PropertyMap unsuccessful = cmt.setProperties(map);
CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), unsuccessful.size());
CPPUNIT_ASSERT(cmt.properties().isEmpty());
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestXiphComment);