obscure string bugfixes

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22723 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2006-03-28 06:05:04 +00:00
parent c7cae70ec4
commit 51bfa42d59
3 changed files with 75 additions and 47 deletions

View file

@ -1,3 +1,9 @@
2006-03-28 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSString.m: Fix error initialising mutable string from
unicode char array conmtaining ascii characters.
Fix a few memory mleaks.
2006-03-25 Richard Frith-Macdonald <rfm@gnu.org>
* Source/win32/NSStreamWin32.m: Various tidyups for pipe streams.
@ -5,7 +11,7 @@
* Headers/Additions/GNUstepBase/Unicode.h: Add validation function.
* Source/Additions/Unicode.m: Add unicode validation function and
alter UTF8 handling to be stricter.
* Source/GSString.m: validate unicode when initialisiung a string.
* Source/GSString.m: validate unicode when initialising a string.
Also create 8bit data strings rather than 16bit where possible.
2006-03-24 Richard Frith-Macdonald <rfm@gnu.org>

View file

@ -1349,6 +1349,22 @@ GSToUnicode(unichar **dst, unsigned int *size, const unsigned char *src,
}
u = u & ~(0xffffffff << ((5 * sle) + 1));
spos += sle;
/*
* We discard invalid codepoints here.
*/
if (u > 0x10ffff || u == 0xfffe || u == 0xffff
|| (u >= 0xfdd0 && u <= 0xfdef))
{
result = NO; // Invalid character.
break;
}
if ((u >= 0xd800) && (u <= 0xdfff))
{
result = NO; // Unmatched half of surrogate pair.
break;
}
}
else
{
@ -1358,33 +1374,12 @@ GSToUnicode(unichar **dst, unsigned int *size, const unsigned char *src,
/*
* Add codepoint as either a single unichar for BMP
* or as a pair of surrogates for codepoints over 16 bits.
* We also discard invalid codepoints here.
*/
if (u == 0xfffe || u == 0xffff
|| (u >= 0xfdd0 && u <= 0xfdef))
{
result = NO; // Invalid character.
break;
}
if ((u >= 0xd800) && (u <= 0xdfff))
{
result = NO; // Unmatched half of surrogate pair.
break;
}
if (u > 0x10ffff)
{
result = NO; // Too large
break;
}
if (dpos >= bsize)
{
GROW();
}
if (u < 0x10000)
{
ptr[dpos++] = u;

View file

@ -402,6 +402,10 @@ setup(void)
if (GSUnicode(chars, length, &isASCII, &isLatin1) != length)
{
if (flag == YES && chars != 0)
{
NSZoneFree(NSZoneFromPointer(chars), chars);
}
return nil; // Invalid data
}
if (isASCII == YES
@ -420,6 +424,10 @@ setup(void)
{
me->_contents.c[length] = (unsigned char)chars[length];
}
if (flag == YES && chars != 0)
{
NSZoneFree(NSZoneFromPointer(chars), chars);
}
}
else
{
@ -3093,6 +3101,10 @@ agree, create a new GSUnicodeInlineString otherwise.
if (GSUnicode(chars, length, &isASCII, &isLatin1) != length)
{
RELEASE(self);
if (flag == YES && chars != 0)
{
NSZoneFree(NSZoneFromPointer(chars), chars);
}
return nil; // Invalid data
}
if (isASCII == YES
@ -3114,6 +3126,10 @@ agree, create a new GSUnicodeInlineString otherwise.
me->_contents.c[length] = (unsigned char)chars[length];
}
RELEASE(self);
if (flag == YES && chars != 0)
{
NSZoneFree(NSZoneFromPointer(chars), chars);
}
return (id)me;
}
if (_contents.u != 0)
@ -3559,45 +3575,56 @@ agree, create a new GSUnicodeInlineString otherwise.
if (GSUnicode(chars, length, &isASCII, &isLatin1) != length)
{
RELEASE(self);
if (flag == YES && chars != 0)
{
NSZoneFree(NSZoneFromPointer(chars), chars);
}
return nil; // Invalid data
}
if (isASCII == YES
|| (intEnc == NSISOLatin1StringEncoding && isLatin1 == YES))
{
GSStr me;
unsigned char *buf;
/*
* OK ... we can do a more compact version
*/
me = (GSStr)NSAllocateObject(GSCInlineStringClass, length,
GSObjCZone(self));
me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
me->_count = length;
me->_flags.wide = 0;
me->_flags.free = 1;
while (length-- > 0)
{
me->_contents.c[length] = (unsigned char)chars[length];
}
RELEASE(self);
return (id)me;
}
_count = length;
_capacity = length;
_contents.u = chars;
_flags.wide = 1;
if (flag == YES && chars != 0)
{
#if GS_WITH_GC
_zone = GSAtomicMallocZone();
#else
_zone = NSZoneFromPointer(chars);
_zone = NSDefaultMallocZone();
#endif
buf = NSZoneMalloc(_zone, length);
_count = length;
_capacity = length;
_contents.c = buf;
_flags.wide = 0;
_flags.free = 1;
while (length-- > 0)
{
buf[length] = (unsigned char)chars[length];
}
if (flag == YES && chars != 0)
{
NSZoneFree(NSZoneFromPointer(chars), chars);
}
}
else
{
_zone = 0;
_count = length;
_capacity = length;
_contents.u = chars;
_flags.wide = 1;
if (flag == YES && chars != 0)
{
#if GS_WITH_GC
_zone = GSAtomicMallocZone();
#else
_zone = NSZoneFromPointer(chars);
#endif
_flags.free = 1;
}
else
{
_zone = 0;
}
}
return self;
}