summaryrefslogtreecommitdiffstats
path: root/WebCore/dom/XMLTokenizerLibxml2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/dom/XMLTokenizerLibxml2.cpp')
-rw-r--r--WebCore/dom/XMLTokenizerLibxml2.cpp59
1 files changed, 31 insertions, 28 deletions
diff --git a/WebCore/dom/XMLTokenizerLibxml2.cpp b/WebCore/dom/XMLTokenizerLibxml2.cpp
index 9aa0961..42c8b9b 100644
--- a/WebCore/dom/XMLTokenizerLibxml2.cpp
+++ b/WebCore/dom/XMLTokenizerLibxml2.cpp
@@ -465,7 +465,7 @@ static void errorFunc(void*, const char*, ...)
static bool didInit = false;
-static xmlParserCtxtPtr createStringParser(xmlSAXHandlerPtr handlers, void* userData)
+PassRefPtr<XMLParserContext> XMLParserContext::createStringParser(xmlSAXHandlerPtr handlers, void* userData)
{
if (!didInit) {
xmlInitParser();
@@ -482,12 +482,12 @@ static xmlParserCtxtPtr createStringParser(xmlSAXHandlerPtr handlers, void* user
const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);
xmlSwitchEncoding(parser, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE);
- return parser;
+ return adoptRef(new XMLParserContext(parser));
}
// Chunk should be encoded in UTF-8
-static xmlParserCtxtPtr createMemoryParser(xmlSAXHandlerPtr handlers, void* userData, const char* chunk)
+PassRefPtr<XMLParserContext> XMLParserContext::createMemoryParser(xmlSAXHandlerPtr handlers, void* userData, const char* chunk)
{
if (!didInit) {
xmlInitParser();
@@ -518,8 +518,8 @@ static xmlParserCtxtPtr createMemoryParser(xmlSAXHandlerPtr handlers, void* user
parser->str_xmlns = xmlDictLookup(parser->dict, BAD_CAST "xmlns", 5);
parser->str_xml_ns = xmlDictLookup(parser->dict, XML_XML_NAMESPACE, 36);
parser->_private = userData;
-
- return parser;
+
+ return adoptRef(new XMLParserContext(parser));
}
// --------------------------------
@@ -609,6 +609,13 @@ XMLTokenizer::XMLTokenizer(DocumentFragment* fragment, Element* parentElement)
m_defaultNamespaceURI = parentElement->namespaceURI();
}
+XMLParserContext::~XMLParserContext()
+{
+ if (m_context->myDoc)
+ xmlFreeDoc(m_context->myDoc);
+ xmlFreeParserCtxt(m_context);
+}
+
XMLTokenizer::~XMLTokenizer()
{
clearCurrentNodeStack();
@@ -616,15 +623,16 @@ XMLTokenizer::~XMLTokenizer()
m_doc->deref();
if (m_pendingScript)
m_pendingScript->removeClient(this);
- if (m_context)
- xmlFreeParserCtxt(m_context);
}
void XMLTokenizer::doWrite(const String& parseString)
{
if (!m_context)
initializeParserContext();
-
+
+ // Protect the libxml context from deletion during a callback
+ RefPtr<XMLParserContext> context = m_context;
+
// libXML throws an error if you try to switch the encoding for an empty string.
if (parseString.length()) {
// Hack around libxml2's lack of encoding overide support by manually
@@ -633,15 +641,15 @@ void XMLTokenizer::doWrite(const String& parseString)
// and switch encodings, causing the parse to fail.
const UChar BOM = 0xFEFF;
const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);
- xmlSwitchEncoding(m_context, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE);
+ xmlSwitchEncoding(context->context(), BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE);
XMLTokenizerScope scope(m_doc->docLoader());
- xmlParseChunk(m_context, reinterpret_cast<const char*>(parseString.characters()), sizeof(UChar) * parseString.length(), 0);
+ xmlParseChunk(context->context(), reinterpret_cast<const char*>(parseString.characters()), sizeof(UChar) * parseString.length(), 0);
}
if (m_doc->decoder() && m_doc->decoder()->sawError()) {
// If the decoder saw an error, report it as fatal (stops parsing)
- handleError(fatal, "Encoding error", lineNumber(), columnNumber());
+ handleError(fatal, "Encoding error", context->context()->input->line, context->context()->input->col);
}
return;
@@ -1277,9 +1285,9 @@ void XMLTokenizer::initializeParserContext(const char* chunk)
XMLTokenizerScope scope(m_doc->docLoader());
if (m_parsingFragment)
- m_context = createMemoryParser(&sax, this, chunk);
+ m_context = XMLParserContext::createMemoryParser(&sax, this, chunk);
else
- m_context = createStringParser(&sax, this);
+ m_context = XMLParserContext::createStringParser(&sax, this);
}
void XMLTokenizer::doEnd()
@@ -1300,12 +1308,9 @@ void XMLTokenizer::doEnd()
// Tell libxml we're done.
{
XMLTokenizerScope scope(m_doc->docLoader());
- xmlParseChunk(m_context, 0, 0, 1);
+ xmlParseChunk(context(), 0, 0, 1);
}
- if (m_context->myDoc)
- xmlFreeDoc(m_context->myDoc);
- xmlFreeParserCtxt(m_context);
m_context = 0;
}
}
@@ -1334,18 +1339,19 @@ void* xmlDocPtrForString(DocLoader* docLoader, const String& source, const Strin
int XMLTokenizer::lineNumber() const
{
- return m_context ? m_context->input->line : 1;
+ return context() ? context()->input->line : 1;
}
int XMLTokenizer::columnNumber() const
{
- return m_context ? m_context->input->col : 1;
+ return context() ? context()->input->col : 1;
}
void XMLTokenizer::stopParsing()
{
Tokenizer::stopParsing();
- xmlStopParser(m_context);
+ if (context())
+ xmlStopParser(context());
}
void XMLTokenizer::resumeParsing()
@@ -1384,17 +1390,17 @@ bool parseXMLDocumentFragment(const String& chunk, DocumentFragment* fragment, E
CString chunkAsUtf8 = chunk.utf8();
tokenizer.initializeParserContext(chunkAsUtf8.data());
- xmlParseContent(tokenizer.m_context);
+ xmlParseContent(tokenizer.context());
tokenizer.endDocument();
// Check if all the chunk has been processed.
- long bytesProcessed = xmlByteConsumed(tokenizer.m_context);
+ long bytesProcessed = xmlByteConsumed(tokenizer.context());
if (bytesProcessed == -1 || ((unsigned long)bytesProcessed) != chunkAsUtf8.length())
return false;
// No error if the chunk is well formed or it is not but we have no error.
- return tokenizer.m_context->wellFormed || xmlCtxtGetLastError(tokenizer.m_context) == 0;
+ return tokenizer.context()->wellFormed || xmlCtxtGetLastError(tokenizer.context()) == 0;
}
// --------------------------------
@@ -1437,12 +1443,9 @@ HashMap<String, String> parseAttributes(const String& string, bool& attrsOK)
memset(&sax, 0, sizeof(sax));
sax.startElementNs = attributesStartElementNsHandler;
sax.initialized = XML_SAX2_MAGIC;
- xmlParserCtxtPtr parser = createStringParser(&sax, &state);
+ RefPtr<XMLParserContext> parser = XMLParserContext::createStringParser(&sax, &state);
String parseString = "<?xml version=\"1.0\"?><attrs " + string + " />";
- xmlParseChunk(parser, reinterpret_cast<const char*>(parseString.characters()), parseString.length() * sizeof(UChar), 1);
- if (parser->myDoc)
- xmlFreeDoc(parser->myDoc);
- xmlFreeParserCtxt(parser);
+ xmlParseChunk(parser->context(), reinterpret_cast<const char*>(parseString.characters()), parseString.length() * sizeof(UChar), 1);
attrsOK = state.gotAttributes;
return state.attributes;
}