mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
Fix for bug #17112
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@25554 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
51e7ad576b
commit
3ee4677362
3 changed files with 79 additions and 20 deletions
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue