mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 16:30:41 +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
87edda35d7
commit
9bea555194
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>
|
2007-10-31 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/NSUserDefaults.m: ([setBoolForKey:]) changed to store YES
|
* Source/NSUserDefaults.m: ([setBoolForKey:]) changed to store YES
|
||||||
|
|
|
@ -44,11 +44,14 @@
|
||||||
#include "Foundation/NSUserDefaults.h"
|
#include "Foundation/NSUserDefaults.h"
|
||||||
#include "Foundation/NSValue.h"
|
#include "Foundation/NSValue.h"
|
||||||
#include "Foundation/NSDebug.h"
|
#include "Foundation/NSDebug.h"
|
||||||
|
#include "Foundation/NSNull.h"
|
||||||
#include "Foundation/NSXMLParser.h"
|
#include "Foundation/NSXMLParser.h"
|
||||||
#include "GNUstepBase/Unicode.h"
|
#include "GNUstepBase/Unicode.h"
|
||||||
|
|
||||||
#include "GSPrivate.h"
|
#include "GSPrivate.h"
|
||||||
|
|
||||||
|
@class GSSloppyXMLParser;
|
||||||
|
|
||||||
extern BOOL GSScanDouble(unichar*, unsigned, double*);
|
extern BOOL GSScanDouble(unichar*, unsigned, double*);
|
||||||
|
|
||||||
@class GSMutableDictionary;
|
@class GSMutableDictionary;
|
||||||
|
@ -103,7 +106,7 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
|
||||||
if ((self = [super init]) != nil)
|
if ((self = [super init]) != nil)
|
||||||
{
|
{
|
||||||
stack = [[NSMutableArray alloc] initWithCapacity: 10];
|
stack = [[NSMutableArray alloc] initWithCapacity: 10];
|
||||||
theParser = [[NSXMLParser alloc] initWithData: data];
|
theParser = [[GSSloppyXMLParser alloc] initWithData: data];
|
||||||
[theParser setDelegate: self];
|
[theParser setDelegate: self];
|
||||||
opts = options;
|
opts = options;
|
||||||
}
|
}
|
||||||
|
@ -113,11 +116,15 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
|
||||||
- (void) parser: (NSXMLParser *)parser
|
- (void) parser: (NSXMLParser *)parser
|
||||||
foundCharacters: (NSString *)string
|
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
|
- (void) parser: (NSXMLParser *)parser
|
||||||
|
@ -130,6 +137,12 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
|
||||||
{
|
{
|
||||||
NSMutableDictionary *d;
|
NSMutableDictionary *d;
|
||||||
|
|
||||||
|
if (key == nil)
|
||||||
|
{
|
||||||
|
key = RETAIN([NSNull null]);
|
||||||
|
}
|
||||||
|
[stack addObject: key];
|
||||||
|
DESTROY(key);
|
||||||
d = [[NSMutableDictionary alloc] initWithCapacity: 10];
|
d = [[NSMutableDictionary alloc] initWithCapacity: 10];
|
||||||
[stack addObject: d];
|
[stack addObject: d];
|
||||||
RELEASE(d);
|
RELEASE(d);
|
||||||
|
@ -140,6 +153,12 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
|
||||||
{
|
{
|
||||||
NSMutableArray *a;
|
NSMutableArray *a;
|
||||||
|
|
||||||
|
if (key == nil)
|
||||||
|
{
|
||||||
|
key = RETAIN([NSNull null]);
|
||||||
|
}
|
||||||
|
[stack addObject: key];
|
||||||
|
DESTROY(key);
|
||||||
a = [[NSMutableArray alloc] initWithCapacity: 10];
|
a = [[NSMutableArray alloc] initWithCapacity: 10];
|
||||||
[stack addObject: a];
|
[stack addObject: a];
|
||||||
RELEASE(a);
|
RELEASE(a);
|
||||||
|
@ -174,13 +193,19 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
|
||||||
{
|
{
|
||||||
ASSIGN(plist, [[stack lastObject] makeImmutableCopyOnFail: NO]);
|
ASSIGN(plist, [[stack lastObject] makeImmutableCopyOnFail: NO]);
|
||||||
}
|
}
|
||||||
|
[stack removeLastObject];
|
||||||
inArray = NO;
|
inArray = NO;
|
||||||
inDictionary = NO;
|
inDictionary = NO;
|
||||||
|
ASSIGN(key, [stack lastObject]);
|
||||||
|
[stack removeLastObject];
|
||||||
|
if ((id)key == (id)[NSNull null])
|
||||||
|
{
|
||||||
|
DESTROY(key);
|
||||||
|
}
|
||||||
if ([stack count] > 0)
|
if ([stack count] > 0)
|
||||||
{
|
{
|
||||||
id last;
|
id last;
|
||||||
|
|
||||||
[stack removeLastObject];
|
|
||||||
last = [stack lastObject];
|
last = [stack lastObject];
|
||||||
if ([last isKindOfClass: [NSArray class]] == YES)
|
if ([last isKindOfClass: [NSArray class]] == YES)
|
||||||
{
|
{
|
||||||
|
@ -2584,6 +2609,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml,
|
||||||
parser = [GSXMLParser parser];
|
parser = [GSXMLParser parser];
|
||||||
[parser substituteEntities: YES];
|
[parser substituteEntities: YES];
|
||||||
[parser doValidityChecking: YES];
|
[parser doValidityChecking: YES];
|
||||||
|
[parser saveMessages: YES];
|
||||||
if ([parser parse: data] == NO || [parser parse: nil] == NO)
|
if ([parser parse: data] == NO || [parser parse: nil] == NO)
|
||||||
{
|
{
|
||||||
error = @"failed to parse as valid XML matching DTD";
|
error = @"failed to parse as valid XML matching DTD";
|
||||||
|
|
|
@ -33,7 +33,15 @@
|
||||||
|
|
||||||
NSString* const NSXMLParserErrorDomain = @"NSXMLParserErrorDomain";
|
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>
|
#include <Additions/GNUstepBase/GSXML.h>
|
||||||
|
|
||||||
|
@ -442,6 +450,18 @@ NSString* const NSXMLParserErrorDomain = @"NSXMLParserErrorDomain";
|
||||||
|
|
||||||
#else
|
#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)
|
@implementation NSString (NSXMLParser)
|
||||||
|
|
||||||
- (NSString *) _stringByExpandingXMLEntities
|
- (NSString *) _stringByExpandingXMLEntities
|
||||||
|
@ -485,8 +505,13 @@ typedef struct NSXMLParserIvarsType
|
||||||
BOOL acceptHTML; // be lazy with bad tag nesting
|
BOOL acceptHTML; // be lazy with bad tag nesting
|
||||||
} NSXMLParserIvars;
|
} 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 this ((NSXMLParserIvars*)_parser)
|
||||||
#define _del ((id)_handler)
|
#define _del ((id)_handler)
|
||||||
|
|
||||||
|
@ -508,6 +533,8 @@ typedef struct NSXMLParserIvarsType
|
||||||
RELEASE(this->error);
|
RELEASE(this->error);
|
||||||
RELEASE(this->tagPath);
|
RELEASE(this->tagPath);
|
||||||
NSZoneFree([self zone], this);
|
NSZoneFree([self zone], this);
|
||||||
|
_parser = 0;
|
||||||
|
_handler = 0;
|
||||||
}
|
}
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
@ -568,7 +595,7 @@ typedef struct NSXMLParserIvarsType
|
||||||
|
|
||||||
- (BOOL) _parseError: (NSString *)message
|
- (BOOL) _parseError: (NSString *)message
|
||||||
{
|
{
|
||||||
#if 0
|
#if EXTRA_DEBUG
|
||||||
NSLog(@"XML parseError: %@", message);
|
NSLog(@"XML parseError: %@", message);
|
||||||
#endif
|
#endif
|
||||||
NSError *err = nil;
|
NSError *err = nil;
|
||||||
|
@ -590,7 +617,7 @@ typedef struct NSXMLParserIvarsType
|
||||||
{
|
{
|
||||||
if ([tag isEqualToString: @"?xml"])
|
if ([tag isEqualToString: @"?xml"])
|
||||||
{
|
{
|
||||||
#if 0
|
#if EXTRA_DEBUG
|
||||||
NSLog(@"parserDidStartDocument: ");
|
NSLog(@"parserDidStartDocument: ");
|
||||||
#endif
|
#endif
|
||||||
if ([_del respondsToSelector: @selector(parserDidStartDocument:)])
|
if ([_del respondsToSelector: @selector(parserDidStartDocument:)])
|
||||||
|
@ -599,7 +626,7 @@ NSLog(@"parserDidStartDocument: ");
|
||||||
}
|
}
|
||||||
if ([tag hasPrefix: @"?"])
|
if ([tag hasPrefix: @"?"])
|
||||||
{
|
{
|
||||||
#if 0
|
#if EXTRA_DEBUG
|
||||||
NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
||||||
#endif
|
#endif
|
||||||
// parser: foundProcessingInstructionWithTarget: data:
|
// parser: foundProcessingInstructionWithTarget: data:
|
||||||
|
@ -607,14 +634,14 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
||||||
}
|
}
|
||||||
if ([tag isEqualToString: @"!DOCTYPE"])
|
if ([tag isEqualToString: @"!DOCTYPE"])
|
||||||
{
|
{
|
||||||
#if 0
|
#if EXTRA_DEBUG
|
||||||
NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ([tag isEqualToString: @"!ENTITY"])
|
if ([tag isEqualToString: @"!ENTITY"])
|
||||||
{
|
{
|
||||||
#if 0
|
#if EXTRA_DEBUG
|
||||||
NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
|
@ -623,7 +650,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
||||||
{
|
{
|
||||||
// pass through as NSData
|
// pass through as NSData
|
||||||
// parser: foundCDATA:
|
// parser: foundCDATA:
|
||||||
#if 0
|
#if EXTRA_DEBUG
|
||||||
NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
|
@ -729,7 +756,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
||||||
const unsigned char *ap = --this->cp; // argument start pointer
|
const unsigned char *ap = --this->cp; // argument start pointer
|
||||||
int c = cget(); // refetch first character
|
int c = cget(); // refetch first character
|
||||||
|
|
||||||
#if 0
|
#if EXTRA_DEBUG
|
||||||
NSLog(@"_qarg: %02x %c", c, isprint(c)?c: ' ');
|
NSLog(@"_qarg: %02x %c", c, isprint(c)?c: ' ');
|
||||||
#endif
|
#endif
|
||||||
if (c == '\"')
|
if (c == '\"')
|
||||||
|
@ -777,7 +804,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
||||||
while (!this->abort)
|
while (!this->abort)
|
||||||
{
|
{
|
||||||
// parse next element
|
// parse next element
|
||||||
#if 0
|
#if EXTRA_DEBUG
|
||||||
NSLog(@"_nextelement %02x %c", c, isprint(c)?c: ' ');
|
NSLog(@"_nextelement %02x %c", c, isprint(c)?c: ' ');
|
||||||
#endif
|
#endif
|
||||||
switch(c)
|
switch(c)
|
||||||
|
@ -821,7 +848,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
||||||
[this->tagPath removeLastObject]; // pop from stack
|
[this->tagPath removeLastObject]; // pop from stack
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if 0
|
#if EXTRA_DEBUG
|
||||||
NSLog(@"parserDidEndDocument: ");
|
NSLog(@"parserDidEndDocument: ");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -878,7 +905,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
||||||
tag = UTF8STR(tp + 1, this->cp - tp - 2); // don't include / and delimiting character
|
tag = UTF8STR(tp + 1, this->cp - tp - 2); // don't include / and delimiting character
|
||||||
else
|
else
|
||||||
tag = UTF8STR(tp, this->cp - tp - 1); // don't include delimiting character
|
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: ' ');
|
NSLog(@"tag=%@ - %02x %c", tag, c, isprint(c)?c: ' ');
|
||||||
#endif
|
#endif
|
||||||
parameters=[NSMutableDictionary dictionaryWithCapacity: 5];
|
parameters=[NSMutableDictionary dictionaryWithCapacity: 5];
|
||||||
|
@ -913,7 +940,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
arg=[self _qarg]; // get next argument (eats up to /, ?, >, =, space)
|
arg=[self _qarg]; // get next argument (eats up to /, ?, >, =, space)
|
||||||
#if 0
|
#if EXTRA_DEBUG
|
||||||
NSLog(@"arg=%@", arg);
|
NSLog(@"arg=%@", arg);
|
||||||
#endif
|
#endif
|
||||||
if (!this->acceptHTML && [arg length] == 0)
|
if (!this->acceptHTML && [arg length] == 0)
|
||||||
|
@ -989,8 +1016,6 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@implementation NSObject (NSXMLParserDelegateEventAdditions)
|
@implementation NSObject (NSXMLParserDelegateEventAdditions)
|
||||||
- (NSData*) parser: (NSXMLParser*)aParser
|
- (NSData*) parser: (NSXMLParser*)aParser
|
||||||
resolveExternalEntityName: (NSString*)aName
|
resolveExternalEntityName: (NSString*)aName
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue