mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
Fix mutable copy of 8bit string ... hope this doesnt break anything, it passes
the testsuite and my apps saeem to run. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22920 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
a9c025da57
commit
849e0b2af3
2 changed files with 173 additions and 101 deletions
|
@ -3,6 +3,10 @@
|
|||
* Source/GSString.m: validate UTF-16 data when producing a Cstring
|
||||
* Source/NSCharacterSetData.h: Add code plane 16 (private use)
|
||||
* Source/NSCharacterSet.m: Fix to support code plane 16
|
||||
* Source/GSString.m: Attempt to fix error making a mutable copy of
|
||||
an 8bit string when the external Cstring encoding is not the same as
|
||||
the internal one. Use new initWithBytes... method specifying the
|
||||
encoding used in those cases.
|
||||
|
||||
2006-05-11 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
|
|
|
@ -2681,7 +2681,9 @@ transmute(GSStr self, NSString *aString)
|
|||
|
||||
obj = (GSMutableString*)NSAllocateObject(GSMutableStringClass, 0,
|
||||
NSDefaultMallocZone());
|
||||
obj = [obj initWithCString: (char*)_contents.c length: _count];
|
||||
obj = [obj initWithBytes: (char*)_contents.c
|
||||
length: _count
|
||||
encoding: intEnc];
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -3562,6 +3564,158 @@ agree, create a new GSUnicodeInlineString otherwise.
|
|||
return [self initWithCapacity: 0];
|
||||
}
|
||||
|
||||
- (id) initWithBytes: (const void*)bytes
|
||||
length: (unsigned int)length
|
||||
encoding: (NSStringEncoding)encoding
|
||||
{
|
||||
void *chars = NSZoneMalloc(NSDefaultMallocZone(), length);
|
||||
|
||||
memcpy(chars, bytes, length);
|
||||
return [self initWithBytesNoCopy: chars
|
||||
length: length
|
||||
encoding: encoding
|
||||
freeWhenDone: YES];
|
||||
}
|
||||
|
||||
- (id) initWithBytesNoCopy: (const void*)bytes
|
||||
length: (unsigned int)length
|
||||
encoding: (NSStringEncoding)encoding
|
||||
freeWhenDone: (BOOL)flag
|
||||
{
|
||||
BOOL isASCII = NO;
|
||||
BOOL isLatin1 = NO;
|
||||
|
||||
if (encoding != intEnc && GSIsByteEncoding(encoding) == YES)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
if (((unsigned char*)bytes)[i] > 127)
|
||||
{
|
||||
if (encoding == NSASCIIStringEncoding)
|
||||
{
|
||||
RELEASE(self);
|
||||
if (flag == YES && bytes != 0)
|
||||
{
|
||||
NSZoneFree(NSZoneFromPointer(bytes), bytes);
|
||||
}
|
||||
return nil; // Invalid data
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == length)
|
||||
{
|
||||
/*
|
||||
* This is actually ASCII data ... so we can just stor it as if
|
||||
* in the internal 8bit encoding scheme.
|
||||
*/
|
||||
encoding = intEnc;
|
||||
}
|
||||
}
|
||||
|
||||
if (encoding == intEnc)
|
||||
{
|
||||
_count = length;
|
||||
_capacity = length;
|
||||
_contents.c = bytes;
|
||||
_flags.wide = 0;
|
||||
_flags.free = flag;
|
||||
#if GS_WITH_GC
|
||||
_zone = GSAtomicMallocZone();
|
||||
#else
|
||||
_zone = NSZoneFromPointer(bytes);
|
||||
#endif
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
* Any remaining encoding needs to be converted to UTF-16.
|
||||
*/
|
||||
if (encoding != NSUnicodeStringEncoding)
|
||||
{
|
||||
unichar *u = 0;
|
||||
unsigned l = 0;
|
||||
|
||||
if (GSToUnicode(&u, &l, (unsigned char*)bytes, length, encoding,
|
||||
GSObjCZone(self), 0) == NO)
|
||||
{
|
||||
RELEASE(self);
|
||||
if (flag == YES && bytes != 0)
|
||||
{
|
||||
NSZoneFree(NSZoneFromPointer(bytes), bytes);
|
||||
}
|
||||
return nil; // Invalid data
|
||||
}
|
||||
if (flag == YES && bytes != 0)
|
||||
{
|
||||
NSZoneFree(NSZoneFromPointer(bytes), bytes);
|
||||
}
|
||||
bytes = u;
|
||||
length = l * sizeof(unichar);
|
||||
flag = YES;
|
||||
}
|
||||
|
||||
length /= sizeof(unichar);
|
||||
if (GSUnicode(bytes, length, &isASCII, &isLatin1) != length)
|
||||
{
|
||||
RELEASE(self);
|
||||
if (flag == YES && bytes != 0)
|
||||
{
|
||||
NSZoneFree(NSZoneFromPointer(bytes), bytes);
|
||||
}
|
||||
return nil; // Invalid data
|
||||
}
|
||||
|
||||
if (isASCII == YES
|
||||
|| (intEnc == NSISOLatin1StringEncoding && isLatin1 == YES))
|
||||
{
|
||||
unsigned char *buf;
|
||||
|
||||
#if GS_WITH_GC
|
||||
_zone = GSAtomicMallocZone();
|
||||
#else
|
||||
_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] = ((unichar*)bytes)[length];
|
||||
}
|
||||
if (flag == YES && bytes != 0)
|
||||
{
|
||||
NSZoneFree(NSZoneFromPointer(bytes), bytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_count = length;
|
||||
_capacity = length;
|
||||
_contents.u = bytes;
|
||||
_flags.wide = 1;
|
||||
if (flag == YES && bytes != 0)
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
_zone = GSAtomicMallocZone();
|
||||
#else
|
||||
_zone = NSZoneFromPointer(bytes);
|
||||
#endif
|
||||
_flags.free = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_zone = 0;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithCapacity: (unsigned)capacity
|
||||
{
|
||||
if (capacity < 2)
|
||||
|
@ -3585,110 +3739,20 @@ agree, create a new GSUnicodeInlineString otherwise.
|
|||
length: (unsigned int)length
|
||||
freeWhenDone: (BOOL)flag
|
||||
{
|
||||
BOOL isASCII;
|
||||
BOOL isLatin1;
|
||||
|
||||
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))
|
||||
{
|
||||
unsigned char *buf;
|
||||
|
||||
#if GS_WITH_GC
|
||||
_zone = GSAtomicMallocZone();
|
||||
#else
|
||||
_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
|
||||
{
|
||||
_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;
|
||||
return [self initWithBytesNoCopy: (void*)chars
|
||||
length: length*sizeof(unichar)
|
||||
encoding: NSUnicodeStringEncoding
|
||||
freeWhenDone: flag];
|
||||
}
|
||||
|
||||
- (id) initWithCStringNoCopy: (char*)chars
|
||||
length: (unsigned int)length
|
||||
freeWhenDone: (BOOL)flag
|
||||
{
|
||||
if (defEnc != intEnc)
|
||||
{
|
||||
unichar *u = 0;
|
||||
unsigned l = 0;
|
||||
|
||||
if (GSToUnicode(&u, &l, (unsigned char*)chars, length, defEnc,
|
||||
GSObjCZone(self), 0) == NO)
|
||||
{
|
||||
DESTROY(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
self = [self initWithCharactersNoCopy: u length: l freeWhenDone: YES];
|
||||
}
|
||||
if (flag == YES && chars != 0)
|
||||
{
|
||||
NSZoneFree(NSZoneFromPointer(chars), chars);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
if (flag == YES && chars != 0)
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
_zone = GSAtomicMallocZone();
|
||||
#else
|
||||
_zone = NSZoneFromPointer(chars);
|
||||
#endif
|
||||
_flags.free = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_zone = 0;
|
||||
}
|
||||
_count = length;
|
||||
_capacity = length;
|
||||
_contents.c = (unsigned char*)chars;
|
||||
_flags.wide = 0;
|
||||
|
||||
return self;
|
||||
return [self initWithBytesNoCopy: (void*)chars
|
||||
length: length
|
||||
encoding: defEnc
|
||||
freeWhenDone: flag];
|
||||
}
|
||||
|
||||
- (id) initWithFormat: (NSString*)format
|
||||
|
@ -3795,7 +3859,9 @@ agree, create a new GSUnicodeInlineString otherwise.
|
|||
if (_flags.wide == 1)
|
||||
obj = [obj initWithCharacters: _contents.u length: _count];
|
||||
else
|
||||
obj = [obj initWithCString: (char*)_contents.c length: _count];
|
||||
obj = [obj initWithBytes: (char*)_contents.c
|
||||
length: _count
|
||||
encoding: intEnc];
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -3808,7 +3874,9 @@ agree, create a new GSUnicodeInlineString otherwise.
|
|||
if (_flags.wide == 1)
|
||||
obj = [obj initWithCharacters: _contents.u length: _count];
|
||||
else
|
||||
obj = [obj initWithCString: (char*)_contents.c length: _count];
|
||||
obj = [obj initWithBytes: (char*)_contents.c
|
||||
length: _count
|
||||
encoding: intEnc];
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue