Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: src/xml/SkXMLParser.cpp

Issue 2154853002: [SkXMLParser] Initial text node support (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: rebase Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/SkDOMTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "expat.h" 8 #include "expat.h"
9 9
10 #include "SkStream.h" 10 #include "SkStream.h"
11 #include "SkString.h"
12 #include "SkTypes.h"
11 #include "SkXMLParser.h" 13 #include "SkXMLParser.h"
12 14
13 static char const* const gErrorStrings[] = { 15 static char const* const gErrorStrings[] = {
14 "empty or missing file ", 16 "empty or missing file ",
15 "unknown element ", 17 "unknown element ",
16 "unknown attribute name ", 18 "unknown attribute name ",
17 "error in attribute value ", 19 "error in attribute value ",
18 "duplicate ID ", 20 "duplicate ID ",
19 "unknown error " 21 "unknown error "
20 }; 22 };
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 //////////////// 54 ////////////////
53 55
54 namespace { 56 namespace {
55 57
56 const XML_Memory_Handling_Suite sk_XML_alloc = { 58 const XML_Memory_Handling_Suite sk_XML_alloc = {
57 sk_malloc_throw, 59 sk_malloc_throw,
58 sk_realloc_throw, 60 sk_realloc_throw,
59 sk_free 61 sk_free
60 }; 62 };
61 63
64 struct ParsingContext {
65 ParsingContext(SkXMLParser* parser)
66 : fParser(parser)
67 , fXMLParser(XML_ParserCreate_MM(nullptr, &sk_XML_alloc, nullptr)) { }
68
69 void flushText() {
70 if (!fBufferedText.isEmpty()) {
71 fParser->text(fBufferedText.c_str(), SkTo<int>(fBufferedText.size()) );
72 fBufferedText.reset();
73 }
74 }
75
76 void appendText(const char* txt, size_t len) {
77 fBufferedText.append(txt, len);
78 }
79
80 SkXMLParser* fParser;
81 SkAutoTCallVProc<skstd::remove_pointer_t<XML_Parser>, XML_ParserFree> fXMLPa rser;
82
83 private:
84 SkString fBufferedText;
85 };
86
87 #define HANDLER_CONTEXT(arg, name) ParsingContext* name = static_cast<ParsingCon text*>(arg);
88
62 void XMLCALL start_element_handler(void *data, const char* tag, const char** att ributes) { 89 void XMLCALL start_element_handler(void *data, const char* tag, const char** att ributes) {
63 SkXMLParser* parser = static_cast<SkXMLParser*>(data); 90 HANDLER_CONTEXT(data, ctx);
91 ctx->flushText();
64 92
65 parser->startElement(tag); 93 ctx->fParser->startElement(tag);
66 94
67 for (size_t i = 0; attributes[i]; i += 2) { 95 for (size_t i = 0; attributes[i]; i += 2) {
68 parser->addAttribute(attributes[i], attributes[i + 1]); 96 ctx->fParser->addAttribute(attributes[i], attributes[i + 1]);
69 } 97 }
70 } 98 }
71 99
72 void XMLCALL end_element_handler(void* data, const char* tag) { 100 void XMLCALL end_element_handler(void* data, const char* tag) {
73 static_cast<SkXMLParser*>(data)->endElement(tag); 101 HANDLER_CONTEXT(data, ctx);
102 ctx->flushText();
103
104 ctx->fParser->endElement(tag);
105 }
106
107 void XMLCALL text_handler(void *data, const char* txt, int len) {
108 HANDLER_CONTEXT(data, ctx);
109
110 ctx->appendText(txt, SkTo<size_t>(len));
111 }
112
113 void XMLCALL entity_decl_handler(void *data,
114 const XML_Char *entityName,
115 int is_parameter_entity,
116 const XML_Char *value,
117 int value_length,
118 const XML_Char *base,
119 const XML_Char *systemId,
120 const XML_Char *publicId,
121 const XML_Char *notationName) {
122 HANDLER_CONTEXT(data, ctx);
123
124 SkDebugf("'%s' entity declaration found, stopping processing", entityName);
125 XML_StopParser(ctx->fXMLParser, XML_FALSE);
74 } 126 }
75 127
76 } // anonymous namespace 128 } // anonymous namespace
77 129
78 SkXMLParser::SkXMLParser(SkXMLParserError* parserError) : fParser(nullptr), fErr or(parserError) 130 SkXMLParser::SkXMLParser(SkXMLParserError* parserError) : fParser(nullptr), fErr or(parserError)
79 { 131 {
80 } 132 }
81 133
82 SkXMLParser::~SkXMLParser() 134 SkXMLParser::~SkXMLParser()
83 { 135 {
84 } 136 }
85 137
86 bool SkXMLParser::parse(SkStream& docStream) 138 bool SkXMLParser::parse(SkStream& docStream)
87 { 139 {
88 SkAutoTCallVProc<skstd::remove_pointer_t<XML_Parser>, XML_ParserFree> 140 ParsingContext ctx(this);
89 parser(XML_ParserCreate_MM(nullptr, &sk_XML_alloc, nullptr)); 141 if (!ctx.fXMLParser) {
90 if (!parser) {
91 SkDebugf("could not create XML parser\n"); 142 SkDebugf("could not create XML parser\n");
92 return false; 143 return false;
93 } 144 }
94 145
95 XML_SetUserData(parser, this); 146 XML_SetUserData(ctx.fXMLParser, &ctx);
96 XML_SetElementHandler(parser, start_element_handler, end_element_handler); 147 XML_SetElementHandler(ctx.fXMLParser, start_element_handler, end_element_han dler);
148 XML_SetCharacterDataHandler(ctx.fXMLParser, text_handler);
149
150 // Disable entity processing, to inhibit internal entity expansion. See expa t CVE-2013-0340.
151 XML_SetEntityDeclHandler(ctx.fXMLParser, entity_decl_handler);
97 152
98 static const int kBufferSize = 512 SkDEBUGCODE( - 507); 153 static const int kBufferSize = 512 SkDEBUGCODE( - 507);
99 bool done = false; 154 bool done = false;
100 do { 155 do {
101 void* buffer = XML_GetBuffer(parser, kBufferSize); 156 void* buffer = XML_GetBuffer(ctx.fXMLParser, kBufferSize);
102 if (!buffer) { 157 if (!buffer) {
103 SkDebugf("could not buffer enough to continue\n"); 158 SkDebugf("could not buffer enough to continue\n");
104 return false; 159 return false;
105 } 160 }
106 161
107 size_t len = docStream.read(buffer, kBufferSize); 162 size_t len = docStream.read(buffer, kBufferSize);
108 done = docStream.isAtEnd(); 163 done = docStream.isAtEnd();
109 XML_Status status = XML_ParseBuffer(parser, SkToS32(len), done); 164 XML_Status status = XML_ParseBuffer(ctx.fXMLParser, SkToS32(len), done);
110 if (XML_STATUS_ERROR == status) { 165 if (XML_STATUS_ERROR == status) {
111 XML_Error error = XML_GetErrorCode(parser); 166 XML_Error error = XML_GetErrorCode(ctx.fXMLParser);
112 int line = XML_GetCurrentLineNumber(parser); 167 int line = XML_GetCurrentLineNumber(ctx.fXMLParser);
113 int column = XML_GetCurrentColumnNumber(parser); 168 int column = XML_GetCurrentColumnNumber(ctx.fXMLParser);
114 const XML_LChar* errorString = XML_ErrorString(error); 169 const XML_LChar* errorString = XML_ErrorString(error);
115 SkDebugf("parse error @%d:%d: %d (%s).\n", line, column, error, erro rString); 170 SkDebugf("parse error @%d:%d: %d (%s).\n", line, column, error, erro rString);
116 return false; 171 return false;
117 } 172 }
118 } while (!done); 173 } while (!done);
119 174
120 return true; 175 return true;
121 } 176 }
122 177
123 bool SkXMLParser::parse(const char doc[], size_t len) 178 bool SkXMLParser::parse(const char doc[], size_t len)
(...skipping 26 matching lines...) Expand all
150 { 205 {
151 return this->onText(text, len); 206 return this->onText(text, len);
152 } 207 }
153 208
154 //////////////////////////////////////////////////////////////////////////////// 209 ////////////////////////////////////////////////////////////////////////////////
155 210
156 bool SkXMLParser::onStartElement(const char elem[]) {return false; } 211 bool SkXMLParser::onStartElement(const char elem[]) {return false; }
157 bool SkXMLParser::onAddAttribute(const char name[], const char value[]) {return false; } 212 bool SkXMLParser::onAddAttribute(const char name[], const char value[]) {return false; }
158 bool SkXMLParser::onEndElement(const char elem[]) { return false; } 213 bool SkXMLParser::onEndElement(const char elem[]) { return false; }
159 bool SkXMLParser::onText(const char text[], int len) {return false; } 214 bool SkXMLParser::onText(const char text[], int len) {return false; }
OLDNEW
« no previous file with comments | « no previous file | tests/SkDOMTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698