Fix stack overflow.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@17453 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2003-08-07 18:22:03 +00:00
parent c42c824740
commit d5867fd5a6
3 changed files with 132 additions and 126 deletions

View file

@ -3,7 +3,11 @@
* Source/NSString.m: nodeToObject() fix error in handling escape
sequences in strings ... only treat a backslash specially when it
is immediately followed by 'U' or 'u' and four hexadecimal digits.
ensure data ia deallocated promptly.
* Source/GSCompatibility.m: match changes to property list escapes
* Source/Additions/GSXML.m: change ownership policy so that nodes
are owned by theri parents, never by siblings ... prevent stack
overflow deallocating nodes in long documents.
* Tools/plist-0_9.dtd: document unicode escapes.
2003-08-02 Adam Fedor <fedor@gnu.org>

View file

@ -1340,7 +1340,7 @@ static NSMapTable *nodeNames = 0;
{
GSXMLNode *n = [GSXMLNode alloc];
n = [n _initFrom: ((xmlNodePtr)(lib))->next parent: self];
n = [n _initFrom: ((xmlNodePtr)(lib))->next parent: _parent];
return AUTORELEASE(n);
}
else
@ -1367,7 +1367,7 @@ static NSMapTable *nodeNames = 0;
{
GSXMLNode *n = [GSXMLNode alloc];
n = [n _initFrom: ptr parent: self];
n = [n _initFrom: ptr parent: _parent];
return AUTORELEASE(n);
}
}
@ -1476,7 +1476,7 @@ static NSMapTable *nodeNames = 0;
{
GSXMLNode *n = [GSXMLNode alloc];
n = [n _initFrom: ((xmlNodePtr)(lib))->prev parent: self];
n = [n _initFrom: ((xmlNodePtr)(lib))->prev parent: _parent];
return AUTORELEASE(n);
}
else
@ -1501,7 +1501,7 @@ static NSMapTable *nodeNames = 0;
{
GSXMLNode *n = [GSXMLNode alloc];
n = [n _initFrom: ptr parent: self];
n = [n _initFrom: ptr parent: _parent];
return AUTORELEASE(n);
}
}

View file

@ -46,6 +46,7 @@
#include <stdio.h>
#include <string.h>
#include "GNUstepBase/preface.h"
#include "Foundation/NSAutoreleasePool.h"
#include "Foundation/NSString.h"
#include "Foundation/NSCalendarDate.h"
#include "Foundation/NSArray.h"
@ -4988,163 +4989,164 @@ elementNode(GSXMLNode* node)
static id
nodeToObject(GSXMLNode* node)
{
NSString *name;
NSString *content;
GSXMLNode *children;
CREATE_AUTORELEASE_POOL(arp);
id result = nil;
node = elementNode(node);
if (node == nil)
if (node != nil)
{
return nil;
}
name = [node name];
children = [node firstChild];
content = [children content];
children = elementNode(children);
NSString *name;
NSString *content;
GSXMLNode *children;
if ([name isEqualToString: @"string"]
|| [name isEqualToString: @"key"])
{
if (content == nil)
{
content = @"";
}
else
{
NSRange r;
name = [node name];
children = [node firstChild];
content = [children content];
children = elementNode(children);
r = [content rangeOfString: @"\\"];
if (r.length == 1)
if ([name isEqualToString: @"string"]
|| [name isEqualToString: @"key"])
{
if (content == nil)
{
unsigned len = [content length];
unichar buf[len];
unsigned pos = r.location;
content = @"";
}
else
{
NSRange r;
[content getCharacters: buf];
while (pos < len)
r = [content rangeOfString: @"\\"];
if (r.length == 1)
{
if (++pos < len)
unsigned len = [content length];
unichar buf[len];
unsigned pos = r.location;
[content getCharacters: buf];
while (pos < len)
{
if ((buf[pos] == 'u' || buf[pos] == 'U')
&& (len >= pos + 4))
if (++pos < len)
{
unichar val = 0;
unsigned i;
BOOL ok = YES;
for (i = 1; i < 5; i++)
if ((buf[pos] == 'u' || buf[pos] == 'U')
&& (len >= pos + 4))
{
unichar c = buf[pos + i];
unichar val = 0;
unsigned i;
BOOL ok = YES;
if (c >= '0' && c <= '9')
for (i = 1; i < 5; i++)
{
val = (val << 4) + c - '0';
unichar c = buf[pos + i];
if (c >= '0' && c <= '9')
{
val = (val << 4) + c - '0';
}
else if (c >= 'A' && c <= 'F')
{
val = (val << 4) + c - 'A' + 10;
}
else if (c >= 'a' && c <= 'f')
{
val = (val << 4) + c - 'a' + 10;
}
else
{
ok = NO;
}
}
else if (c >= 'A' && c <= 'F')
if (ok == YES)
{
val = (val << 4) + c - 'A' + 10;
}
else if (c >= 'a' && c <= 'f')
{
val = (val << 4) + c - 'a' + 10;
}
else
{
ok = NO;
len -= 5;
memcpy(&buf[pos], &buf[pos+5],
(len - pos) * sizeof(unichar));
buf[pos - 1] = val;
}
}
if (ok == YES)
while (pos < len && buf[pos] != '\\')
{
len -= 5;
memcpy(&buf[pos], &buf[pos+5],
(len - pos) * sizeof(unichar));
buf[pos - 1] = val;
pos++;
}
}
while (pos < len && buf[pos] != '\\')
{
pos++;
}
}
content = [NSString stringWithCharacters: buf length: len];
}
content = [NSString stringWithCharacters: buf length: len];
}
result = content;
}
return content;
}
else if ([name isEqualToString: @"true"])
{
return [NSNumber numberWithBool: YES];
}
else if ([name isEqualToString: @"false"])
{
return [NSNumber numberWithBool: NO];
}
else if ([name isEqualToString: @"integer"])
{
if (content == nil)
else if ([name isEqualToString: @"true"])
{
content = @"0";
result = [NSNumber numberWithBool: YES];
}
return [NSNumber numberWithInt: [content intValue]];
}
else if ([name isEqualToString: @"real"])
{
if (content == nil)
else if ([name isEqualToString: @"false"])
{
content = @"0.0";
result = [NSNumber numberWithBool: NO];
}
return [NSNumber numberWithDouble: [content doubleValue]];
}
else if ([name isEqualToString: @"date"])
{
if (content == nil)
else if ([name isEqualToString: @"integer"])
{
content = @"";
if (content == nil)
{
content = @"0";
}
result = [NSNumber numberWithInt: [content intValue]];
}
return [NSCalendarDate dateWithString: content
calendarFormat: @"%Y-%m-%d %H:%M:%S %z"];
}
else if ([name isEqualToString: @"data"])
{
return [GSMimeDocument decodeBase64String: content];
}
// container class
else if ([name isEqualToString: @"array"])
{
NSMutableArray *container = [NSMutableArray array];
else if ([name isEqualToString: @"real"])
{
if (content == nil)
{
content = @"0.0";
}
result = [NSNumber numberWithDouble: [content doubleValue]];
}
else if ([name isEqualToString: @"date"])
{
if (content == nil)
{
content = @"";
}
result = [NSCalendarDate dateWithString: content
calendarFormat: @"%Y-%m-%d %H:%M:%S %z"];
}
else if ([name isEqualToString: @"data"])
{
result = [GSMimeDocument decodeBase64String: content];
}
// container class
else if ([name isEqualToString: @"array"])
{
NSMutableArray *container = [NSMutableArray array];
while (children != nil)
{
id val;
while (children != nil)
{
id val;
val = nodeToObject(children);
[container addObject: val];
children = elementNode([children next]);
}
return container;
}
else if ([name isEqualToString: @"dict"])
{
NSMutableDictionary *container = [NSMutableDictionary dictionary];
val = nodeToObject(children);
[container addObject: val];
children = [children nextElement];
}
result = container;
}
else if ([name isEqualToString: @"dict"])
{
NSMutableDictionary *container = [NSMutableDictionary dictionary];
while (children != nil)
{
NSString *key;
id val;
while (children != nil)
{
NSString *key;
id val;
key = nodeToObject(children);
children = elementNode([children next]);
val = nodeToObject(children);
children = elementNode([children next]);
[container setObject: val forKey: key];
}
return container;
}
else
{
return nil;
key = nodeToObject(children);
children = [children nextElement];
val = nodeToObject(children);
children = [children nextElement];
[container setObject: val forKey: key];
}
result = container;
}
}
RETAIN(result);
RELEASE(arp);
return AUTORELEASE(result);
}
#endif