* Fixed CID 1650: the "raw" buffer could be leaked.

* Automatic whitespace cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38420 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2010-08-28 16:46:18 +00:00
parent 8235dffe80
commit 44260788fe
@@ -1,10 +1,12 @@
#include "UdfString.h" #include "UdfString.h"
#include "ByteOrder.h" #include <ByteOrder.h>
#include <AutoDeleter.h>
/*! \brief Converts the given unicode character to utf8. /*! \brief Converts the given unicode character to utf8.
\param c The unicode character. \param c The unicode character.
\param out Pointer to a C-string of at least 4 characters \param out Pointer to a C-string of at least 4 characters
long into which the output utf8 characters will long into which the output utf8 characters will
@@ -16,8 +18,7 @@
upon returning, out will point to a pointer to upon returning, out will point to a pointer to
the fifth character in \c str. the fifth character in \c str.
*/ */
static static void
void
unicode_to_utf8(uint32 c, char **out) unicode_to_utf8(uint32 c, char **out)
{ {
char *s = *out; char *s = *out;
@@ -46,12 +47,11 @@ unicode_to_utf8(uint32 c, char **out)
will be read. *in will be incremented to reflect will be read. *in will be incremented to reflect
the number of characters read, similarly to the the number of characters read, similarly to the
\c out parameter for unicode_to_utf8(). \c out parameter for unicode_to_utf8().
\return The 4-byte unicode character, or **in if passed an \return The 4-byte unicode character, or **in if passed an
invalid character, or 0 if passed any NULL pointers. invalid character, or 0 if passed any NULL pointers.
*/ */
static static uint32
uint32
utf8_to_unicode(const char **in) utf8_to_unicode(const char **in)
{ {
if (!in) if (!in)
@@ -92,6 +92,9 @@ utf8_to_unicode(const char **in)
} }
// #pragma mark -
/*! \brief Creates an empty string object. */ /*! \brief Creates an empty string object. */
UdfString::UdfString() UdfString::UdfString()
: :
@@ -162,12 +165,14 @@ UdfString::SetTo(const char *utf8)
return; return;
} }
ArrayDeleter<uint32> rawDeleter(raw);
const char *in = utf8; const char *in = utf8;
uint32 rawLength = 0; uint32 rawLength = 0;
for (uint32 i = 0; i < length && uint32(in - utf8) < length; i++, rawLength++) for (uint32 i = 0; i < length && uint32(in - utf8) < length; i++, rawLength++)
raw[i] = utf8_to_unicode(&in); raw[i] = utf8_to_unicode(&in);
// Check for invalids. // Check for invalids.
uint32 mask = 0xffff0000; uint32 mask = 0xffff0000;
for (uint32 i = 0; i < rawLength; i++) { for (uint32 i = 0; i < rawLength; i++) {
if (raw[i] & mask) { if (raw[i] & mask) {
@@ -191,20 +196,20 @@ UdfString::SetTo(const char *utf8)
if (canUse8bit) { if (canUse8bit) {
fCs0Length = rawLength + 1; fCs0Length = rawLength + 1;
fCs0String = new(nothrow) char[fCs0Length]; fCs0String = new(nothrow) char[fCs0Length];
if (fCs0String) { if (fCs0String != NULL) {
fCs0String[0] = '\x08'; // 8-bit compressed unicode fCs0String[0] = '\x08'; // 8-bit compressed unicode
for (uint32 i = 0; i < rawLength; i++) for (uint32 i = 0; i < rawLength; i++)
fCs0String[i + 1] = raw[i] % 256; fCs0String[i + 1] = raw[i] % 256;
} else { } else {
TRACE_ERROR(("UdfString::SetTo: fCs0String[%ld] allocation failed\n", TRACE_ERROR(("UdfString::SetTo: fCs0String[%ld] allocation failed\n",
fCs0Length)); fCs0Length));
_Clear(); _Clear();
return; return;
} }
} else { } else {
fCs0Length = rawLength * 2 + 1; fCs0Length = rawLength * 2 + 1;
fCs0String = new(nothrow) char[fCs0Length]; fCs0String = new(nothrow) char[fCs0Length];
if (fCs0String) { if (fCs0String != NULL) {
uint32 pos = 0; uint32 pos = 0;
fCs0String[pos++] = '\x10'; // 16-bit unicode fCs0String[pos++] = '\x10'; // 16-bit unicode
for (uint32 i = 0; i < rawLength; i++) { for (uint32 i = 0; i < rawLength; i++) {
@@ -222,9 +227,6 @@ UdfString::SetTo(const char *utf8)
return; return;
} }
} }
// Clean up
delete [] raw;
raw = NULL;
} }
@@ -232,7 +234,7 @@ UdfString::SetTo(const char *utf8)
void void
UdfString::SetTo(const char *cs0, uint32 length) UdfString::SetTo(const char *cs0, uint32 length)
{ {
DEBUG_INIT_ETC("UdfString", ("cs0: %p, length: %ld", cs0, length)); DEBUG_INIT_ETC("UdfString", ("cs0: %p, length: %ld", cs0, length));
_Clear(); _Clear();
if (length == 0) if (length == 0)
@@ -240,7 +242,7 @@ UdfString::SetTo(const char *cs0, uint32 length)
if (!cs0) { if (!cs0) {
PRINT(("passed NULL cs0 string\n")); PRINT(("passed NULL cs0 string\n"));
return; return;
} }
// First copy the Cs0 string and length // First copy the Cs0 string and length
fCs0String = new(nothrow) char[length]; fCs0String = new(nothrow) char[length];
@@ -253,7 +255,7 @@ UdfString::SetTo(const char *cs0, uint32 length)
} }
// Now convert to utf8 // Now convert to utf8
// The first byte of the CS0 string is the compression ID. // The first byte of the CS0 string is the compression ID.
// - 8: 1 byte characters // - 8: 1 byte characters
// - 16: 2 byte, big endian characters // - 16: 2 byte, big endian characters
@@ -261,16 +263,16 @@ UdfString::SetTo(const char *cs0, uint32 length)
// - 255: "CS0 expansion is empty and unique", 2 byte, big endian characters // - 255: "CS0 expansion is empty and unique", 2 byte, big endian characters
PRINT(("compression ID: %d\n", cs0[0])); PRINT(("compression ID: %d\n", cs0[0]));
switch (reinterpret_cast<const uint8*>(cs0)[0]) { switch (reinterpret_cast<const uint8*>(cs0)[0]) {
case 8: case 8:
case 254: case 254:
{ {
const uint8 *inputString = reinterpret_cast<const uint8*>(&(cs0[1])); const uint8 *inputString = reinterpret_cast<const uint8*>(&(cs0[1]));
int32 maxLength = length-1; // Max length of input string in uint8 characters int32 maxLength = length-1; // Max length of input string in uint8 characters
int32 allocationLength = maxLength*2+1; // Need at most 2 utf8 chars per uint8 char int32 allocationLength = maxLength*2+1; // Need at most 2 utf8 chars per uint8 char
fUtf8String = new(nothrow) char[allocationLength]; fUtf8String = new(nothrow) char[allocationLength];
if (fUtf8String) { if (fUtf8String) {
char *outputString = fUtf8String; char *outputString = fUtf8String;
for (int32 i = 0; i < maxLength && inputString[i]; i++) { for (int32 i = 0; i < maxLength && inputString[i]; i++) {
unicode_to_utf8(inputString[i], &outputString); unicode_to_utf8(inputString[i], &outputString);
} }
@@ -278,7 +280,7 @@ UdfString::SetTo(const char *cs0, uint32 length)
} else { } else {
PRINT(("new fUtf8String[%ld] allocation failed\n", allocationLength)); PRINT(("new fUtf8String[%ld] allocation failed\n", allocationLength));
} }
break; break;
} }
@@ -299,10 +301,10 @@ UdfString::SetTo(const char *cs0, uint32 length)
} else { } else {
PRINT(("new fUtf8String[%ld] allocation failed\n", allocationLength)); PRINT(("new fUtf8String[%ld] allocation failed\n", allocationLength));
} }
break; break;
} }
default: default:
PRINT(("invalid compression id!\n")); PRINT(("invalid compression id!\n"));
break; break;
@@ -312,7 +314,7 @@ UdfString::SetTo(const char *cs0, uint32 length)
void void
UdfString::_Clear() UdfString::_Clear()
{ {
DEBUG_INIT("UdfString"); DEBUG_INIT("UdfString");
delete [] fCs0String; delete [] fCs0String;
fCs0String = NULL; fCs0String = NULL;