Index: src/OFXMLParser.h ================================================================== --- src/OFXMLParser.h +++ src/OFXMLParser.h @@ -125,18 +125,19 @@ */ @interface OFXMLParser: OFObject { id _delegate; enum { + OF_XMLPARSER_IN_BYTE_ORDER_MARK, OF_XMLPARSER_OUTSIDE_TAG, OF_XMLPARSER_TAG_OPENED, OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS, OF_XMLPARSER_IN_TAG_NAME, OF_XMLPARSER_IN_CLOSE_TAG_NAME, OF_XMLPARSER_IN_TAG, OF_XMLPARSER_IN_ATTR_NAME, - OF_XMLPARSER_EXPECT_DELIM, + OF_XMLPARSER_EXPECT_DELIMITER, OF_XMLPARSER_IN_ATTR_VALUE, OF_XMLPARSER_EXPECT_CLOSE, OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE, OF_XMLPARSER_IN_EXCLAMATIONMARK, OF_XMLPARSER_IN_CDATA_OPENING, Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -137,11 +137,12 @@ @implementation OFXMLParser + (void)initialize { size_t i; - const SEL selectors_[] = { + const SEL selectors_[OF_XMLPARSER_NUM_STATES] = { + @selector(OF_parseInByteOrderMarkWithBuffer:i:last:), @selector(OF_parseOutsideTagWithBuffer:i:last:), @selector(OF_parseTagOpenedWithBuffer:i:last:), @selector(OF_parseInProcessingInstructionsWithBuffer:i:last:), @selector(OF_parseInTagNameWithBuffer:i:last:), @selector(OF_parseInCloseTagNameWithBuffer:i:last:), @@ -309,10 +310,31 @@ /* * The following methods handle the different states of the parser. They are * looked up in +[initialize] and put in a lookup table to speed things up. * One dispatch for every character would be way too slow! */ + +- (void)OF_parseInByteOrderMarkWithBuffer: (const char*)buffer + i: (size_t*)i + last: (size_t*)last +{ + if (buffer[*i] != "\xEF\xBB\xBF"[_level]) { + if (_level == 0) { + _state = OF_XMLPARSER_OUTSIDE_TAG; + (*i)--; + return; + } + + @throw [OFMalformedXMLException exceptionWithClass: [self class] + parser: self]; + } + + if (_level++ == 2) + _state = OF_XMLPARSER_OUTSIDE_TAG; + + *last = *i + 1; +} /* Not in a tag */ - (void)OF_parseOutsideTagWithBuffer: (const char*)buffer i: (size_t*)i last: (size_t*)last @@ -805,11 +827,11 @@ objc_autoreleasePoolPop(pool); [_buffer removeAllItems]; *last = *i + 1; - _state = OF_XMLPARSER_EXPECT_DELIM; + _state = OF_XMLPARSER_EXPECT_DELIMITER; } /* Expecting delimiter */ - (void)OF_parseExpectDelimiterWithBuffer: (const char*)buffer i: (size_t*)i Index: tests/OFXMLParserTests.m ================================================================== --- tests/OFXMLParserTests.m +++ tests/OFXMLParserTests.m @@ -321,11 +321,11 @@ } - (void)XMLParserTests { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - const char *str = "" + const char *str = "\xEF\xBB\xBF" "<<>>>>\r\r" " \n" " \r\n" " \n" " \n" @@ -338,11 +338,11 @@ " \n" " \n" ""; size_t j, len; - TEST(@"+[xmlParser]", (parser = [OFXMLParser parser])) + TEST(@"+[parser]", (parser = [OFXMLParser parser])) TEST(@"-[setDelegate:]", R([parser setDelegate: self])) /* Simulate a stream where we only get chunks */ len = strlen(str);