Minore xml parsing fixes

This commit is contained in:
Richard Frith-Macdonald 2018-01-11 13:50:39 +00:00
parent 4efa322ca2
commit 93389bb357
3 changed files with 83 additions and 26 deletions

View file

@ -1,3 +1,8 @@
2018-01-11 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSXMLParser.m: OSX compatibility tweaks and correction
for setting entity resolution flag in sloppy parser.
2018-01-04 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSObject.m: Fix bug with one path to object allocation

View file

@ -117,6 +117,11 @@ static NSNull *null = nil;
qName = [NSString stringWithFormat: @"%@:%@", prefix, qName];
}
if (elementAttributes == nil)
{
elementAttributes = [NSMutableDictionary dictionary];
}
if ([elementNamespaces count] > 0)
{
[_namespaces addObject: [elementNamespaces allKeys]];
@ -158,10 +163,6 @@ static NSNull *null = nil;
NSEnumerator *e = [elementNamespaces keyEnumerator];
NSString *k;
if (elementAttributes == nil)
{
elementAttributes = [NSMutableDictionary dictionary];
}
while ((k = [e nextObject]) != nil)
{
NSString *v = [elementNamespaces objectForKey: k];
@ -664,6 +665,22 @@ NewUTF8STR(const void *ptr, int len)
}
@end
@implementation GSXMLParserIvars
- (NSString*) description
{
return [[super description] stringByAppendingFormat:
@" shouldProcessNamespaces: %d"
@" shouldReportNamespacePrefixes: %d"
@" shouldResolveExternalEntities: %d"
@" acceptHTML: %d"
@" hasStarted: %d"
@" hasElement: %d",
shouldProcessNamespaces,
shouldReportNamespacePrefixes,
shouldResolveExternalEntities,
acceptHTML,
hasStarted,
hasElement];
}
@end
static SEL didEndElementSel = 0;
@ -938,7 +955,7 @@ static SEL foundIgnorableSel;
}
/* Go up the namespace stack looking for a mapping from p to
* a URI. Return the first URI found (or nil if none is found).
* a URI. Return the first URI found (or an empty string if none is found).
*/
- (NSString*) _uriForPrefix: (NSString*)p
{
@ -954,7 +971,7 @@ static SEL foundIgnorableSel;
uri = [(NSDictionary*)o objectForKey: p];
}
}
return uri;
return (nil == uri) ? @"" : uri;
}
- (void) _closeLastTag
@ -1319,7 +1336,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
}
if (prefix != nil)
{
if (ns == nil)
if (nil == ns)
{
ns = [NSMutableDictionary new];
if (this->shouldProcessNamespaces)
@ -1341,12 +1358,17 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
didStartMappingPrefixSel, self, prefix, uri);
}
}
if (attr != nil)
{
attributes = attr;
}
}
}
if ([attr count] > 0)
{
attributes = attr;
}
else if (nil == attributes)
{
attr = [NSMutableArray new];
attributes = attr;
}
[this->tagPath addObject: tag];
[this->namespaces addObject: ((ns == nil) ? (id)null : (id)ns)];
@ -1463,14 +1485,21 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
code: NSXMLParserInvalidCharacterError];
}
#if 1
NSLog(@"NSXMLParser: unrecognized entity: &%@;", entity);
#endif
// entity=[entitiesTable objectForKey: entity]; // look up string in entity translation table
if (nil == entity)
if (this->shouldResolveExternalEntities)
{
entity = @"&??;"; // unknown entity
#if 1
NSLog(@"NSXMLParser: unrecognized entity: &%@;", entity);
#endif
// entity=[entitiesTable objectForKey: entity]; // look up string in entity translation table
if (nil == entity)
{
entity = @"&??;"; // unknown entity
}
}
else
{
entity = @""; // not resolved
}
return entity;
}
@ -2148,7 +2177,7 @@ NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes);
- (void) setShouldResolveExternalEntities: (BOOL)aFlag
{
this->shouldProcessNamespaces = aFlag;
this->shouldResolveExternalEntities = aFlag;
}
- (void) _setAcceptHTML: (BOOL) flag

View file

@ -211,15 +211,15 @@
- (void) parser: (NSXMLParser *)parser
parseErrorOccurred: (NSError *)parseError
{
[s appendFormat: @"%@ %@\n", NSStringFromSelector(_cmd),
parseError];
[s appendFormat: @"%@ %@ at %ld on %ld\n", NSStringFromSelector(_cmd),
parseError, (long)[parser columnNumber], (long)[parser lineNumber]];
}
- (void) parser: (NSXMLParser *)parser
validationErrorOccurred: (NSError *)validationError
{
[s appendFormat: @"%@ %@\n", NSStringFromSelector(_cmd),
validationError];
[s appendFormat: @"%@ %@ at %ld on %ld\n", NSStringFromSelector(_cmd),
validationError, (long)[parser columnNumber], (long)[parser lineNumber]];
}
- (void) reset
@ -241,8 +241,11 @@ testParse(NSData *xml, NSString *expect)
NSAutoreleasePool *arp = [NSAutoreleasePool new];
Handler *handler;
NSXMLParser *parser;
Class c = NSClassFromString(@"GSSloppyXMLParser");
parser = [[NSXMLParser alloc] initWithData: xml];
c = Nil;
if (Nil == c) c = [NSXMLParser class];
parser = [[c alloc] initWithData: xml];
[parser setShouldProcessNamespaces: setShouldProcessNamespaces];
[parser setShouldReportNamespacePrefixes: setShouldReportNamespacePrefixes];
@ -252,7 +255,8 @@ testParse(NSData *xml, NSString *expect)
[parser setDelegate: handler];
if (NO == [parser parse])
{
NSLog(@"Parsing failed: %@", [parser parserError]);
NSLog(@"Parsing failed: %@ at %ld on %ld", [parser parserError],
(long)[parser columnNumber], (long)[parser lineNumber]);
[arp release];
return NO;
}
@ -284,6 +288,7 @@ int main()
NSAutoreleasePool *arp = [NSAutoreleasePool new];
NSFileManager *mgr = [NSFileManager defaultManager];
NSDirectoryEnumerator *dir;
NSString *str;
NSString *xmlName;
const char *x1 = "<?xml version=\"1.0\"?><test x = \"1\"></test>";
const char *x1e = "<test x=\"1\"></test>";
@ -301,7 +306,6 @@ int main()
{
if ([[xmlName pathExtension] isEqualToString: @"xml"])
{
NSString *str;
NSString *xmlPath;
NSData *xmlData;
NSString *result;
@ -315,6 +319,25 @@ int main()
}
}
{
NSString *exp;
NSData *dat;
exp = @"parserDidStartDocument:\n\
parser:didStartElement:namespaceURI:qualifiedName:attributes: file file {\n}\n\
&Aparser:didEndElement:namespaceURI:qualifiedName: file file\n\
parserDidEndDocument:\n\
";
str = [NSString stringWithFormat:
@"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
@"<!DOCTYPE file [<!ENTITY foo SYSTEM \"file://%@/GNUmakefile\">]>\n"
@"<file>&amp;&foo;&#65;</file>", [mgr currentDirectoryPath]];
dat = [str dataUsingEncoding: NSUTF8StringEncoding];
PASS((testParse(dat, exp)), "external entity")
}
[arp release]; arp = nil;
return 0;
}