Loading...
--- xnu/xnu-4570.41.2/libkern/c++/OSSerializeBinary.cpp
+++ xnu/xnu-3248.30.4/libkern/c++/OSSerializeBinary.cpp
@@ -69,13 +69,12 @@
unsigned int newCapacity;
size_t alignSize;
- if (os_add_overflow(size, 3, &alignSize)) return (false);
- alignSize &= ~3L;
- if (os_add_overflow(length, alignSize, &newCapacity)) return (false);
+ alignSize = ((size + 3) & ~3L);
+ newCapacity = length + alignSize;
if (newCapacity >= capacity)
{
newCapacity = (((newCapacity - 1) / capacityIncrement) + 1) * capacityIncrement;
- if (newCapacity > ensureCapacity(newCapacity)) return (false);
+ if (newCapacity < ensureCapacity(newCapacity)) return (false);
}
bcopy(bits, &data[length], size);
@@ -89,17 +88,21 @@
{
unsigned int newCapacity;
size_t alignSize;
-
- // add to tag array
- tags->setObject(o);
-
- if (os_add3_overflow(size, sizeof(key), 3, &alignSize)) return (false);
- alignSize &= ~3L;
- if (os_add_overflow(length, alignSize, &newCapacity)) return (false);
+ OSNumber * tagNum;
+
+ // build a tag
+ tagNum = OSNumber::withNumber(tag, 32);
+ tag++;
+ // add to tag dictionary
+ tags->setObject((const OSSymbol *) o, tagNum);
+ tagNum->release();
+
+ alignSize = ((size + sizeof(key) + 3) & ~3L);
+ newCapacity = length + alignSize;
if (newCapacity >= capacity)
{
newCapacity = (((newCapacity - 1) / capacityIncrement) + 1) * capacityIncrement;
- if (newCapacity > ensureCapacity(newCapacity)) return (false);
+ if (newCapacity < ensureCapacity(newCapacity)) return (false);
}
if (endCollection)
@@ -123,19 +126,19 @@
OSNumber * num;
OSSymbol * sym;
OSString * str;
- OSData * ldata;
+ OSData * data;
OSBoolean * boo;
- unsigned int tagIdx;
+ OSNumber * tagNum;
uint32_t i, key;
size_t len;
bool ok;
- tagIdx = tags->getNextIndexOfObject(o, 0);
+ tagNum = (OSNumber *)tags->getObject((const OSSymbol *) o);
// does it exist?
- if (-1U != tagIdx)
- {
- key = (kOSSerializeObject | tagIdx);
+ if (tagNum)
+ {
+ key = (kOSSerializeObject | tagNum->unsigned32BitValue());
if (endCollection)
{
endCollection = false;
@@ -155,9 +158,9 @@
const OSMetaClassBase * dictValue;
const OSMetaClassBase * nvalue = 0;
- dictKey = dict->dictionary[i].key;
- dictValue = dict->dictionary[i].value;
i++;
+ dictKey = dict->dictionary[i-1].key;
+ dictValue = dict->dictionary[i-1].value;
if (editor)
{
dictValue = nvalue = (*editor)(editRef, this, dict, dictKey, dictValue);
@@ -220,12 +223,12 @@
key = (kOSSerializeString | len);
ok = addBinaryObject(o, key, str->getCStringNoCopy(), len);
}
- else if ((ldata = OSDynamicCast(OSData, o)))
- {
- len = ldata->getLength();
- if (ldata->reserved && ldata->reserved->disableSerialization) len = 0;
+ else if ((data = OSDynamicCast(OSData, o)))
+ {
+ len = data->getLength();
+ if (data->reserved && data->reserved->disableSerialization) len = 0;
key = (kOSSerializeData | len);
- ok = addBinaryObject(o, key, ldata->getBytesNoCopy(), len);
+ ok = addBinaryObject(o, key, data->getBytesNoCopy(), len);
}
else return (false);
@@ -234,27 +237,20 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#define setAtIndex(v, idx, o) \
- if (idx >= v##Capacity) \
- { \
- if (v##Capacity >= v##CapacityMax) ok = false; \
- else \
- { \
- uint32_t ncap = v##Capacity + 64; \
- typeof(v##Array) nbuf = (typeof(v##Array)) kalloc_container(ncap * sizeof(o)); \
- if (!nbuf) ok = false; \
- else \
- { \
- if (v##Array) \
- { \
- bcopy(v##Array, nbuf, v##Capacity * sizeof(o)); \
- kfree(v##Array, v##Capacity * sizeof(o)); \
- } \
- v##Array = nbuf; \
- v##Capacity = ncap; \
- } \
- } \
- } \
+#define setAtIndex(v, idx, o) \
+ if (idx >= v##Capacity) \
+ { \
+ uint32_t ncap = v##Capacity + 64; \
+ typeof(v##Array) nbuf = (typeof(v##Array)) kalloc_container(ncap * sizeof(o)); \
+ if (!nbuf) ok = false; \
+ if (v##Array) \
+ { \
+ bcopy(v##Array, nbuf, v##Capacity * sizeof(o)); \
+ kfree(v##Array, v##Capacity * sizeof(o)); \
+ } \
+ v##Array = nbuf; \
+ v##Capacity = ncap; \
+ } \
if (ok) v##Array[idx] = o;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -264,12 +260,10 @@
{
OSObject ** objsArray;
uint32_t objsCapacity;
- enum { objsCapacityMax = 16*1024*1024 };
uint32_t objsIdx;
OSObject ** stackArray;
uint32_t stackCapacity;
- enum { stackCapacityMax = 64 };
uint32_t stackIdx;
OSObject * result;
@@ -292,9 +286,9 @@
bool ok;
if (errorString) *errorString = 0;
- if (bufferSize < sizeof(kOSSerializeBinarySignature)) return (NULL);
if (0 != strcmp(kOSSerializeBinarySignature, buffer)) return (NULL);
if (3 & ((uintptr_t) buffer)) return (NULL);
+ if (bufferSize < sizeof(kOSSerializeBinarySignature)) return (NULL);
bufferPos = sizeof(kOSSerializeBinarySignature);
next = (typeof(next)) (((uintptr_t) buffer) + bufferPos);
@@ -344,13 +338,13 @@
case kOSSerializeObject:
if (len >= objsIdx) break;
o = objsArray[len];
+ o->retain();
isRef = true;
break;
case kOSSerializeNumber:
bufferPos += sizeof(long long);
if (bufferPos > bufferSize) break;
- if ((len != 32) && (len != 64) && (len != 16) && (len != 8)) break;
value = next[1];
value <<= 32;
value |= next[0];
@@ -361,7 +355,6 @@
case kOSSerializeSymbol:
bufferPos += (wordLen * sizeof(uint32_t));
if (bufferPos > bufferSize) break;
- if (len < 2) break;
if (0 != ((const char *)next)[len-1]) break;
o = (OSObject *) OSSymbol::withCString((const char *) next);
next += wordLen;
@@ -394,36 +387,42 @@
if (!isRef)
{
setAtIndex(objs, objsIdx, o);
- if (!ok)
+ if (!ok) break;
+ objsIdx++;
+ }
+
+ if (dict)
+ {
+ if (sym)
{
- o->release();
- break;
- }
- objsIdx++;
- }
-
- if (dict)
- {
- if (!sym) sym = (OSSymbol *) o;
- else
+ DEBG("%s = %s\n", sym->getCStringNoCopy(), o->getMetaClass()->getClassName());
+ if (o != dict) ok = dict->setObject(sym, o);
+ o->release();
+ sym->release();
+ sym = 0;
+ }
+ else
{
- str = sym;
- sym = OSDynamicCast(OSSymbol, sym);
- if (!sym && (str = OSDynamicCast(OSString, str)))
+ sym = OSDynamicCast(OSSymbol, o);
+ if (!sym && (str = OSDynamicCast(OSString, o)))
{
sym = (OSSymbol *) OSSymbol::withString(str);
- ok = (sym != 0);
- if (!ok) break;
+ o->release();
+ o = 0;
}
- DEBG("%s = %s\n", sym->getCStringNoCopy(), o->getMetaClass()->getClassName());
- if (o != dict) ok = dict->setObject(sym, o);
- if (sym && (sym != str)) sym->release();
- sym = 0;
+ ok = (sym != 0);
}
}
- else if (array) ok = array->setObject(o);
- else if (set) ok = set->setObject(o);
- else if (result) ok = false;
+ else if (array)
+ {
+ ok = array->setObject(o);
+ o->release();
+ }
+ else if (set)
+ {
+ ok = set->setObject(o);
+ o->release();
+ }
else
{
assert(!parent);
@@ -432,12 +431,14 @@
if (!ok) break;
- if (end) parent = 0;
if (newCollect)
{
- stackIdx++;
- setAtIndex(stack, stackIdx, parent);
- if (!ok) break;
+ if (!end)
+ {
+ stackIdx++;
+ setAtIndex(stack, stackIdx, parent);
+ if (!ok) break;
+ }
DEBG("++stack[%d] %p\n", stackIdx, parent);
parent = o;
dict = newDict;
@@ -448,15 +449,11 @@
if (end)
{
- while (stackIdx)
- {
- parent = stackArray[stackIdx];
- DEBG("--stack[%d] %p\n", stackIdx, parent);
- stackIdx--;
- if (parent) break;
- }
- if (!parent) break;
- set = 0;
+ if (!stackIdx) break;
+ parent = stackArray[stackIdx];
+ DEBG("--stack[%d] %p\n", stackIdx, parent);
+ stackIdx--;
+ set = 0;
dict = 0;
array = 0;
if (!(dict = OSDynamicCast(OSDictionary, parent)))
@@ -467,14 +464,13 @@
}
DEBG("ret %p\n", result);
- if (!ok) result = 0;
-
- if (objsCapacity)
- {
- for (len = (result != 0); len < objsIdx; len++) objsArray[len]->release();
- kfree(objsArray, objsCapacity * sizeof(*objsArray));
- }
+ if (objsCapacity) kfree(objsArray, objsCapacity * sizeof(*objsArray));
if (stackCapacity) kfree(stackArray, stackCapacity * sizeof(*stackArray));
+ if (!ok && result)
+ {
+ result->release();
+ result = 0;
+ }
return (result);
}