From a88c6fbd98dd9befe9ba5e9dec82718b1d7a3c1c Mon Sep 17 00:00:00 2001 From: rfm Date: Tue, 28 Mar 2006 06:05:04 +0000 Subject: [PATCH] obscure string bugfixes git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22723 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 8 +++- Source/Additions/Unicode.m | 37 ++++++++---------- Source/GSString.m | 77 +++++++++++++++++++++++++------------- 3 files changed, 75 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1c9299a47..2ff564142 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2006-03-28 Richard Frith-Macdonald + + * 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 * 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 diff --git a/Source/Additions/Unicode.m b/Source/Additions/Unicode.m index 413b725d2..a2623ba56 100644 --- a/Source/Additions/Unicode.m +++ b/Source/Additions/Unicode.m @@ -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; diff --git a/Source/GSString.m b/Source/GSString.m index b692a9d69..3d1323740 100644 --- a/Source/GSString.m +++ b/Source/GSString.m @@ -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; }