mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-07 23:10:44 +00:00
recommit with bugfix decoding array count
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@34843 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
a4f2dd506a
commit
2c2bfccccb
1 changed files with 85 additions and 9 deletions
|
@ -433,14 +433,47 @@ static IMP _xRefImp; /* Serialize a crossref. */
|
||||||
count: (NSUInteger)expected
|
count: (NSUInteger)expected
|
||||||
at: (void*)buf
|
at: (void*)buf
|
||||||
{
|
{
|
||||||
unsigned int i;
|
NSUInteger i;
|
||||||
int offset = 0;
|
NSUInteger offset = 0;
|
||||||
int size = objc_sizeof_type(type);
|
unsigned size = objc_sizeof_type(type);
|
||||||
unsigned char info;
|
unsigned char info;
|
||||||
unsigned count;
|
NSUInteger count;
|
||||||
|
|
||||||
(*_dTagImp)(_src, dTagSel, &info, 0, &_cursor);
|
(*_dTagImp)(_src, dTagSel, &info, 0, &_cursor);
|
||||||
(*_dDesImp)(_src, dDesSel, &count, @encode(unsigned), &_cursor, nil);
|
if (_version > 12401)
|
||||||
|
{
|
||||||
|
uint8_t c;
|
||||||
|
|
||||||
|
/* Unpack variable length count.
|
||||||
|
*/
|
||||||
|
count = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (count * 128 < count)
|
||||||
|
{
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"overflow in array count"];
|
||||||
|
}
|
||||||
|
count *= 128;
|
||||||
|
(*_dDesImp)(_src, dDesSel, &c, @encode(uint8_t), &_cursor, nil);
|
||||||
|
if (c & 128)
|
||||||
|
{
|
||||||
|
count += (c & 127);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count += c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned c;
|
||||||
|
|
||||||
|
(*_dDesImp)(_src, dDesSel, &c, @encode(unsigned), &_cursor, nil);
|
||||||
|
count = c;
|
||||||
|
}
|
||||||
if (info != _GSC_ARY_B)
|
if (info != _GSC_ARY_B)
|
||||||
{
|
{
|
||||||
[NSException raise: NSInternalInconsistencyException
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
@ -1101,11 +1134,33 @@ static IMP _xRefImp; /* Serialize a crossref. */
|
||||||
count: (NSUInteger)count
|
count: (NSUInteger)count
|
||||||
at: (const void*)buf
|
at: (const void*)buf
|
||||||
{
|
{
|
||||||
unsigned i;
|
NSUInteger i;
|
||||||
unsigned offset = 0;
|
unsigned c = count;
|
||||||
|
uint8_t bytes[20];
|
||||||
|
uint8_t *bytePtr = 0;
|
||||||
|
uint8_t byteCount = 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] > 12401)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
@ -1133,7 +1188,18 @@ static IMP _xRefImp; /* Serialize a crossref. */
|
||||||
if (_initialPass == NO)
|
if (_initialPass == NO)
|
||||||
{
|
{
|
||||||
(*_eTagImp)(_dst, eTagSel, _GSC_ARY_B);
|
(*_eTagImp)(_dst, eTagSel, _GSC_ARY_B);
|
||||||
(*_eSerImp)(_dst, eSerSel, &count, @encode(unsigned), nil);
|
if (0 == byteCount)
|
||||||
|
{
|
||||||
|
(*_eSerImp)(_dst, eSerSel, &c, @encode(unsigned), nil);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < byteCount; i++)
|
||||||
|
{
|
||||||
|
(*_eSerImp)
|
||||||
|
(_dst, eSerSel, bytePtr + i, @encode(uint8_t), nil);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
|
@ -1144,7 +1210,17 @@ static IMP _xRefImp; /* Serialize a crossref. */
|
||||||
else if (_initialPass == NO)
|
else if (_initialPass == NO)
|
||||||
{
|
{
|
||||||
(*_eTagImp)(_dst, eTagSel, _GSC_ARY_B);
|
(*_eTagImp)(_dst, eTagSel, _GSC_ARY_B);
|
||||||
(*_eSerImp)(_dst, eSerSel, &count, @encode(unsigned), nil);
|
if (0 == byteCount)
|
||||||
|
{
|
||||||
|
(*_eSerImp)(_dst, eSerSel, &c, @encode(unsigned), nil);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < byteCount; i++)
|
||||||
|
{
|
||||||
|
(*_eSerImp)(_dst, eSerSel, bytePtr + i, @encode(uint8_t), nil);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(*_eTagImp)(_dst, eTagSel, info);
|
(*_eTagImp)(_dst, eTagSel, info);
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
|
|
Loading…
Reference in a new issue