Another patch from Oliver Tappe: BString behaves better when the user supplies out-of bounds values in Insert(), Remove(), etc.

Code is refactored, and it fully complies with our guidelines.
Tests have been updated too (hint: try the replace tests with R5 and our implementation...)


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5348 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2003-11-13 07:35:16 +00:00
parent 81b9c77691
commit 5480b4590e
8 changed files with 715 additions and 505 deletions
+9 -1
View File
@@ -1,5 +1,5 @@
//------------------------------------------------------------------------------
// Copyright (c) 2001-2002, OpenBeOS
// Copyright (c) 2001-2003, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
@@ -319,6 +319,14 @@ private:
void _AssertNotUsingAsCString() const {}
#endif
char *_Alloc( int32);
struct PosVect;
void _ReplaceAtPositions( const PosVect* positions,
int32 searchLen,
const char* with,
int32 withLen);
protected:
char *_privateData;
};
File diff suppressed because it is too large Load Diff
@@ -99,7 +99,7 @@ StringAppendTest::PerformTest(void)
str1 = new BString("Base");
str1->Append("APPENDED", 40);
CPPUNIT_ASSERT(strcmp(str1->String(), "BaseAPPENDED") == 0);
CPPUNIT_ASSERT(str1->Length() == strlen("BaseAPPENDED"));
CPPUNIT_ASSERT(str1->Length() == (int32)strlen("BaseAPPENDED"));
delete str1;
//char ptr is NULL
@@ -115,6 +115,25 @@ StringAppendTest::PerformTest(void)
str1->Append('C', 5);
CPPUNIT_ASSERT(strcmp(str1->String(), "BaseCCCCC") == 0);
delete str1;
const int32 OUT_OF_MEM_VAL = 2*1000*1000*1000;
#ifndef TEST_R5
//Append(char, int32) with excessive length:
NextSubTest();
str1 = new BString("Base");
str1->Append('C', OUT_OF_MEM_VAL);
CPPUNIT_ASSERT(strcmp(str1->String(), "Base") == 0);
delete str1;
#endif
#ifndef TEST_R5
//Append(char*, int32) with excessive length:
NextSubTest();
str1 = new BString("Base");
str1->Append("some more text", OUT_OF_MEM_VAL);
CPPUNIT_ASSERT(strcmp(str1->String(), "Basesome more text") == 0);
delete str1;
#endif
}
@@ -99,6 +99,25 @@ StringAssignTest::PerformTest(void)
CPPUNIT_ASSERT(str->Length() == 2);
CPPUNIT_ASSERT(strcmp(newstring.String(), "") == 0);
delete str;
const int32 OUT_OF_MEM_VAL = 2*1000*1000*1000;
#ifndef TEST_R5
//SetTo(char, int32) with excessive length:
NextSubTest();
str = new BString("dummy");
str->SetTo('C', OUT_OF_MEM_VAL);
CPPUNIT_ASSERT(strcmp(str->String(), "dummy") == 0);
delete str;
#endif
#ifndef TEST_R5
//SetTo(char*, int32) with excessive length:
NextSubTest();
str = new BString("dummy");
str->SetTo("some more text", OUT_OF_MEM_VAL);
CPPUNIT_ASSERT(strcmp(str->String(), "some more text") == 0);
delete str;
#endif
}
@@ -17,7 +17,7 @@ StringEscapeTest::~StringEscapeTest()
void
StringEscapeTest::PerformTest(void)
{
BString *string1, *string2;
BString *string1;
//CharacterEscape(char*, char)
NextSubTest();
@@ -26,12 +26,15 @@ StringInsertTest::PerformTest(void)
CPPUNIT_ASSERT(strcmp(str1->String(), "StrINSERTEDing") == 0);
delete str1;
//This test crashes both implementations
//NextSubTest();
//str1 = new BString("String");
//str1->Insert("INSERTED", 10);
//CPPUNIT_ASSERT(strcmp(str1->String(), "string") == 0);
//delete str1;
#ifndef TEST_R5
// This test crashes R5 and should drop into the debugger in OpenBeOS
// (if compiled with DEBUG):
NextSubTest();
str1 = new BString("String");
str1->Insert("INSERTED", 10);
CPPUNIT_ASSERT(strcmp(str1->String(), "String") == 0);
delete str1;
#endif
NextSubTest();
str1 = new BString;
@@ -39,6 +42,15 @@ StringInsertTest::PerformTest(void)
CPPUNIT_ASSERT(strcmp(str1->String(), "NSERTED") == 0);
delete str1;
#ifndef TEST_R5
// check limitation of negative values (R5 doesn't):
NextSubTest();
str1 = new BString;
str1->Insert("INSERTED", -142364253);
CPPUNIT_ASSERT(strcmp(str1->String(), "") == 0);
delete str1;
#endif
//&Insert(const char *, int32 length, int32 pos);
NextSubTest();
str1 = new BString("string");
@@ -46,12 +58,15 @@ StringInsertTest::PerformTest(void)
CPPUNIT_ASSERT(strcmp(str1->String(), "stINring") == 0);
delete str1;
//This test crashes both implementations
//NextSubTest();
//str1 = new BString("string");
//str1->Insert("INSERTED", 2, 30);
//CPPUNIT_ASSERT(strcmp(str1->String(), "stINring") == 0);
//delete str1;
#ifndef TEST_R5
// This test crashes R5 and should drop into the debugger in OpenBeOS
// (if compiled with DEBUG):
NextSubTest();
str1 = new BString("string");
str1->Insert("INSERTED", 2, 30);
CPPUNIT_ASSERT(strcmp(str1->String(), "string") == 0);
delete str1;
#endif
NextSubTest();
str1 = new BString("string");
@@ -73,6 +88,13 @@ StringInsertTest::PerformTest(void)
CPPUNIT_ASSERT(strcmp(str1->String(), "strPPPPPing") == 0);
delete str1;
//Insert(char c, int32 count, int32 pos)
NextSubTest();
str1 = new BString("string");
str1->Insert('P', 5, -2);
CPPUNIT_ASSERT(strcmp(str1->String(), "PPPstring") == 0);
delete str1;
//Insert(BString&)
NextSubTest();
str1 = new BString("string");
@@ -86,11 +86,11 @@ StringRemoveTest::PerformTest(void)
CPPUNIT_ASSERT(strcmp(string1->String(), "a String") == 0);
delete string1;
//from + length is > Length()
//from + length exceeds Length() (R5 fails)
NextSubTest();
string1 = new BString("a String");
string1->Remove(4, 30);
CPPUNIT_ASSERT(strcmp(string1->String(), "a String") == 0);
CPPUNIT_ASSERT(strcmp(string1->String(), "a St") == 0);
delete string1;
NextSubTest();
@@ -223,7 +223,7 @@ StringRemoveTest::PerformTest(void)
string2 = new BString("string");
string2->MoveInto(*string1, 0, 200);
CPPUNIT_ASSERT(strcmp(string1->String(), "string") == 0);
CPPUNIT_ASSERT(strcmp(string2->String(), "string") == 0);
CPPUNIT_ASSERT(strcmp(string2->String(), "") == 0);
delete string1;
delete string2;
@@ -242,7 +242,7 @@ StringRemoveTest::PerformTest(void)
memset(dest, 0, 100);
string1->MoveInto(dest, 0, 50);
CPPUNIT_ASSERT(strcmp(dest, "some text") == 0);
CPPUNIT_ASSERT(strcmp(string1->String(), "some text") == 0);
CPPUNIT_ASSERT(strcmp(string1->String(), "") == 0);
delete string1;
}
@@ -17,7 +17,9 @@ StringReplaceTest::~StringReplaceTest()
void
StringReplaceTest::PerformTest(void)
{
BString *str1, *str2;
BString *str1;
const int32 sz = 1024*50;
char* buf;
//&ReplaceFirst(char, char);
NextSubTest();
@@ -253,6 +255,15 @@ StringReplaceTest::PerformTest(void)
CPPUNIT_ASSERT(strcmp(str1->String(), "ccccccccccccccc") == 0);
delete str1;
#ifndef TEST_R5
//ReplaceSet(const char*, const char*)
NextSubTest();
str1 = new BString("abcd abcd abcd");
str1->ReplaceSet("abcd ", "");
CPPUNIT_ASSERT(strcmp(str1->String(), "") == 0);
delete str1;
#endif
#ifndef TEST_R5
//ReplaceSet(const char*, const char*)
NextSubTest();
@@ -261,6 +272,66 @@ StringReplaceTest::PerformTest(void)
CPPUNIT_ASSERT(strcmp(str1->String(), "dabcda dabcda dabcda") == 0);
delete str1;
#endif
#ifndef TEST_R5
//ReplaceSet(const char*, const char*)
NextSubTest();
str1 = new BString("abcd abcd abcd");
str1->ReplaceSet("ad", "");
CPPUNIT_ASSERT(strcmp(str1->String(), "bc bc bc") == 0);
delete str1;
#endif
// we repeat some test, but this time with a bit of data
// to test the performance:
// ReplaceSet(const char*, const char*)
NextSubTest();
str1 = new BString();
buf = str1->LockBuffer(sz);
memset( buf, 'x', sz);
str1->UnlockBuffer( sz);
str1->ReplaceSet("x", "y");
CPPUNIT_ASSERT(str1->Length() == sz);
delete str1;
NextSubTest();
str1 = new BString();
buf = str1->LockBuffer(sz);
memset( buf, 'x', sz);
str1->UnlockBuffer( sz);
str1->ReplaceSet("x", "");
CPPUNIT_ASSERT(str1->Length() == 0);
delete str1;
// ReplaceAll(const char*, const char*)
NextSubTest();
str1 = new BString();
buf = str1->LockBuffer(sz);
memset( buf, 'x', sz);
str1->UnlockBuffer( sz);
str1->ReplaceAll("x", "y");
CPPUNIT_ASSERT(str1->Length() == sz);
delete str1;
NextSubTest();
str1 = new BString();
buf = str1->LockBuffer(sz);
memset( buf, 'x', sz);
str1->UnlockBuffer( sz);
str1->ReplaceAll("xx", "y");
CPPUNIT_ASSERT(str1->Length() == sz/2);
delete str1;
NextSubTest();
str1 = new BString();
buf = str1->LockBuffer(sz);
memset( buf, 'x', sz);
str1->UnlockBuffer( sz);
str1->ReplaceSet("xx", "");
CPPUNIT_ASSERT(str1->Length() == 0);
delete str1;
}