The result of some more proof-reading caused by Stephan's comments:
* _Realloc(), and _Detach[With]() may fail, but that wasn't accounted for
everywhere.
* The Append(), Prepend(), and Insert() char versions all caused their
backends to access invalid data (must use strncpy() instead of memcpy()
here).
* All Append(), Prepend(), and Insert() BString variants used an invalid
check, and would therefore just do nothing in certain situations like this
one:
BString a = "-";
BString b = a;
a.Append(b);
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24347 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+29
-19
@@ -155,7 +155,9 @@ BStringRef::operator&() const
|
|||||||
char*
|
char*
|
||||||
BStringRef::operator&()
|
BStringRef::operator&()
|
||||||
{
|
{
|
||||||
fString._Detach();
|
if (fString._Detach() != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
fString._ReferenceCount() = -1;
|
fString._ReferenceCount() = -1;
|
||||||
// mark as unsharable
|
// mark as unsharable
|
||||||
return &fString.fPrivateData[fPosition];
|
return &fString.fPrivateData[fPosition];
|
||||||
@@ -385,7 +387,8 @@ BString::operator+=(char c)
|
|||||||
BString&
|
BString&
|
||||||
BString::Append(const BString& string, int32 length)
|
BString::Append(const BString& string, int32 length)
|
||||||
{
|
{
|
||||||
_DoAppend(string.fPrivateData, min_clamp0(length, string.Length()));
|
if (&string != this)
|
||||||
|
_DoAppend(string.fPrivateData, min_clamp0(length, string.Length()));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,8 +427,8 @@ BString::Prepend(const char* string)
|
|||||||
BString&
|
BString&
|
||||||
BString::Prepend(const BString& string)
|
BString::Prepend(const BString& string)
|
||||||
{
|
{
|
||||||
if (fPrivateData != string.fPrivateData)
|
if (&string != this)
|
||||||
_DoPrepend(string.fPrivateData, string.Length());
|
_DoPrepend(string.String(), string.Length());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,7 +445,7 @@ BString::Prepend(const char* string, int32 length)
|
|||||||
BString&
|
BString&
|
||||||
BString::Prepend(const BString& string, int32 length)
|
BString::Prepend(const BString& string, int32 length)
|
||||||
{
|
{
|
||||||
if (fPrivateData != string.fPrivateData)
|
if (&string != this)
|
||||||
_DoPrepend(string.fPrivateData, min_clamp0(length, string.Length()));
|
_DoPrepend(string.fPrivateData, min_clamp0(length, string.Length()));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -511,7 +514,7 @@ BString::Insert(const char* string, int32 fromOffset, int32 length,
|
|||||||
BString&
|
BString&
|
||||||
BString::Insert(const BString& string, int32 position)
|
BString::Insert(const BString& string, int32 position)
|
||||||
{
|
{
|
||||||
if ((fPrivateData != string.fPrivateData) && string.Length() > 0)
|
if (&string != this && string.Length() > 0)
|
||||||
Insert(string.fPrivateData, position);
|
Insert(string.fPrivateData, position);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -520,7 +523,7 @@ BString::Insert(const BString& string, int32 position)
|
|||||||
BString&
|
BString&
|
||||||
BString::Insert(const BString& string, int32 length, int32 position)
|
BString::Insert(const BString& string, int32 length, int32 position)
|
||||||
{
|
{
|
||||||
if ((fPrivateData != string.fPrivateData) && string.Length() > 0)
|
if (&string != this && string.Length() > 0)
|
||||||
Insert(string.String(), length, position);
|
Insert(string.String(), length, position);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -530,7 +533,7 @@ BString&
|
|||||||
BString::Insert(const BString& string, int32 fromOffset, int32 length,
|
BString::Insert(const BString& string, int32 fromOffset, int32 length,
|
||||||
int32 position)
|
int32 position)
|
||||||
{
|
{
|
||||||
if ((fPrivateData != string.fPrivateData) && string.Length() > 0)
|
if (&string != this && string.Length() > 0)
|
||||||
Insert(string.String() + fromOffset, length, position);
|
Insert(string.String() + fromOffset, length, position);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -1381,8 +1384,13 @@ BString::operator[](int32 index)
|
|||||||
char&
|
char&
|
||||||
BString::operator[](int32 index)
|
BString::operator[](int32 index)
|
||||||
{
|
{
|
||||||
_Detach();
|
if (_Detach() != B_OK) {
|
||||||
|
static char invalid;
|
||||||
|
return invalid;
|
||||||
|
}
|
||||||
|
|
||||||
_ReferenceCount() = -1;
|
_ReferenceCount() = -1;
|
||||||
|
// mark string as unshareable
|
||||||
|
|
||||||
return fPrivateData[index];
|
return fPrivateData[index];
|
||||||
}
|
}
|
||||||
@@ -1399,9 +1407,10 @@ BString::LockBuffer(int32 maxLength)
|
|||||||
if (maxLength > length)
|
if (maxLength > length)
|
||||||
length += maxLength - length;
|
length += maxLength - length;
|
||||||
|
|
||||||
_DetachWith(fPrivateData, length);
|
if (_DetachWith(fPrivateData, length) == B_OK) {
|
||||||
_ReferenceCount() = -1;
|
_ReferenceCount() = -1;
|
||||||
// mark unshareable
|
// mark unshareable
|
||||||
|
}
|
||||||
return fPrivateData;
|
return fPrivateData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1416,10 +1425,11 @@ BString::UnlockBuffer(int32 length)
|
|||||||
length = (fPrivateData == NULL) ? 0 : strlen(fPrivateData);
|
length = (fPrivateData == NULL) ? 0 : strlen(fPrivateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
_Realloc(length);
|
if (_Realloc(length) != NULL) {
|
||||||
fPrivateData[length] = '\0';
|
fPrivateData[length] = '\0';
|
||||||
_ReferenceCount() = 1;
|
_ReferenceCount() = 1;
|
||||||
// mark shareable again
|
// mark shareable again
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -1819,7 +1829,7 @@ BString::_DoAppend(const char* string, int32 length)
|
|||||||
int32 oldLength = Length();
|
int32 oldLength = Length();
|
||||||
if (_DetachWith(fPrivateData, oldLength + length) == B_OK) {
|
if (_DetachWith(fPrivateData, oldLength + length) == B_OK) {
|
||||||
if (string && length)
|
if (string && length)
|
||||||
memcpy(fPrivateData + oldLength, string, length);
|
strncpy(fPrivateData + oldLength, string, length);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -1833,7 +1843,7 @@ BString::_DoPrepend(const char* string, int32 length)
|
|||||||
if (_DetachWith(fPrivateData, oldLength + length) == B_OK) {
|
if (_DetachWith(fPrivateData, oldLength + length) == B_OK) {
|
||||||
memmove(fPrivateData + length, fPrivateData, oldLength);
|
memmove(fPrivateData + length, fPrivateData, oldLength);
|
||||||
if (string && length)
|
if (string && length)
|
||||||
memcpy(fPrivateData, string, length);
|
strncpy(fPrivateData, string, length);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -1848,7 +1858,7 @@ BString::_DoInsert(const char* string, int32 offset, int32 length)
|
|||||||
memmove(fPrivateData + offset + length, fPrivateData + offset,
|
memmove(fPrivateData + offset + length, fPrivateData + offset,
|
||||||
oldLength - offset);
|
oldLength - offset);
|
||||||
if (string && length)
|
if (string && length)
|
||||||
memcpy(fPrivateData + offset, string, length);
|
strncpy(fPrivateData + offset, string, length);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user