Index: src/OFXMLParser.h ================================================================== --- src/OFXMLParser.h +++ src/OFXMLParser.h @@ -165,14 +165,16 @@ BOOL acceptProlog; size_t lineNumber; BOOL lastCarriageReturn; BOOL finishedParsing; of_string_encoding_t encoding; + size_t depthLimit; } #ifdef OF_HAVE_PROPERTIES @property (assign) id delegate; +@property size_t depthLimit; #endif /*! * @brief Creates a new XML parser. * @@ -186,16 +188,34 @@ * @return The delegate that is used by the XML parser */ - (id )delegate; /*! - * @brief Sets the delegate the OFXMLParser should use. + * @brief Sets the delegate the XML parser should use. * * @param delegate The delegate to use */ - (void)setDelegate: (id )delegate; +/*! + * @brief Returns the depth limit for the XML parser. + * + * @return The depth limit for the XML parser + */ +- (size_t)depthLimit; + +/*! + * @brief Sets the depth limit for the XML parser. + * + * If the depth limit is exceeded, an OFMalformedXMLException is thrown. + * + * The default is 32. 0 means unlimited (insecure!). + * + * @param depthLimit The depth limit for the XML parser + */ +- (void)setDepthLimit: (size_t)depthLimit; + /*! * @brief Parses the specified buffer with the specified size. * * @param buffer The buffer to parse * @param length The length of the buffer Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -200,10 +200,11 @@ [namespaces addObject: dict]; acceptProlog = YES; lineNumber = 1; encoding = OF_STRING_ENCODING_UTF_8; + depthLimit = 32; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; @@ -233,10 +234,20 @@ - (void)setDelegate: (id )delegate_ { delegate = delegate_; } + +- (size_t)depthLimit +{ + return depthLimit; +} + +- (void)setDepthLimit: (size_t)depthLimit_ +{ + depthLimit = depthLimit_; +} - (void)parseBuffer: (const char*)buffer length: (size_t)length { size_t i, last = 0; @@ -362,10 +373,15 @@ *last = *i + 1; state = OF_XMLPARSER_IN_EXCLAMATIONMARK; acceptProlog = NO; break; default: + if (depthLimit > 0 && [previous count] >= depthLimit) + @throw [OFMalformedXMLException + exceptionWithClass: [self class] + parser: self]; + state = OF_XMLPARSER_IN_TAG_NAME; acceptProlog = NO; (*i)--; break; }