revise archive format.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@34832 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2012-02-27 20:07:05 +00:00
parent 3b76abbaae
commit 3aee9ca4ba
3 changed files with 93 additions and 12 deletions

View file

@ -1,3 +1,12 @@
2012-02-28 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSArchiver.m:
* Source/NSUnarchiver.m:
Revise archive format to allow for variable sized array counts ...
original versionallowed for variable encodings of integral types in
archived data, but not for the count of the nuymber of items in the
array :-(
2012-02-27 Fred Kiefer <FredKiefer@gmx.de> 2012-02-27 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSXMLNode.m (-copyWithZone:): Copy name spaces as well. * Source/NSXMLNode.m (-copyWithZone:): Copy name spaces as well.

View file

@ -254,12 +254,33 @@ static Class NSMutableDataMallocClass;
count: (NSUInteger)count count: (NSUInteger)count
at: (const void*)buf at: (const void*)buf
{ {
NSUInteger c = count; unsigned c = count;
uint8_t bytes[20];
uint8_t *bytePtr = 0;
uint8_t byteCount = 0;
NSUInteger i; NSUInteger i;
NSUInteger offset = 0; NSUInteger offset = 0;
unsigned size = objc_sizeof_type(type); unsigned size = objc_sizeof_type(type);
uchar info; uchar info;
/* The array count is encoded as a sequence of bytes containing 7bits of
* data and using the eighth (top) bit to indicate that there are more
* bytes in the sequence.
*/
if ([self systemVersion] >= ((((1 * 100) + 24) * 100) + 1))
{
NSUInteger tmp = count;
bytes[sizeof(bytes) - ++byteCount] = (uint8_t)(tmp % 128);
tmp /= 128;
while (tmp > 0)
{
bytes[sizeof(bytes) - ++byteCount] = (uint8_t)(128 | (tmp % 128));
tmp /= 128;
}
bytePtr = &bytes[sizeof(bytes) - byteCount];
}
switch (*type) switch (*type)
{ {
case _C_ID: info = _GSC_NONE; break; case _C_ID: info = _GSC_NONE; break;
@ -287,8 +308,20 @@ static Class NSMutableDataMallocClass;
if (_initialPass == NO) if (_initialPass == NO)
{ {
(*_tagImp)(_dst, tagSel, _GSC_ARY_B); (*_tagImp)(_dst, tagSel, _GSC_ARY_B);
(*_serImp)(_dst, serSel, &c, @encode(NSUInteger), nil); if (0 == byteCount)
{
(*_serImp)(_dst, serSel, &c, @encode(unsigned), nil);
}
else
{
i = byteCount;
for (i = 0; i < byteCount; i++)
{
(*_serImp)(_dst, serSel, bytePtr + i, @encode(uint8_t), nil);
}
}
} }
for (i = 0; i < c; i++) for (i = 0; i < c; i++)
{ {
(*_eValImp)(self, eValSel, type, (char*)buf + offset); (*_eValImp)(self, eValSel, type, (char*)buf + offset);
@ -298,10 +331,21 @@ static Class NSMutableDataMallocClass;
else if (_initialPass == NO) else if (_initialPass == NO)
{ {
(*_tagImp)(_dst, tagSel, _GSC_ARY_B); (*_tagImp)(_dst, tagSel, _GSC_ARY_B);
(*_serImp)(_dst, serSel, &c, @encode(NSUInteger), nil); if (0 == byteCount)
{
(*_serImp)(_dst, serSel, &c, @encode(unsigned), nil);
}
else
{
i = byteCount;
for (i = 0; i < byteCount; i++)
{
(*_serImp)(_dst, serSel, bytePtr + i, @encode(uint8_t), nil);
}
}
(*_tagImp)(_dst, tagSel, info); (*_tagImp)(_dst, tagSel, info);
for (i = 0; i < c; i++) for (i = 0; i < count; i++)
{ {
(*_serImp)(_dst, serSel, (char*)buf + offset, type, nil); (*_serImp)(_dst, serSel, (char*)buf + offset, type, nil);
offset += size; offset += size;
@ -320,7 +364,7 @@ static Class NSMutableDataMallocClass;
case _C_ARY_B: case _C_ARY_B:
{ {
NSUInteger count = atoll(++type); unsigned count = atoi(++type);
while (isdigit(*type)) while (isdigit(*type))
{ {
@ -734,9 +778,9 @@ static Class NSMutableDataMallocClass;
- (void) encodeDataObject: (NSData*)anObject - (void) encodeDataObject: (NSData*)anObject
{ {
NSUInteger l = [anObject length]; unsigned l = [anObject length];
(*_eValImp)(self, eValSel, @encode(NSUInteger), &l); (*_eValImp)(self, eValSel, @encode(unsigned int), &l);
if (l) if (l)
{ {
const void *b = [anObject bytes]; const void *b = [anObject bytes];

View file

@ -531,12 +531,40 @@ static Class NSDataMallocClass;
{ {
NSUInteger i; NSUInteger i;
NSUInteger offset = 0; NSUInteger offset = 0;
NSUInteger size = (unsigned int)objc_sizeof_type(type); unsigned int size = (unsigned int)objc_sizeof_type(type);
unsigned char info; unsigned char info;
NSUInteger count; NSUInteger count;
(*tagImp)(src, tagSel, &info, 0, &cursor); (*tagImp)(src, tagSel, &info, 0, &cursor);
(*desImp)(src, desSel, &count, @encode(NSUInteger), &cursor, nil); if ([self systemVersion] >= ((((1 * 100) + 24) * 100) + 1))
{
uint8_t c;
/* Unpack variable length count.
*/
count = 0;
for (;;)
{
count *= 128;
(*desImp)(src, desSel, &c, @encode(uint8_t), &cursor, nil);
if (c & 128)
{
count += (c & 127);
}
else
{
count += c;
break;
}
}
}
else
{
unsigned c;
(*desImp)(src, desSel, &c, @encode(unsigned), &cursor, nil);
count = c;
}
if (info != _GSC_ARY_B) if (info != _GSC_ARY_B)
{ {
[NSException raise: NSInternalInconsistencyException [NSException raise: NSInternalInconsistencyException
@ -545,7 +573,7 @@ static Class NSDataMallocClass;
if (count != expected) if (count != expected)
{ {
[NSException raise: NSInternalInconsistencyException [NSException raise: NSInternalInconsistencyException
format: @"expected array count %"PRIuPTR" and got %"PRIuPTR, format: @"expected array count %u and got %u",
expected, count]; expected, count];
} }
@ -1219,9 +1247,9 @@ static Class NSDataMallocClass;
- (NSData*) decodeDataObject - (NSData*) decodeDataObject
{ {
NSUInteger l; unsigned l;
(*dValImp)(self, dValSel, @encode(NSUInteger), &l); (*dValImp)(self, dValSel, @encode(unsigned int), &l);
if (l) if (l)
{ {
unsigned char c; unsigned char c;