SVN commit 1114089 by lalinsky: Fix upgrading of ID3v2.3 genre with number 0 (Blues) M +4 -3 taglib/mpeg/id3v2/id3v2framefactory.cpp M +4 -13 taglib/mpeg/id3v2/id3v2tag.cpp M +13 -3 taglib/toolkit/tstring.cpp M +12 -0 taglib/toolkit/tstring.h M +28 -0 tests/test_string.cpp --- trunk/kdesupport/taglib/taglib/mpeg/id3v2/id3v2framefactory.cpp #1114088:1114089 @@ -412,10 +412,11 @@ if(s.startsWith("(") && end > 0) { // "(12)Genre" String text = s.substr(end + 1); - int number = s.substr(1, end - 1).toInt(); - if (number > 0 && number <= 255 && !(ID3v1::genre(number) == text)) + bool ok; + int number = s.substr(1, end - 1).toInt(&ok); + if(ok && number >= 0 && number <= 255 && !(ID3v1::genre(number) == text)) newfields.append(s.substr(1, end - 1)); - if (!text.isEmpty()) + if(!text.isEmpty()) newfields.append(text); } else { --- trunk/kdesupport/taglib/taglib/mpeg/id3v2/id3v2tag.cpp #1114088:1114089 @@ -164,21 +164,12 @@ if((*it).isEmpty()) continue; - bool isNumber = true; - - for(String::ConstIterator charIt = (*it).begin(); - isNumber && charIt != (*it).end(); - ++charIt) - { - isNumber = *charIt >= '0' && *charIt <= '9'; + bool ok; + int number = (*it).toInt(&ok); + if(ok && number >= 0 && number <= 255) { + *it = ID3v1::genre(number); } - if(isNumber) { - int number = (*it).toInt(); - if(number >= 0 && number <= 255) - *it = ID3v1::genre(number); - } - if(std::find(genres.begin(), genres.end(), *it) == genres.end()) genres.append(*it); } --- trunk/kdesupport/taglib/taglib/toolkit/tstring.cpp #1114088:1114089 @@ -432,17 +432,27 @@ int String::toInt() const { + return toInt(0); +} + +int String::toInt(bool *ok) const +{ int value = 0; - bool negative = d->data[0] == '-'; - uint i = negative ? 1 : 0; + uint size = d->data.size(); + bool negative = size > 0 && d->data[0] == '-'; + uint start = negative ? 1 : 0; + uint i = start; - for(; i < d->data.size() && d->data[i] >= '0' && d->data[i] <= '9'; i++) + for(; i < size && d->data[i] >= '0' && d->data[i] <= '9'; i++) value = value * 10 + (d->data[i] - '0'); if(negative) value = value * -1; + if(ok) + *ok = (size > start && i == size); + return value; } --- trunk/kdesupport/taglib/taglib/toolkit/tstring.h #1114088:1114089 @@ -291,10 +291,22 @@ /*! * Convert the string to an integer. + * + * Returns the integer if the conversion was successfull or 0 if the + * string does not represent a number. */ int toInt() const; /*! + * Convert the string to an integer. + * + * If the conversion was successfull, it sets the value of \a *ok to + * true and returns the integer. Otherwise it sets \a *ok to false + * and the result is undefined. + */ + int toInt(bool *ok) const; + + /*! * Returns a string with the leading and trailing whitespace stripped. */ String stripWhiteSpace() const; --- trunk/kdesupport/taglib/tests/test_string.cpp #1114088:1114089 @@ -40,6 +40,7 @@ CPPUNIT_TEST(testUTF16DecodeEmptyWithBOM); CPPUNIT_TEST(testAppendCharDetach); CPPUNIT_TEST(testAppendStringDetach); + CPPUNIT_TEST(testToInt); CPPUNIT_TEST_SUITE_END(); public: @@ -165,6 +166,33 @@ CPPUNIT_ASSERT_EQUAL(3, String("foo.bar").rfind(".")); } + void testToInt() + { + bool ok; + CPPUNIT_ASSERT_EQUAL(String("123").toInt(&ok), 123); + CPPUNIT_ASSERT_EQUAL(ok, true); + + CPPUNIT_ASSERT_EQUAL(String("-123").toInt(&ok), -123); + CPPUNIT_ASSERT_EQUAL(ok, true); + + CPPUNIT_ASSERT_EQUAL(String("abc").toInt(&ok), 0); + CPPUNIT_ASSERT_EQUAL(ok, false); + + CPPUNIT_ASSERT_EQUAL(String("1x").toInt(&ok), 1); + CPPUNIT_ASSERT_EQUAL(ok, false); + + CPPUNIT_ASSERT_EQUAL(String("").toInt(&ok), 0); + CPPUNIT_ASSERT_EQUAL(ok, false); + + CPPUNIT_ASSERT_EQUAL(String("-").toInt(&ok), 0); + CPPUNIT_ASSERT_EQUAL(ok, false); + + CPPUNIT_ASSERT_EQUAL(String("123").toInt(), 123); + CPPUNIT_ASSERT_EQUAL(String("-123").toInt(), -123); + CPPUNIT_ASSERT_EQUAL(String("123aa").toInt(), 123); + CPPUNIT_ASSERT_EQUAL(String("-123aa").toInt(), -123); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestString);