Author: thebeing
Date: Fri Aug 7 17:06:38 2015
New Revision: 38859
URL: http://svn.gna.org/viewcvs/gnustep?rev=38859&view=rev
Log:
Safety fix for parsing binary property lists
Added:
libs/base/trunk/Tests/base/PropertyLists/cyclic.plist (with props)
Modified:
libs/base/trunk/ChangeLog
libs/base/trunk/Source/NSPropertyList.m
libs/base/trunk/Tests/base/PropertyLists/test01.m
Modified: libs/base/trunk/ChangeLog
URL:
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/ChangeLog?rev=38859&r1=38858&r2=38859&view=diff
==============================================================================
--- libs/base/trunk/ChangeLog (original)
+++ libs/base/trunk/ChangeLog Fri Aug 7 17:06:38 2015
@@ -1,3 +1,11 @@
+2015-08-07 Niels Grewe <[email protected]>
+
+ * Source/NSPropertyList.m: Cope with certain malformed binary
+ property lists.
+ * Tests/PropertyLists/test01.m
+ * Tests/PropertyLists/cyclic.plist:
+ Test case for binary plists.
+
2015-08-05 Riccardo Mottola <[email protected]>
* Source/NSArray.m:
Modified: libs/base/trunk/Source/NSPropertyList.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/NSPropertyList.m?rev=38859&r1=38858&r2=38859&view=diff
==============================================================================
--- libs/base/trunk/Source/NSPropertyList.m (original)
+++ libs/base/trunk/Source/NSPropertyList.m Fri Aug 7 17:06:38 2015
@@ -36,6 +36,7 @@
#import "Foundation/NSEnumerator.h"
#import "Foundation/NSError.h"
#import "Foundation/NSException.h"
+#import "Foundation/NSHashTable.h"
#import "Foundation/NSPropertyList.h"
#import "Foundation/NSSerialization.h"
#import "Foundation/NSStream.h"
@@ -457,6 +458,7 @@
unsigned object_count; // Number of objects
unsigned root_index; // Index of root object
unsigned table_start; // Start address of object table
+ NSHashTable *_stack; // The stack of objects we are currently
parsing
}
- (id) initWithData: (NSData*)plData
@@ -2774,10 +2776,18 @@
@implementation GSBinaryPLParser
+#define PUSH_OBJ(index) if (NO == [self _pushObject: index]) \
+ { \
+ [NSException raise: NSGenericException \
+ format: @"Cyclic object graph"]; \
+ }
+
+#define POP_OBJ(index) do { [self _popObject: index]; } while (0)
- (void) dealloc
{
DESTROY(data);
+ DESTROY(_stack);
[super dealloc];
}
@@ -2945,6 +2955,28 @@
return [self objectAtIndex: root_index];
}
+- (BOOL)_pushObject: (NSUInteger)index
+{
+ uintptr_t val;
+ if (nil == _stack)
+ {
+ _stack = NSCreateHashTable(NSIntegerHashCallBacks,
+ 5);
+ }
+ val = (index == 0) ? UINTPTR_MAX : (uintptr_t)(void*)index;
+ // NSHashInsertIfAbsent() returns NULL on success
+ return NO == NSHashInsertIfAbsent(_stack, (void*)val);
+}
+
+- (void)_popObject: (NSUInteger)index
+{
+ if (_stack != nil)
+ {
+ uintptr_t val = (index == 0) ? UINTPTR_MAX : (uintptr_t)(void*)index;
+ NSHashRemove(_stack, (void*)val);
+ }
+}
+
- (id) objectAtIndex: (NSUInteger)index
{
unsigned char next;
@@ -3148,14 +3180,14 @@
unsigned len = next - 0xA0;
unsigned i;
id objects[len];
-
+ PUSH_OBJ(index);
for (i = 0; i < len; i++)
{
int oid = [self readObjectIndexAt: &counter];
objects[i] = [self objectAtIndex: oid];
}
-
+ POP_OBJ(index);
if (mutability == NSPropertyListMutableContainersAndLeaves
|| mutability == NSPropertyListMutableContainers)
{
@@ -3175,14 +3207,14 @@
len = [self readCountAt: &counter];
objects = NSAllocateCollectable(sizeof(id) * len, NSScannedOption);
-
+ PUSH_OBJ(index);
for (i = 0; i < len; i++)
{
int oid = [self readObjectIndexAt: &counter];
objects[i] = [self objectAtIndex: oid];
}
-
+ POP_OBJ(index);
if (mutability == NSPropertyListMutableContainersAndLeaves
|| mutability == NSPropertyListMutableContainers)
{
@@ -3201,14 +3233,13 @@
unsigned i;
id keys[len];
id values[len];
-
+ PUSH_OBJ(index);
for (i = 0; i < len; i++)
{
int oid = [self readObjectIndexAt: &counter];
keys[i] = [self objectAtIndex: oid];
}
-
for (i = 0; i < len; i++)
{
int oid = [self readObjectIndexAt: &counter];
@@ -3216,6 +3247,7 @@
values[i] = [self objectAtIndex: oid];
}
+ POP_OBJ(index);
if (mutability == NSPropertyListMutableContainersAndLeaves
|| mutability == NSPropertyListMutableContainers)
{
@@ -3241,6 +3273,7 @@
len = [self readCountAt: &counter];
keys = NSAllocateCollectable(sizeof(id) * len * 2, NSScannedOption);
values = keys + len;
+ PUSH_OBJ(index);
for (i = 0; i < len; i++)
{
int oid = [self readObjectIndexAt: &counter];
@@ -3254,7 +3287,7 @@
values[i] = [self objectAtIndex: oid];
}
-
+ POP_OBJ(index);
if (mutability == NSPropertyListMutableContainersAndLeaves
|| mutability == NSPropertyListMutableContainers)
{
@@ -3278,7 +3311,8 @@
return result;
}
-
+#undef PUSH_OBJ
+#undef POP_OBJ
@end
/* Test two items for equality ... both are objects.
Added: libs/base/trunk/Tests/base/PropertyLists/cyclic.plist
URL:
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Tests/base/PropertyLists/cyclic.plist?rev=38859&view=auto
==============================================================================
Binary file - no diff available.
Propchange: libs/base/trunk/Tests/base/PropertyLists/cyclic.plist
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: libs/base/trunk/Tests/base/PropertyLists/test01.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Tests/base/PropertyLists/test01.m?rev=38859&r1=38858&r2=38859&view=diff
==============================================================================
--- libs/base/trunk/Tests/base/PropertyLists/test01.m (original)
+++ libs/base/trunk/Tests/base/PropertyLists/test01.m Fri Aug 7 17:06:38 2015
@@ -329,6 +329,21 @@
}
#endif
+#if defined(GNUSTEP_BASE_LIBRARY)
+{
+ NSData *d = [NSData dataWithContentsOfFile: @"cyclic.plist"];
+ NSPropertyListFormat format;
+ id u = nil;
+ PASS_EXCEPTION(
+ u = [NSPropertyListSerialization propertyListFromData: d
+ mutabilityOption: NSPropertyListImmutable
+ format: &format
+ errorDescription: 0];, NSGenericException, "Does not crash on binary plist
with cyclic references." );
+ PASS(nil == u, "Rejects cyclic plist");
+}
+#endif
+
+
[arp release]; arp = nil;
return 0;
}
_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs