Index: src/OFExceptions.h ================================================================== --- src/OFExceptions.h +++ src/OFExceptions.h @@ -209,10 +209,16 @@ * An OFException indicating that the format is invalid. */ @interface OFInvalidFormatException: OFException {} @end +/** + * An OFException indicating that a parser encountered malformed or invalid XML. + */ +@interface OFMalformedXMLException: OFException {} +@end + /** * An OFException indicating that initializing something failed. */ @interface OFInitializationFailedException: OFException {} @end Index: src/OFExceptions.m ================================================================== --- src/OFExceptions.m +++ src/OFExceptions.m @@ -299,10 +299,24 @@ return string; string = [[OFString alloc] initWithFormat: @"The format is invalid for class %s!", [class name]]; + return string; +} +@end + +@implementation OFMalformedXMLException +- (OFString*)string +{ + if (string != nil) + return string; + + string = [[OFString alloc] initWithFormat: + @"The parser in class %s encountered malformed or invalid XML!", + [class name]]; + return string; } @end @implementation OFInitializationFailedException Index: src/OFXMLParser.h ================================================================== --- src/OFXMLParser.h +++ src/OFXMLParser.h @@ -57,10 +57,11 @@ OFString *prefix; OFString *ns; OFDictionary *attrs; OFString *attr_name; char delim; + OFArray *previous; } + xmlParser; - (id)delegate; - setDelegate: (OFObject *)delegate; Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -77,10 +77,11 @@ { self = [super init]; @try { cache = [[OFMutableString alloc] init]; + previous = [[OFMutableArray alloc] init]; } @catch (OFException *e) { /* We can't use [super dealloc] on OS X here. Compiler bug? */ [self dealloc]; @throw e; } @@ -96,10 +97,11 @@ [name release]; [prefix release]; [ns release]; [attrs release]; [attr_name release]; + [previous release]; [super dealloc]; } - (id)delegate @@ -194,12 +196,10 @@ name = [[OFString alloc] initWithCString: cache_c length: cache_len]; } - [cache setToCString: ""]; - if (buf[i] == '>' || buf[i] == '/') { pool = [[OFAutoreleasePool alloc] init]; [delegate xmlParser: self didStartTagWithName: name @@ -210,10 +210,13 @@ if (buf[i] == '/') [delegate xmlParser: self didEndTagWithName: name prefix: prefix namespace: ns]; + else + [previous addObject: + [[cache copy] autorelease]]; [pool release]; [name release]; [prefix release]; @@ -223,10 +226,11 @@ ? OF_XMLPARSER_EXPECT_CLOSE : OF_XMLPARSER_OUTSIDE_TAG); } else state = OF_XMLPARSER_IN_TAG; + [cache setToCString: ""]; last = i + 1; } break; /* Inside a close tag, no name yet */ @@ -255,10 +259,15 @@ prefix = nil; name = [[OFString alloc] initWithCString: cache_c length: cache_len]; } + + if (![[previous lastObject] isEqual: cache]) + @throw [OFMalformedXMLException + newWithClass: isa]; + [previous removeNObjects: 1]; [cache setToCString: ""]; pool = [[OFAutoreleasePool alloc] init]; @@ -294,10 +303,18 @@ if (buf[i] == '/') [delegate xmlParser: self didEndTagWithName: name prefix: prefix namespace: ns]; + else if (prefix != nil) { + OFString *str = [OFString + stringWithFormat: @"%s:%s", + [prefix cString], + [name cString]]; + [previous addObject: str]; + } else + [previous addObject: name]; [pool release]; [name release]; [prefix release]; @@ -334,11 +351,11 @@ break; /* Expecting delimiter */ case OF_XMLPARSER_EXPECT_DELIM: if (buf[i] != '\'' && buf[i] != '"') - @throw [OFInvalidEncodingException + @throw [OFMalformedXMLException newWithClass: isa]; delim = buf[i]; last = i + 1; state = OF_XMLPARSER_IN_ATTR_VALUE; @@ -377,21 +394,21 @@ case OF_XMLPARSER_EXPECT_CLOSE: if (buf[i] == '>') { last = i + 1; state = OF_XMLPARSER_OUTSIDE_TAG; } else - @throw [OFInvalidEncodingException + @throw [OFMalformedXMLException newWithClass: isa]; break; /* Expecting closing '>' or space */ case OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE: if (buf[i] == '>') { last = i + 1; state = OF_XMLPARSER_OUTSIDE_TAG; } else if (buf[i] != ' ') - @throw [OFInvalidEncodingException + @throw [OFMalformedXMLException newWithClass: isa]; break; } } Index: tests/OFXMLParser/OFXMLParser.m ================================================================== --- tests/OFXMLParser/OFXMLParser.m +++ tests/OFXMLParser/OFXMLParser.m @@ -81,11 +81,11 @@ int main() { const char *foo = "barfoo<bar" - "barquxbar"; + "barquxbar"; size_t len = strlen(foo); size_t i; OFXMLParser *parser = [OFXMLParser xmlParser]; [parser setDelegate: [[ParserDelegate alloc] init]];