git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@25554 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2007-11-05 11:30:23 +00:00
parent 51e7ad576b
commit 3ee4677362
3 changed files with 79 additions and 20 deletions

View file

@ -1,3 +1,11 @@
2007-11-05 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSXML.m: Make sloppy parser available for internal use when
parsing bad xml produced by Apple tools.
* Source/NSPropertyList.m: Use GSSloppyXMLParser if normal xml2 based
parsing fails due to Ap[ple4's inclusioon of illegal characters in
the XML.
2007-10-31 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSUserDefaults.m: ([setBoolForKey:]) changed to store YES

View file

@ -44,11 +44,14 @@
#include "Foundation/NSUserDefaults.h"
#include "Foundation/NSValue.h"
#include "Foundation/NSDebug.h"
#include "Foundation/NSNull.h"
#include "Foundation/NSXMLParser.h"
#include "GNUstepBase/Unicode.h"
#include "GSPrivate.h"
@class GSSloppyXMLParser;
extern BOOL GSScanDouble(unichar*, unsigned, double*);
@class GSMutableDictionary;
@ -103,7 +106,7 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
if ((self = [super init]) != nil)
{
stack = [[NSMutableArray alloc] initWithCapacity: 10];
theParser = [[NSXMLParser alloc] initWithData: data];
theParser = [[GSSloppyXMLParser alloc] initWithData: data];
[theParser setDelegate: self];
opts = options;
}
@ -113,11 +116,15 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
- (void) parser: (NSXMLParser *)parser
foundCharacters: (NSString *)string
{
if (value == nil)
string = [string stringByTrimmingSpaces];
if ([string length] > 0)
{
value = [[NSMutableString alloc] initWithCapacity: 50];
if (value == nil)
{
value = [[NSMutableString alloc] initWithCapacity: 50];
}
[value appendString: string];
}
[value appendString: string];
}
- (void) parser: (NSXMLParser *)parser
@ -130,6 +137,12 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
{
NSMutableDictionary *d;
if (key == nil)
{
key = RETAIN([NSNull null]);
}
[stack addObject: key];
DESTROY(key);
d = [[NSMutableDictionary alloc] initWithCapacity: 10];
[stack addObject: d];
RELEASE(d);
@ -140,6 +153,12 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
{
NSMutableArray *a;
if (key == nil)
{
key = RETAIN([NSNull null]);
}
[stack addObject: key];
DESTROY(key);
a = [[NSMutableArray alloc] initWithCapacity: 10];
[stack addObject: a];
RELEASE(a);
@ -174,13 +193,19 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
{
ASSIGN(plist, [[stack lastObject] makeImmutableCopyOnFail: NO]);
}
[stack removeLastObject];
inArray = NO;
inDictionary = NO;
ASSIGN(key, [stack lastObject]);
[stack removeLastObject];
if ((id)key == (id)[NSNull null])
{
DESTROY(key);
}
if ([stack count] > 0)
{
id last;
[stack removeLastObject];
last = [stack lastObject];
if ([last isKindOfClass: [NSArray class]] == YES)
{
@ -2584,6 +2609,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml,
parser = [GSXMLParser parser];
[parser substituteEntities: YES];
[parser doValidityChecking: YES];
[parser saveMessages: YES];
if ([parser parse: data] == NO || [parser parse: nil] == NO)
{
error = @"failed to parse as valid XML matching DTD";

View file

@ -33,7 +33,15 @@
NSString* const NSXMLParserErrorDomain = @"NSXMLParserErrorDomain";
#ifdef HAVE_LIBXML
#if defined(HAVE_LIBXML)
/* We support a strict libxml2 based parser ... but sometimes we need a
* sloppier parser which copes with bad XML generated by Apple's software,
* so we call the sloppy parser GSSloppyXMLParser.
*/
#define SloppyXMLParser GSSloppyXMLParser
@interface GSSloppyXMLParser : NSXMLParser
@end
#include <Additions/GNUstepBase/GSXML.h>
@ -442,6 +450,18 @@ NSString* const NSXMLParserErrorDomain = @"NSXMLParserErrorDomain";
#else
/* We have no strict libxml based parser, so we use the sloppy parser
* as the normal NSXMLParser and create a GSSloppyXMLParser subclass
* so that we can still specify GSSloppyXMLParser in other files.
*/
#define SloppyXMLParser NSXMLParser
@interface GSSloppyXMLParser : NSXMLParser
@end
@implementation GSSloppyXMLParser
@end
#endif
@implementation NSString (NSXMLParser)
- (NSString *) _stringByExpandingXMLEntities
@ -485,8 +505,13 @@ typedef struct NSXMLParserIvarsType
BOOL acceptHTML; // be lazy with bad tag nesting
} NSXMLParserIvars;
@implementation NSXMLParser
@implementation SloppyXMLParser
#define EXTRA_DEBUG 0
typedef struct { @defs(NSXMLParser) } *xp;
#define _parser (((xp)self)->_parser)
#define _handler (((xp)self)->_handler)
#define this ((NSXMLParserIvars*)_parser)
#define _del ((id)_handler)
@ -508,6 +533,8 @@ typedef struct NSXMLParserIvarsType
RELEASE(this->error);
RELEASE(this->tagPath);
NSZoneFree([self zone], this);
_parser = 0;
_handler = 0;
}
[super dealloc];
}
@ -568,7 +595,7 @@ typedef struct NSXMLParserIvarsType
- (BOOL) _parseError: (NSString *)message
{
#if 0
#if EXTRA_DEBUG
NSLog(@"XML parseError: %@", message);
#endif
NSError *err = nil;
@ -590,7 +617,7 @@ typedef struct NSXMLParserIvarsType
{
if ([tag isEqualToString: @"?xml"])
{
#if 0
#if EXTRA_DEBUG
NSLog(@"parserDidStartDocument: ");
#endif
if ([_del respondsToSelector: @selector(parserDidStartDocument:)])
@ -599,7 +626,7 @@ NSLog(@"parserDidStartDocument: ");
}
if ([tag hasPrefix: @"?"])
{
#if 0
#if EXTRA_DEBUG
NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
#endif
// parser: foundProcessingInstructionWithTarget: data:
@ -607,14 +634,14 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
}
if ([tag isEqualToString: @"!DOCTYPE"])
{
#if 0
#if EXTRA_DEBUG
NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
#endif
return;
}
if ([tag isEqualToString: @"!ENTITY"])
{
#if 0
#if EXTRA_DEBUG
NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
#endif
return;
@ -623,7 +650,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
{
// pass through as NSData
// parser: foundCDATA:
#if 0
#if EXTRA_DEBUG
NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
#endif
return;
@ -729,7 +756,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
const unsigned char *ap = --this->cp; // argument start pointer
int c = cget(); // refetch first character
#if 0
#if EXTRA_DEBUG
NSLog(@"_qarg: %02x %c", c, isprint(c)?c: ' ');
#endif
if (c == '\"')
@ -777,7 +804,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
while (!this->abort)
{
// parse next element
#if 0
#if EXTRA_DEBUG
NSLog(@"_nextelement %02x %c", c, isprint(c)?c: ' ');
#endif
switch(c)
@ -821,7 +848,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
[this->tagPath removeLastObject]; // pop from stack
}
}
#if 0
#if EXTRA_DEBUG
NSLog(@"parserDidEndDocument: ");
#endif
@ -878,7 +905,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
tag = UTF8STR(tp + 1, this->cp - tp - 2); // don't include / and delimiting character
else
tag = UTF8STR(tp, this->cp - tp - 1); // don't include delimiting character
#if 0
#if EXTRA_DEBUG
NSLog(@"tag=%@ - %02x %c", tag, c, isprint(c)?c: ' ');
#endif
parameters=[NSMutableDictionary dictionaryWithCapacity: 5];
@ -913,7 +940,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
break;
}
arg=[self _qarg]; // get next argument (eats up to /, ?, >, =, space)
#if 0
#if EXTRA_DEBUG
NSLog(@"arg=%@", arg);
#endif
if (!this->acceptHTML && [arg length] == 0)
@ -989,8 +1016,6 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
@end
#endif
@implementation NSObject (NSXMLParserDelegateEventAdditions)
- (NSData*) parser: (NSXMLParser*)aParser
resolveExternalEntityName: (NSString*)aName