Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions taglib/toolkit/tbytevector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ ByteVector fromNumber(T value, bool mostSignificantByteFirst)
template <typename TFloat, typename TInt, Utils::ByteOrder ENDIAN>
TFloat toFloat(const ByteVector &v, size_t offset)
{
if(offset > v.size() - sizeof(TInt)) {
if(offset + sizeof(TInt) > v.size()) {
debug("toFloat() - offset is out of range. Returning 0.");
return 0.0;
}
Expand Down Expand Up @@ -195,7 +195,7 @@ long double toFloat80(const ByteVector &v, size_t offset)
{
using std::swap;

if(offset > v.size() - 10) {
if(offset + 10 > v.size()) {
debug("toFloat80() - offset is out of range. Returning 0.");
return 0.0;
}
Expand Down Expand Up @@ -360,7 +360,7 @@ ByteVector::ByteVector(const char *data, unsigned int length) :
}

ByteVector::ByteVector(const char *data) :
d(std::make_unique<ByteVectorPrivate>(data, static_cast<unsigned int>(::strlen(data))))
d(std::make_unique<ByteVectorPrivate>(data, data ? static_cast<unsigned int>(::strlen(data)) : 0))
{
}

Expand Down Expand Up @@ -767,6 +767,9 @@ bool ByteVector::operator!=(const ByteVector &v) const

bool ByteVector::operator==(const char *s) const
{
if(!s)
return isEmpty();

if(size() != ::strlen(s))
return false;

Expand Down
48 changes: 32 additions & 16 deletions taglib/toolkit/tstring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,23 +195,27 @@ String::String(const wchar_t *s) :
String::String(const wchar_t *s, Type t) :
d(std::make_shared<StringPrivate>())
{
if(t == UTF16 || t == UTF16BE || t == UTF16LE) {
copyFromUTF16(d->data, s, ::wcslen(s), t);
}
else {
debug("String::String() -- const wchar_t * should not contain Latin1 or UTF-8.");
if(s) {
if(t == UTF16 || t == UTF16BE || t == UTF16LE) {
copyFromUTF16(d->data, s, ::wcslen(s), t);
}
else {
debug("String::String() -- const wchar_t * should not contain Latin1 or UTF-8.");
}
}
}

String::String(const char *s, Type t) :
d(std::make_shared<StringPrivate>())
{
if(t == Latin1)
copyFromLatin1(d->data, s, ::strlen(s));
else if(t == String::UTF8)
copyFromUTF8(d->data, s, ::strlen(s));
else {
debug("String::String() -- const char * should not contain UTF16.");
if(s) {
if(t == Latin1)
copyFromLatin1(d->data, s, ::strlen(s));
else if(t == String::UTF8)
copyFromUTF8(d->data, s, ::strlen(s));
else {
debug("String::String() -- const char * should not contain UTF16.");
}
}
}

Expand Down Expand Up @@ -546,6 +550,10 @@ bool String::operator!=(const String &s) const

bool String::operator==(const char *s) const
{
if(!s) {
return isEmpty();
}

const wchar_t *p = toCWString();

while(*p != L'\0' || *s != '\0') {
Expand All @@ -562,6 +570,10 @@ bool String::operator!=(const char *s) const

bool String::operator==(const wchar_t *s) const
{
if(!s) {
return isEmpty();
}

return d->data == s;
}

Expand All @@ -580,18 +592,22 @@ String &String::operator+=(const String &s)

String &String::operator+=(const wchar_t *s)
{
detach();
if(s) {
detach();

d->data += s;
d->data += s;
}
return *this;
}

String &String::operator+=(const char *s)
{
detach();
if(s) {
detach();

for(int i = 0; s[i] != 0; i++)
d->data += static_cast<unsigned char>(s[i]);
for(int i = 0; s[i] != 0; i++)
d->data += static_cast<unsigned char>(s[i]);
}
return *this;
}

Expand Down
90 changes: 90 additions & 0 deletions tests/test_bytevector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/

#include <cstring>
#define _USE_MATH_DEFINES
#include <cmath>

Expand Down Expand Up @@ -53,6 +54,7 @@ class TestByteVector : public CppUnit::TestFixture
CPPUNIT_TEST(testAppend1);
CPPUNIT_TEST(testAppend2);
CPPUNIT_TEST(testBase64);
CPPUNIT_TEST(testEmpty);
CPPUNIT_TEST_SUITE_END();

public:
Expand Down Expand Up @@ -612,6 +614,94 @@ class TestByteVector : public CppUnit::TestFixture

}

void testEmpty()
{
const ByteVector empty;
const ByteVector notEmpty("A");
ByteVector mutEmpty;

CPPUNIT_ASSERT_EQUAL(empty, ByteVector(""));
CPPUNIT_ASSERT_EQUAL(empty, ByteVector("", 0));
CPPUNIT_ASSERT_EQUAL(empty, ByteVector(0U));
CPPUNIT_ASSERT_EQUAL(empty, ByteVector(empty, 0, 0));
CPPUNIT_ASSERT_EQUAL(empty, ByteVector(notEmpty, 1, 0));
CPPUNIT_ASSERT_EQUAL(empty, ByteVector(static_cast<const char *>(nullptr)));
CPPUNIT_ASSERT_EQUAL(empty, ByteVector(static_cast<const char *>(nullptr), 0));
CPPUNIT_ASSERT_EQUAL(mutEmpty.setData("", 0), empty);
CPPUNIT_ASSERT_EQUAL(mutEmpty.setData(""), empty);
CPPUNIT_ASSERT_EQUAL(mutEmpty.setData(nullptr, 0), empty);
CPPUNIT_ASSERT_EQUAL(mutEmpty.setData(nullptr), empty);
CPPUNIT_ASSERT(!empty.data());
CPPUNIT_ASSERT(!mutEmpty.data());
CPPUNIT_ASSERT_EQUAL(empty.mid(0), empty);
CPPUNIT_ASSERT_EQUAL(empty.at(0), '\0');
// Note that the behavior of ByteVector::find() with an empty pattern is
// not consistent with String::find() and std::string::find().
CPPUNIT_ASSERT_EQUAL(empty.find(mutEmpty), -1);
CPPUNIT_ASSERT_EQUAL(empty.find(notEmpty), -1);
CPPUNIT_ASSERT_EQUAL(notEmpty.find(empty), -1);
CPPUNIT_ASSERT_EQUAL(empty.find('\0'), -1);
CPPUNIT_ASSERT_EQUAL(empty.rfind(mutEmpty), -1);
CPPUNIT_ASSERT_EQUAL(empty.rfind(notEmpty), -1);
CPPUNIT_ASSERT_EQUAL(notEmpty.rfind(empty), -1);
CPPUNIT_ASSERT_EQUAL(empty.containsAt(mutEmpty, 0), false);
CPPUNIT_ASSERT_EQUAL(empty.startsWith(mutEmpty), false);
CPPUNIT_ASSERT_EQUAL(empty.startsWith(notEmpty), false);
CPPUNIT_ASSERT_EQUAL(notEmpty.startsWith(empty), false);
CPPUNIT_ASSERT_EQUAL(empty.endsWith(mutEmpty), false);
CPPUNIT_ASSERT_EQUAL(empty.endsWithPartialMatch(mutEmpty), -1);
CPPUNIT_ASSERT_EQUAL(mutEmpty.replace('a', 'b'), empty);
CPPUNIT_ASSERT_EQUAL(mutEmpty.replace("abc", ""), empty);
CPPUNIT_ASSERT_EQUAL(mutEmpty.append(empty), empty);
CPPUNIT_ASSERT_EQUAL(mutEmpty.append(notEmpty), notEmpty);
mutEmpty.clear();
CPPUNIT_ASSERT_EQUAL(mutEmpty, empty);
CPPUNIT_ASSERT_EQUAL(ByteVector(notEmpty).append(empty), notEmpty);
CPPUNIT_ASSERT_EQUAL(mutEmpty.append('A'), notEmpty);
CPPUNIT_ASSERT_EQUAL(mutEmpty.resize(0), empty);
CPPUNIT_ASSERT_EQUAL(empty.size(), 0U);
CPPUNIT_ASSERT(empty.begin() == empty.end());
CPPUNIT_ASSERT(empty.cbegin() == empty.cend());
CPPUNIT_ASSERT(empty.rbegin() == empty.rend());
CPPUNIT_ASSERT(mutEmpty.begin() == mutEmpty.end());
CPPUNIT_ASSERT(mutEmpty.rbegin() == mutEmpty.rend());
CPPUNIT_ASSERT(empty.isEmpty());
CPPUNIT_ASSERT_EQUAL(empty.toUInt(), 0U);
CPPUNIT_ASSERT_EQUAL(empty.toUInt(0, true), 0U);
CPPUNIT_ASSERT_EQUAL(empty.toUInt(0, 0, true), 0U);
CPPUNIT_ASSERT_EQUAL(empty.toShort(), static_cast<short>(0));
CPPUNIT_ASSERT_EQUAL(empty.toShort(0, true), static_cast<short>(0));
CPPUNIT_ASSERT_EQUAL(empty.toUShort(), static_cast<unsigned short>(0));
CPPUNIT_ASSERT_EQUAL(empty.toUShort(0, true), static_cast<unsigned short>(0));
CPPUNIT_ASSERT_EQUAL(empty.toLongLong(), 0LL);
CPPUNIT_ASSERT_EQUAL(empty.toLongLong(0, true), 0LL);
CPPUNIT_ASSERT_EQUAL(empty.toULongLong(), 0ULL);
CPPUNIT_ASSERT_EQUAL(empty.toULongLong(0, true), 0ULL);
CPPUNIT_ASSERT_EQUAL(empty.toFloat32LE(0), 0.f);
CPPUNIT_ASSERT_EQUAL(empty.toFloat32BE(0), 0.f);
CPPUNIT_ASSERT_EQUAL(empty.toFloat64LE(0), 0.);
CPPUNIT_ASSERT_EQUAL(empty.toFloat64BE(0), 0.);
CPPUNIT_ASSERT_EQUAL(empty.toFloat80LE(0), 0.l);
CPPUNIT_ASSERT_EQUAL(empty.toFloat80BE(0), 0.l);
CPPUNIT_ASSERT(empty == mutEmpty);
CPPUNIT_ASSERT(empty != notEmpty);
CPPUNIT_ASSERT(empty == "");
CPPUNIT_ASSERT(empty != " ");
CPPUNIT_ASSERT(empty == static_cast<const char *>(nullptr));
CPPUNIT_ASSERT(!(empty != static_cast<const char *>(nullptr)));
CPPUNIT_ASSERT(empty < notEmpty);
CPPUNIT_ASSERT(!(empty > notEmpty));
CPPUNIT_ASSERT_EQUAL(empty + mutEmpty, empty);
CPPUNIT_ASSERT_EQUAL(empty + notEmpty, notEmpty);
CPPUNIT_ASSERT_EQUAL(mutEmpty = static_cast<const char *>(nullptr), empty);
CPPUNIT_ASSERT_EQUAL(mutEmpty = notEmpty, notEmpty);
ByteVector tmp;
mutEmpty.swap(tmp);
CPPUNIT_ASSERT_EQUAL(mutEmpty, empty);
CPPUNIT_ASSERT_EQUAL(empty.toHex(), empty);
CPPUNIT_ASSERT_EQUAL(empty.toBase64(), empty);
}

};

CPPUNIT_TEST_SUITE_REGISTRATION(TestByteVector);
78 changes: 78 additions & 0 deletions tests/test_string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/

#include <string>
#include <cstring>

#include "tstring.h"
#include "tstringlist.h"
#include "tbytevector.h"
#include "tutils.h"
#include <cppunit/extensions/HelperMacros.h>

Expand Down Expand Up @@ -54,6 +57,7 @@ class TestString : public CppUnit::TestFixture
CPPUNIT_TEST(testEncodeNonBMP);
CPPUNIT_TEST(testIterator);
CPPUNIT_TEST(testInvalidUTF8);
CPPUNIT_TEST(testEmpty);
CPPUNIT_TEST_SUITE_END();

public:
Expand Down Expand Up @@ -370,6 +374,80 @@ class TestString : public CppUnit::TestFixture
CPPUNIT_ASSERT(String(ByteVector("\xED\xB0\x80\xED\xA0\x80"), String::UTF8).isEmpty());
}

void testEmpty()
{
const String empty;
const String notEmpty("A");
String mutEmpty;

CPPUNIT_ASSERT_EQUAL(empty, String(""));
CPPUNIT_ASSERT_EQUAL(empty, String(std::wstring()));
CPPUNIT_ASSERT_EQUAL(empty, String(static_cast<const wchar_t *>(nullptr)));
CPPUNIT_ASSERT(empty != String('\0'));
CPPUNIT_ASSERT_EQUAL(empty, String(L'\0'));
CPPUNIT_ASSERT_EQUAL(empty, String(static_cast<const char *>(nullptr)));
CPPUNIT_ASSERT_EQUAL(empty, String(ByteVector()));
CPPUNIT_ASSERT_EQUAL(empty.to8Bit(), std::string());
CPPUNIT_ASSERT_EQUAL(empty.toWString(), std::wstring());
CPPUNIT_ASSERT_EQUAL(::strlen(empty.toCString()), (size_t)0);
CPPUNIT_ASSERT_EQUAL(::wcslen(empty.toCWString()), (size_t)0);
CPPUNIT_ASSERT(empty.begin() == empty.end());
CPPUNIT_ASSERT(empty.cbegin() == empty.cend());
CPPUNIT_ASSERT(mutEmpty.begin() == mutEmpty.end());
CPPUNIT_ASSERT_EQUAL(empty.find(mutEmpty), 0);
CPPUNIT_ASSERT_EQUAL(empty.find(notEmpty), -1);
CPPUNIT_ASSERT_EQUAL(notEmpty.find(empty), 0);
CPPUNIT_ASSERT_EQUAL(empty.rfind(mutEmpty), 0);
CPPUNIT_ASSERT_EQUAL(empty.rfind(notEmpty), -1);
CPPUNIT_ASSERT_EQUAL(notEmpty.rfind(empty), 1);
CPPUNIT_ASSERT_EQUAL(empty.split(), StringList(empty));
CPPUNIT_ASSERT_EQUAL(empty.startsWith(mutEmpty), true);
CPPUNIT_ASSERT_EQUAL(empty.startsWith(notEmpty), false);
CPPUNIT_ASSERT_EQUAL(notEmpty.startsWith(empty), true);
CPPUNIT_ASSERT_EQUAL(empty.substr(0), empty);
CPPUNIT_ASSERT_EQUAL(mutEmpty.append(empty), empty);
CPPUNIT_ASSERT_EQUAL(mutEmpty.append(notEmpty), notEmpty);
mutEmpty.clear();
CPPUNIT_ASSERT_EQUAL(mutEmpty, empty);
CPPUNIT_ASSERT_EQUAL(String(notEmpty).append(empty), notEmpty);
CPPUNIT_ASSERT_EQUAL(empty.upper(), empty);
CPPUNIT_ASSERT_EQUAL(empty.size(), 0U);
CPPUNIT_ASSERT_EQUAL(empty.length(), 0U);
CPPUNIT_ASSERT_EQUAL(empty.isEmpty(), true);
CPPUNIT_ASSERT_EQUAL(empty.data(String::Latin1), ByteVector());
CPPUNIT_ASSERT_EQUAL(empty.data(String::UTF16LE), ByteVector());
bool ok;
empty.toInt(&ok);
CPPUNIT_ASSERT(!ok);
CPPUNIT_ASSERT_EQUAL(empty.stripWhiteSpace(), empty);
CPPUNIT_ASSERT_EQUAL(empty.isLatin1(), true);
CPPUNIT_ASSERT_EQUAL(empty.isAscii(), true);
CPPUNIT_ASSERT(empty == mutEmpty);
CPPUNIT_ASSERT(empty != notEmpty);
CPPUNIT_ASSERT(empty == "");
CPPUNIT_ASSERT(empty != " ");
CPPUNIT_ASSERT(empty == L"");
CPPUNIT_ASSERT(empty != L" ");
CPPUNIT_ASSERT(empty == static_cast<const char *>(nullptr));
CPPUNIT_ASSERT(!(empty != static_cast<const char *>(nullptr)));
CPPUNIT_ASSERT(empty == static_cast<const wchar_t *>(nullptr));
CPPUNIT_ASSERT(!(empty != static_cast<const wchar_t *>(nullptr)));
CPPUNIT_ASSERT_EQUAL(mutEmpty += empty, empty);
CPPUNIT_ASSERT_EQUAL(mutEmpty += notEmpty, notEmpty);
mutEmpty.clear();
CPPUNIT_ASSERT_EQUAL(mutEmpty += static_cast<const char *>(nullptr), empty);
CPPUNIT_ASSERT_EQUAL(mutEmpty += static_cast<const wchar_t *>(nullptr), empty);
CPPUNIT_ASSERT_EQUAL(mutEmpty = static_cast<const char *>(nullptr), empty);
CPPUNIT_ASSERT_EQUAL(mutEmpty = static_cast<const wchar_t *>(nullptr), empty);
String tmp;
mutEmpty.swap(tmp);
CPPUNIT_ASSERT_EQUAL(mutEmpty, empty);
CPPUNIT_ASSERT_EQUAL(empty < notEmpty, true);
CPPUNIT_ASSERT_EQUAL(empty + mutEmpty, empty);
CPPUNIT_ASSERT_EQUAL(empty + notEmpty, notEmpty);
CPPUNIT_ASSERT_EQUAL(empty + static_cast<const char *>(nullptr), empty);
}

};

CPPUNIT_TEST_SUITE_REGISTRATION(TestString);