From a327fcb80786e4124ccd0e71ed86319ed8ba47e6 Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz Date: Fri, 14 Aug 2015 08:34:56 +0000 Subject: [PATCH] [GB.XML] * BUG: Document: Fixed a memory leak when the instanciation failed due to a parsing exception. * BUG: XmlElement: Internally setting an attribute with a NULL value does not crash anymore. * BUG: Encountering a never-ended attribute does not crash the parser anymore. * OPT: Optimized parser cleanup when an exception is thrown. [GB.XML.HTML] * BUG: Encountering a never-ended attribute does not crash the parser anymore. git-svn-id: svn://localhost/gambas/trunk@7223 867c0c6c-44f3-4631-809d-bfa615b0a4ec --- gb.xml/src/document.cpp | 16 ++++++++++++---- gb.xml/src/document.h | 4 ++-- gb.xml/src/element.cpp | 7 +++++-- gb.xml/src/html/htmlparser.cpp | 5 +++-- gb.xml/src/parser.cpp | 24 +++++++++++++++++------- 5 files changed, 39 insertions(+), 17 deletions(-) diff --git a/gb.xml/src/document.cpp b/gb.xml/src/document.cpp index 91c689af7..43c0e0391 100644 --- a/gb.xml/src/document.cpp +++ b/gb.xml/src/document.cpp @@ -47,7 +47,7 @@ Document* XMLDocument_New() } -Document* XMLDocument_NewFromFile(const char *fileName, const size_t lenFileName, const DocumentType docType) +Document* XMLDocument_NewFromFile(const char *fileName, const size_t lenFileName, const DocumentType docType) throw(XMLParseException) { Document *newDoc = (Document*)malloc(sizeof(Document)); @@ -56,8 +56,16 @@ Document* XMLDocument_NewFromFile(const char *fileName, const size_t lenFileName newDoc->root = 0; newDoc->parentDocument = newDoc; newDoc->docType = docType; - - XMLDocument_Open(newDoc, fileName, lenFileName); + + try + { + XMLDocument_Open(newDoc, fileName, lenFileName); + } + catch(XMLParseException ex) + { + XMLDocument_Release(newDoc); + throw ex; + } return newDoc; } @@ -99,7 +107,7 @@ void XMLDocument_Open(Document *doc, const char *fileName, const size_t lenFileN } -void XMLDocument_SetContent(Document *doc, const char *content, size_t len) throw(XMLParseException) +void XMLDocument_SetContent(Document *doc, const char *content, const size_t len) throw(XMLParseException) { char *posStart = 0, *posEnd = 0; diff --git a/gb.xml/src/document.h b/gb.xml/src/document.h index c82108961..c30eb0bc2 100644 --- a/gb.xml/src/document.h +++ b/gb.xml/src/document.h @@ -26,11 +26,11 @@ #include "utils.h" Document* XMLDocument_New(); -Document* XMLDocument_NewFromFile(const char *fileName, const size_t lenFileName, const DocumentType docType = XMLDocumentType); +Document* XMLDocument_NewFromFile(const char *fileName, const size_t lenFileName, const DocumentType docType = XMLDocumentType) throw(XMLParseException); void XMLDocument_Release(Document *doc); void XMLDocument_Open(Document *doc, const char *fileName, const size_t lenFileName) throw(XMLParseException); -void XMLDocument_SetContent(Document *doc, const char *content, size_t len) throw(XMLParseException); +void XMLDocument_SetContent(Document *doc, const char *content, const size_t len) throw(XMLParseException); void XMLDocument_Save(Document *doc, const char *fileName, bool indent = false); void XMLDocument_SetRoot(Document *doc, Element *newRoot); diff --git a/gb.xml/src/element.cpp b/gb.xml/src/element.cpp index 8d429f0ae..371e4666f 100644 --- a/gb.xml/src/element.cpp +++ b/gb.xml/src/element.cpp @@ -300,8 +300,11 @@ Attribute* XMLAttribute_New(const char *nattrName, const size_t nlenAttrName, newAttr->attrName = (char*)malloc(sizeof(char)*(nlenAttrName)); memcpy(newAttr->attrName, nattrName, nlenAttrName); - newAttr->attrValue = (char*)malloc(nlenAttrVal); - memcpy(newAttr->attrValue, nattrVal, nlenAttrVal); + if(nattrVal && nlenAttrVal) + { + newAttr->attrValue = (char*)malloc(nlenAttrVal); + memcpy(newAttr->attrValue, nattrVal, nlenAttrVal); + } return newAttr; } diff --git a/gb.xml/src/html/htmlparser.cpp b/gb.xml/src/html/htmlparser.cpp index c85cbae03..6b9f925a7 100644 --- a/gb.xml/src/html/htmlparser.cpp +++ b/gb.xml/src/html/htmlparser.cpp @@ -305,7 +305,7 @@ Node** parseHTML(char const *data, const size_t lendata, size_t *nodeCount)// XM //Seeking to the next white space or tag-end while(!(XML.isWhiteSpace(s)) && pos < endData && s != '>'){pos++; s = *pos;} delimiter = s; - char* delimiterPos = (char*)memchr(pos, delimiter, endData - pos); + const char* delimiterPos = (char*)memchr(pos, delimiter, endData - pos); XML.XMLElement_AddAttribute(elmt, attrNamestart, attrNameEnd - attrNamestart, pos, delimiterPos - pos); @@ -315,7 +315,8 @@ Node** parseHTML(char const *data, const size_t lendata, size_t *nodeCount)// XM else { pos++; - char* delimiterPos = (char*)memchr(pos, delimiter, endData - pos); + const char* delimiterPos = (char*)memchr(pos, delimiter, endData - pos); + if(!delimiterPos) delimiterPos = endData; XML.XMLElement_AddAttribute(elmt, attrNamestart, attrNameEnd - attrNamestart, pos, delimiterPos - pos); diff --git a/gb.xml/src/parser.cpp b/gb.xml/src/parser.cpp index 4df85a92e..d967dd525 100644 --- a/gb.xml/src/parser.cpp +++ b/gb.xml/src/parser.cpp @@ -64,12 +64,16 @@ else \ XMLNode_appendChild(curElement, _elmt); \ } -#define THROW(_ex) for(size_t i = 0; i < *nodeCount; i++)\ -{\ - XMLNode_Free(elements[i]);\ -}\ -free(elements);\ -throw(_ex) +void parser_cleanup(Node **elements, size_t *nodeCount) +{ + for(size_t i = *nodeCount; i --> 0;) + { + XMLNode_Free(elements[i]); + } + free(elements); +} + +#define THROW(_ex) parser_cleanup(elements, nodeCount); throw(_ex) Node** parseXML(char const *data, const size_t lendata, size_t *nodeCount) throw(XMLParseException) { @@ -308,7 +312,13 @@ Node** parseXML(char const *data, const size_t lendata, size_t *nodeCount) throw pos++; char* delimiterPos = (char*)memchr(pos, delimiter, endData - pos); - + + if(!delimiterPos) + { + THROW(XMLParseException_New("Never-ending attribute value", + data, lendata, pos - 1)); + } + XMLElement_AddAttribute(elmt, attrNamestart, attrNameEnd - attrNamestart, pos, delimiterPos - pos); pos = delimiterPos;