@@ -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