mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +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
bc30035fa1
commit
a4baa9584d
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/GSString.m: validate UTF-16 data when producing a Cstring
|
||||||
* Source/NSCharacterSetData.h: Add code plane 16 (private use)
|
* Source/NSCharacterSetData.h: Add code plane 16 (private use)
|
||||||
* Source/NSCharacterSet.m: Fix to support code plane 16
|
* 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>
|
2006-05-11 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
|
|
@ -2681,7 +2681,9 @@ transmute(GSStr self, NSString *aString)
|
||||||
|
|
||||||
obj = (GSMutableString*)NSAllocateObject(GSMutableStringClass, 0,
|
obj = (GSMutableString*)NSAllocateObject(GSMutableStringClass, 0,
|
||||||
NSDefaultMallocZone());
|
NSDefaultMallocZone());
|
||||||
obj = [obj initWithCString: (char*)_contents.c length: _count];
|
obj = [obj initWithBytes: (char*)_contents.c
|
||||||
|
length: _count
|
||||||
|
encoding: intEnc];
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3562,6 +3564,158 @@ agree, create a new GSUnicodeInlineString otherwise.
|
||||||
return [self initWithCapacity: 0];
|
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
|
- (id) initWithCapacity: (unsigned)capacity
|
||||||
{
|
{
|
||||||
if (capacity < 2)
|
if (capacity < 2)
|
||||||
|
@ -3585,110 +3739,20 @@ agree, create a new GSUnicodeInlineString otherwise.
|
||||||
length: (unsigned int)length
|
length: (unsigned int)length
|
||||||
freeWhenDone: (BOOL)flag
|
freeWhenDone: (BOOL)flag
|
||||||
{
|
{
|
||||||
BOOL isASCII;
|
return [self initWithBytesNoCopy: (void*)chars
|
||||||
BOOL isLatin1;
|
length: length*sizeof(unichar)
|
||||||
|
encoding: NSUnicodeStringEncoding
|
||||||
if (GSUnicode(chars, length, &isASCII, &isLatin1) != length)
|
freeWhenDone: flag];
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithCStringNoCopy: (char*)chars
|
- (id) initWithCStringNoCopy: (char*)chars
|
||||||
length: (unsigned int)length
|
length: (unsigned int)length
|
||||||
freeWhenDone: (BOOL)flag
|
freeWhenDone: (BOOL)flag
|
||||||
{
|
{
|
||||||
if (defEnc != intEnc)
|
return [self initWithBytesNoCopy: (void*)chars
|
||||||
{
|
length: length
|
||||||
unichar *u = 0;
|
encoding: defEnc
|
||||||
unsigned l = 0;
|
freeWhenDone: flag];
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithFormat: (NSString*)format
|
- (id) initWithFormat: (NSString*)format
|
||||||
|
@ -3795,7 +3859,9 @@ agree, create a new GSUnicodeInlineString otherwise.
|
||||||
if (_flags.wide == 1)
|
if (_flags.wide == 1)
|
||||||
obj = [obj initWithCharacters: _contents.u length: _count];
|
obj = [obj initWithCharacters: _contents.u length: _count];
|
||||||
else
|
else
|
||||||
obj = [obj initWithCString: (char*)_contents.c length: _count];
|
obj = [obj initWithBytes: (char*)_contents.c
|
||||||
|
length: _count
|
||||||
|
encoding: intEnc];
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3808,7 +3874,9 @@ agree, create a new GSUnicodeInlineString otherwise.
|
||||||
if (_flags.wide == 1)
|
if (_flags.wide == 1)
|
||||||
obj = [obj initWithCharacters: _contents.u length: _count];
|
obj = [obj initWithCharacters: _contents.u length: _count];
|
||||||
else
|
else
|
||||||
obj = [obj initWithCString: (char*)_contents.c length: _count];
|
obj = [obj initWithBytes: (char*)_contents.c
|
||||||
|
length: _count
|
||||||
|
encoding: intEnc];
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue