Loading...
libkern/c++/OSSerializeBinary.cpp xnu-12377.101.15 xnu-4903.270.47
--- xnu/xnu-12377.101.15/libkern/c++/OSSerializeBinary.cpp
+++ xnu/xnu-4903.270.47/libkern/c++/OSSerializeBinary.cpp
@@ -27,13 +27,10 @@
  */
 
 
-#include <libkern/c++/OSSharedPtr.h>
-#include <libkern/OSSerializeBinary.h>
 #include <libkern/c++/OSContainers.h>
 #include <libkern/c++/OSLib.h>
 #include <libkern/c++/OSDictionary.h>
 #include <libkern/OSSerializeBinary.h>
-#include <libkern/c++/OSSharedPtr.h>
 
 #include <IOKit/IOLib.h>
 
@@ -54,11 +51,11 @@
 	OSSerialize *me;
 
 	if (inCapacity < sizeof(uint32_t)) {
-		return NULL;
+		return 0;
 	}
 	me = OSSerialize::withCapacity(inCapacity);
 	if (!me) {
-		return NULL;
+		return 0;
 	}
 
 	me->binary        = true;
@@ -101,38 +98,17 @@
 	return true;
 }
 
-void
-OSSerialize::setIndexed(bool index __unused)
-{
-	assert(index && !indexData);
-	indexData = OSData::withCapacity(256);
-	assert(indexData);
-}
-
 bool
 OSSerialize::addBinaryObject(const OSMetaClassBase * o, uint32_t key,
-    const void * bits, uint32_t size,
-    uint32_t * startCollection)
+    const void * bits, size_t size)
 {
 	unsigned int newCapacity;
 	size_t       alignSize;
-	size_t       headerSize;
 
 	// add to tag array
 	tags->setObject(o);
 
-	headerSize = sizeof(key);
-	if (indexData) {
-		uint32_t offset = length;
-		if (startCollection) {
-			*startCollection = offset;
-			headerSize += sizeof(uint32_t);
-		}
-		offset /= sizeof(uint32_t);
-		indexData->appendValue(offset);
-	}
-
-	if (os_add3_overflow(size, headerSize, 3, &alignSize)) {
+	if (os_add3_overflow(size, sizeof(key), 3, &alignSize)) {
 		return false;
 	}
 	alignSize &= ~3L;
@@ -155,58 +131,14 @@
 	}
 
 	bcopy(&key, &data[length], sizeof(key));
-	bcopy(bits, &data[length + headerSize], size);
+	bcopy(bits, &data[length + sizeof(key)], size);
 	length += alignSize;
 
 	return true;
 }
 
-void
-OSSerialize::endBinaryCollection(uint32_t startCollection)
-{
-	uint32_t clength;
-
-	if (!indexData) {
-		return;
-	}
-
-	assert(length > startCollection);
-	if (length <= startCollection) {
-		return;
-	}
-
-	clength = length - startCollection;
-	assert(!(clength & 3));
-	clength /= sizeof(uint32_t);
-
-	memcpy(&data[startCollection + sizeof(uint32_t)], &clength, sizeof(clength));
-}
-
 bool
 OSSerialize::binarySerialize(const OSMetaClassBase *o)
-{
-	bool ok;
-	uint32_t header;
-
-	ok = binarySerializeInternal(o);
-	if (!ok) {
-		return ok;
-	}
-
-	if (indexData) {
-		header = indexData->getLength() / sizeof(uint32_t);
-		assert(header <= kOSSerializeDataMask);
-		header <<= 8;
-		header |= kOSSerializeIndexedBinarySignature;
-
-		memcpy(&data[0], &header, sizeof(header));
-	}
-
-	return ok;
-}
-
-bool
-OSSerialize::binarySerializeInternal(const OSMetaClassBase *o)
 {
 	OSDictionary * dict;
 	OSArray      * array;
@@ -218,18 +150,13 @@
 	OSBoolean    * boo;
 
 	unsigned int  tagIdx;
-	uint32_t   i, key, startCollection = 0;
-	uint32_t   len;
+	uint32_t   i, key;
+	size_t     len;
 	bool       ok;
 
 	tagIdx = tags->getNextIndexOfObject(o, 0);
 	// does it exist?
 	if (-1U != tagIdx) {
-		if (indexData) {
-			assert(indexData->getLength() > (tagIdx * sizeof(uint32_t)));
-			tagIdx = ((const uint32_t *)indexData->getBytesNoCopy())[tagIdx];
-			assert(tagIdx <= kOSSerializeDataMask);
-		}
 		key = (kOSSerializeObject | tagIdx);
 		if (endCollection) {
 			endCollection = false;
@@ -241,11 +168,11 @@
 
 	if ((dict = OSDynamicCast(OSDictionary, o))) {
 		key = (kOSSerializeDictionary | dict->count);
-		ok = addBinaryObject(o, key, NULL, 0, &startCollection);
+		ok = addBinaryObject(o, key, NULL, 0);
 		for (i = 0; ok && (i < dict->count);) {
 			const OSSymbol        * dictKey;
 			const OSMetaClassBase * dictValue;
-			const OSMetaClassBase * nvalue = NULL;
+			const OSMetaClassBase * nvalue = 0;
 
 			dictKey = dict->dictionary[i].key;
 			dictValue = dict->dictionary[i].value;
@@ -270,10 +197,9 @@
 			}
 //			if (!ok) ok = binarySerialize(kOSBooleanFalse);
 		}
-		endBinaryCollection(startCollection);
 	} else if ((array = OSDynamicCast(OSArray, o))) {
 		key = (kOSSerializeArray | array->count);
-		ok = addBinaryObject(o, key, NULL, 0, &startCollection);
+		ok = addBinaryObject(o, key, NULL, 0);
 		for (i = 0; ok && (i < array->count);) {
 			i++;
 			endCollection = (i == array->count);
@@ -283,10 +209,9 @@
 			}
 //			if (!ok) ok = binarySerialize(kOSBooleanFalse);
 		}
-		endBinaryCollection(startCollection);
 	} else if ((set = OSDynamicCast(OSSet, o))) {
 		key = (kOSSerializeSet | set->members->count);
-		ok = addBinaryObject(o, key, NULL, 0, &startCollection);
+		ok = addBinaryObject(o, key, NULL, 0);
 		for (i = 0; ok && (i < set->members->count);) {
 			i++;
 			endCollection = (i == set->members->count);
@@ -296,28 +221,27 @@
 			}
 //			if (!ok) ok = binarySerialize(kOSBooleanFalse);
 		}
-		endBinaryCollection(startCollection);
 	} else if ((num = OSDynamicCast(OSNumber, o))) {
 		key = (kOSSerializeNumber | num->size);
-		ok = addBinaryObject(o, key, &num->value, sizeof(num->value), NULL);
+		ok = addBinaryObject(o, key, &num->value, sizeof(num->value));
 	} else if ((boo = OSDynamicCast(OSBoolean, o))) {
 		key = (kOSSerializeBoolean | (kOSBooleanTrue == boo));
-		ok = addBinaryObject(o, key, NULL, 0, NULL);
+		ok = addBinaryObject(o, key, NULL, 0);
 	} else if ((sym = OSDynamicCast(OSSymbol, o))) {
 		len = (sym->getLength() + 1);
 		key = (kOSSerializeSymbol | len);
-		ok = addBinaryObject(o, key, sym->getCStringNoCopy(), len, NULL);
+		ok = addBinaryObject(o, key, sym->getCStringNoCopy(), len);
 	} else if ((str = OSDynamicCast(OSString, o))) {
-		len = str->getLength();
+		len = (str->getLength() + 0);
 		key = (kOSSerializeString | len);
-		ok = addBinaryObject(o, key, str->getCStringNoCopy(), len, NULL);
+		ok = addBinaryObject(o, key, str->getCStringNoCopy(), len);
 	} else if ((ldata = OSDynamicCast(OSData, o))) {
 		len = ldata->getLength();
 		if (ldata->reserved && ldata->reserved->disableSerialization) {
 			len = 0;
 		}
 		key = (kOSSerializeData | len);
-		ok = addBinaryObject(o, key, ldata->getBytesNoCopy(), len, NULL);
+		ok = addBinaryObject(o, key, ldata->getBytesNoCopy(), len);
 	} else {
 		return false;
 	}
@@ -327,19 +251,28 @@
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-#define setAtIndex(v, idx, o)                                                  \
-	ok = idx < v##Capacity;                                                \
-	if (!ok && v##Capacity < v##CapacityMax) {                             \
-	    uint32_t ncap = v##Capacity + 64;                                  \
-	    typeof(v##Array) nbuf = kreallocp_type_container(OSObject *,       \
-	        v##Array, v##Capacity, &ncap, Z_WAITOK_ZERO);                  \
-	    if (nbuf) {                                                        \
-	        ok = true;                                                     \
-	        v##Array    = nbuf;                                            \
-	        v##Capacity = ncap;                                            \
-	    }                                                                  \
-	}                                                                      \
-	if (ok) v##Array[idx] = o
+#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;                                                                                                             \
+	    }                                                                                                                                   \
+	    }                                                                                                                                                       \
+	}                                                                                                                                                               \
+	if (ok) v##Array[idx] = o;
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
@@ -370,31 +303,23 @@
 
 	size_t           bufferPos;
 	const uint32_t * next;
-	uint32_t         key, len, wordLen, length;
+	uint32_t         key, len, wordLen;
 	bool             end, newCollect, isRef;
-	union {
-		unsigned long long value;
-		double fpValue;
-	} value;
-	bool ok, indexed, hasLength;
-
-	indexed = false;
+	unsigned long long value;
+	bool ok;
+
 	if (errorString) {
-		*errorString = NULL;
-	}
-
+		*errorString = 0;
+	}
 	if (bufferSize < sizeof(kOSSerializeBinarySignature)) {
 		return NULL;
 	}
-	if (kOSSerializeIndexedBinarySignature == (((const uint8_t *) buffer)[0])) {
-		indexed = true;
-	} else if (0 != strcmp(kOSSerializeBinarySignature, buffer)) {
+	if (0 != strcmp(kOSSerializeBinarySignature, buffer)) {
 		return NULL;
 	}
 	if (3 & ((uintptr_t) buffer)) {
 		return NULL;
 	}
-
 	bufferPos = sizeof(kOSSerializeBinarySignature);
 	next = (typeof(next))(((uintptr_t) buffer) + bufferPos);
 
@@ -404,12 +329,12 @@
 	objsIdx   = objsCapacity  = 0;
 	stackIdx  = stackCapacity = 0;
 
-	result   = NULL;
-	parent   = NULL;
-	dict     = NULL;
-	array    = NULL;
-	set      = NULL;
-	sym      = NULL;
+	result   = 0;
+	parent   = 0;
+	dict     = 0;
+	array    = 0;
+	set      = 0;
+	sym      = 0;
 
 	ok = true;
 	while (ok) {
@@ -418,31 +343,27 @@
 			break;
 		}
 		key = *next++;
-		length = 0;
 
 		len = (key & kOSSerializeDataMask);
 		wordLen = (len + 3) >> 2;
 		end = (0 != (kOSSerializeEndCollecton & key));
 		DEBG("key 0x%08x: 0x%04x, %d\n", key, len, end);
 
-		newCollect = isRef = hasLength = false;
-		o = NULL; newDict = NULL; newArray = NULL; newSet = NULL;
+		newCollect = isRef = false;
+		o = 0; newDict = 0; newArray = 0; newSet = 0;
 
 		switch (kOSSerializeTypeMask & key) {
 		case kOSSerializeDictionary:
 			o = newDict = OSDictionary::withCapacity(len);
 			newCollect = (len != 0);
-			hasLength  = indexed;
 			break;
 		case kOSSerializeArray:
 			o = newArray = OSArray::withCapacity(len);
 			newCollect = (len != 0);
-			hasLength  = indexed;
 			break;
 		case kOSSerializeSet:
 			o = newSet = OSSet::withCapacity(len);
 			newCollect = (len != 0);
-			hasLength  = indexed;
 			break;
 
 		case kOSSerializeObject:
@@ -458,23 +379,13 @@
 			if (bufferPos > bufferSize) {
 				break;
 			}
-			value.value = next[1];
-			value.value <<= 32;
-			value.value |= next[0];
-			switch (len) {
-			case 63:
-				o = OSNumber::withDouble(value.fpValue);
-				break;
-			case 31:
-				o = OSNumber::withFloat((float) value.fpValue);
-				break;
-			case 64:
-			case 32:
-			case 16:
-			case 8:
-				o = OSNumber::withNumber(value.value, len);
-				break;
-			}
+			if ((len != 32) && (len != 64) && (len != 16) && (len != 8)) {
+				break;
+			}
+			value = next[1];
+			value <<= 32;
+			value |= next[0];
+			o = OSNumber::withNumber(value, len);
 			next += 2;
 			break;
 
@@ -483,7 +394,7 @@
 			if (bufferPos > bufferSize) {
 				break;
 			}
-			if (len < 1) {
+			if (len < 2) {
 				break;
 			}
 			if (0 != ((const char *)next)[len - 1]) {
@@ -498,7 +409,7 @@
 			if (bufferPos > bufferSize) {
 				break;
 			}
-			o = OSString::withCString((const char *) next, len);
+			o = OSString::withStringOfLength((const char *) next, len);
 			next += wordLen;
 			break;
 
@@ -519,17 +430,8 @@
 			break;
 		}
 
-		if (!(ok = (o != NULL))) {
-			break;
-		}
-
-		if (hasLength) {
-			bufferPos += sizeof(*next);
-			if (!(ok = (bufferPos <= bufferSize))) {
-				o->release();
-				break;
-			}
-			length = *next++;
+		if (!(ok = (o != 0))) {
+			break;
 		}
 
 		if (!isRef) {
@@ -549,7 +451,7 @@
 				sym = OSDynamicCast(OSSymbol, sym);
 				if (!sym && (str = OSDynamicCast(OSString, str))) {
 					sym = const_cast<OSSymbol *>(OSSymbol::withString(str));
-					ok = (sym != NULL);
+					ok = (sym != 0);
 					if (!ok) {
 						break;
 					}
@@ -561,7 +463,7 @@
 				if (sym && (sym != str)) {
 					sym->release();
 				}
-				sym = NULL;
+				sym = 0;
 			}
 		} else if (array) {
 			ok = array->setObject(o);
@@ -579,7 +481,7 @@
 		}
 
 		if (end) {
-			parent = NULL;
+			parent = 0;
 		}
 		if (newCollect) {
 			stackIdx++;
@@ -607,12 +509,12 @@
 			if (!parent) {
 				break;
 			}
-			set   = NULL;
-			dict  = NULL;
-			array = NULL;
+			set   = 0;
+			dict  = 0;
+			array = 0;
 			if (!(dict = OSDynamicCast(OSDictionary, parent))) {
 				if (!(array = OSDynamicCast(OSArray, parent))) {
-					ok = (NULL != (set = OSDynamicCast(OSSet, parent)));
+					ok = (0 != (set = OSDynamicCast(OSSet, parent)));
 				}
 			}
 		}
@@ -620,59 +522,18 @@
 	DEBG("ret %p\n", result);
 
 	if (!ok) {
-		result = NULL;
+		result = 0;
 	}
 
 	if (objsCapacity) {
-		for (len = (result != NULL); len < objsIdx; len++) {
+		for (len = (result != 0); len < objsIdx; len++) {
 			objsArray[len]->release();
 		}
-		kfree_type(OSObject *, objsCapacity, objsArray);
+		kfree(objsArray, objsCapacity  * sizeof(*objsArray));
 	}
 	if (stackCapacity) {
-		kfree_type(OSObject *, stackCapacity, stackArray);
+		kfree(stackArray, stackCapacity * sizeof(*stackArray));
 	}
 
 	return result;
 }
-
-OSObject*
-OSUnserializeXML(
-	const char  * buffer,
-	OSSharedPtr<OSString>& errorString)
-{
-	OSString* errorStringRaw = NULL;
-	OSObject* result = OSUnserializeXML(buffer, &errorStringRaw);
-	errorString.reset(errorStringRaw, OSNoRetain);
-	return result;
-}
-
-OSObject*
-OSUnserializeXML(
-	const char  * buffer,
-	size_t        bufferSize,
-	OSSharedPtr<OSString> &errorString)
-{
-	OSString* errorStringRaw = NULL;
-	OSObject* result = OSUnserializeXML(buffer, bufferSize, &errorStringRaw);
-	errorString.reset(errorStringRaw, OSNoRetain);
-	return result;
-}
-
-OSObject*
-OSUnserializeBinary(const char *buffer, size_t bufferSize, OSSharedPtr<OSString>& errorString)
-{
-	OSString* errorStringRaw = NULL;
-	OSObject* result = OSUnserializeBinary(buffer, bufferSize, &errorStringRaw);
-	errorString.reset(errorStringRaw, OSNoRetain);
-	return result;
-}
-
-OSObject*
-OSUnserialize(const char *buffer, OSSharedPtr<OSString>& errorString)
-{
-	OSString* errorStringRaw = NULL;
-	OSObject* result = OSUnserialize(buffer, &errorStringRaw);
-	errorString.reset(errorStringRaw, OSNoRetain);
-	return result;
-}