Index: src/OFXMLParser.h ================================================================== --- src/OFXMLParser.h +++ src/OFXMLParser.h @@ -123,11 +123,11 @@ OF_XMLPARSER_IN_ATTR_NAME, OF_XMLPARSER_EXPECT_DELIM, OF_XMLPARSER_IN_ATTR_VALUE, OF_XMLPARSER_EXPECT_CLOSE, OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE, - OF_XMLPARSER_IN_CDATA_OR_COMMENT, + OF_XMLPARSER_IN_EXCLAMATIONMARK, OF_XMLPARSER_IN_CDATA_OPENING_1, OF_XMLPARSER_IN_CDATA_OPENING_2, OF_XMLPARSER_IN_CDATA_OPENING_3, OF_XMLPARSER_IN_CDATA_OPENING_4, OF_XMLPARSER_IN_CDATA_OPENING_5, @@ -137,10 +137,11 @@ OF_XMLPARSER_IN_CDATA_3, OF_XMLPARSER_IN_COMMENT_OPENING, OF_XMLPARSER_IN_COMMENT_1, OF_XMLPARSER_IN_COMMENT_2, OF_XMLPARSER_IN_COMMENT_3, + OF_XMLPARSER_IN_DOCTYPE, OF_XMLPARSER_NUM_STATES } state; OFMutableString *cache; OFString *name; OFString *prefix; @@ -156,10 +157,11 @@ of_xml_parser_string_block_t charactersHandler; of_xml_parser_string_block_t CDATAHandler; of_xml_parser_string_block_t commentHandler; of_xml_parser_unknown_entity_block_t unknownEntityHandler; #endif + size_t level; } #ifdef OF_HAVE_PROPERTIES @property (retain) id delegate; # ifdef OF_HAVE_BLOCKS Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -92,11 +92,11 @@ @selector(_parseInAttributeNameWithBuffer:i:last:), @selector(_parseExpectDelimiterWithBuffer:i:last:), @selector(_parseInAttributeValueWithBuffer:i:last:), @selector(_parseExpectCloseWithBuffer:i:last:), @selector(_parseExpectSpaceOrCloseWithBuffer:i:last:), - @selector(_parseInCDATAOrCommentWithBuffer:i:last:), + @selector(_parseInExclamationMarkWithBuffer:i:last:), @selector(_parseInCDATAOpening1WithBuffer:i:last:), @selector(_parseInCDATAOpening2WithBuffer:i:last:), @selector(_parseInCDATAOpening3WithBuffer:i:last:), @selector(_parseInCDATAOpening4WithBuffer:i:last:), @selector(_parseInCDATAOpening5WithBuffer:i:last:), @@ -105,11 +105,12 @@ @selector(_parseInCDATA2WithBuffer:i:last:), @selector(_parseInCDATA3WithBuffer:i:last:), @selector(_parseInCommentOpeningWithBuffer:i:last:), @selector(_parseInComment1WithBuffer:i:last:), @selector(_parseInComment2WithBuffer:i:last:), - @selector(_parseInComment3WithBuffer:i:last:) + @selector(_parseInComment3WithBuffer:i:last:), + @selector(_parseInDoctypeWithBuffer:i:last:), }; memcpy(selectors, sels, sizeof(sels)); for (i = 0; i < OF_XMLPARSER_NUM_STATES; i++) { if (![self instancesRespondToSelector: selectors[i]]) @@ -334,11 +335,11 @@ *last = *i + 1; state = OF_XMLPARSER_IN_CLOSE_TAG_NAME; break; case '!': *last = *i + 1; - state = OF_XMLPARSER_IN_CDATA_OR_COMMENT; + state = OF_XMLPARSER_IN_EXCLAMATIONMARK; break; default: state = OF_XMLPARSER_IN_TAG_NAME; (*i)--; break; @@ -713,20 +714,23 @@ state = OF_XMLPARSER_OUTSIDE_TAG; } else if (buf[*i] != ' ' && buf[*i] != '\n' && buf[*i] != '\r') @throw [OFMalformedXMLException newWithClass: isa]; } -/* CDATA or comment */ -- (void)_parseInCDATAOrCommentWithBuffer: (const char*)buf - i: (size_t*)i - last: (size_t*)last +/* In */ +- (void)_parseInDoctypeWithBuffer: (const char*)buf + i: (size_t*)i + last: (size_t*)last +{ + if ((level < 6 && buf[*i] != "OCTYPE"[level]) || + (level == 6 && buf[*i] != ' ' && buf[*i] != '\t' && + buf[*i] != '\n' && buf[*i] != '\r')) + @throw [OFMalformedXMLException newWithClass: isa]; + + if (level < 7 || buf[*i] == '<') + level++; + + if (buf[*i] == '>') { + if (level == 7) + state = OF_XMLPARSER_OUTSIDE_TAG; + else + level--; + } + + *last = *i + 1; +} - (OFString*)string: (OFString*)string containsUnknownEntityNamed: (OFString*)entity { #ifdef OF_HAVE_BLOCKS Index: tests/OFXMLParserTests.m ================================================================== --- tests/OFXMLParserTests.m +++ tests/OFXMLParserTests.m @@ -300,11 +300,11 @@ - (void)XMLParserTests { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFXMLParser *parser; - const char *str = "\n" + const char *str = "<<>>>>\n" " \n" " \n" " \n" " \n" " \n"