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

Side by Side Diff: third_party/libxml/src/parser.c

Issue 2539003002: Make the XML entity recursion check more precise. (Closed)
Patch Set: Feedback. Created 4 years 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 | « third_party/libxml/src/include/libxml/entities.h ('k') | no next file » | 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 * parser.c : an XML 1.0 parser, namespaces and validity support are mostly 2 * parser.c : an XML 1.0 parser, namespaces and validity support are mostly
3 * implemented on top of the SAX interfaces 3 * implemented on top of the SAX interfaces
4 * 4 *
5 * References: 5 * References:
6 * The XML specification: 6 * The XML specification:
7 * http://www.w3.org/TR/REC-xml 7 * http://www.w3.org/TR/REC-xml
8 * Original 1.0 version: 8 * Original 1.0 version:
9 * http://www.w3.org/TR/1998/REC-xml-19980210 9 * http://www.w3.org/TR/1998/REC-xml-19980210
10 * XML second edition working draft 10 * XML second edition working draft
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 130
131 if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE)) 131 if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
132 return (0); 132 return (0);
133 if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP) 133 if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
134 return (1); 134 return (1);
135 135
136 /* 136 /*
137 * This may look absurd but is needed to detect 137 * This may look absurd but is needed to detect
138 * entities problems 138 * entities problems
139 */ 139 */
140 if ((ent != NULL) && (ent->guard == XML_ENTITY_BEING_CHECKED)) {
141 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
142 return (1);
143 }
140 if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) && 144 if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
141 (ent->content != NULL) && (ent->checked == 0) && 145 (ent->content != NULL) && (ent->checked == 0) &&
142 (ctxt->errNo != XML_ERR_ENTITY_LOOP)) { 146 (ctxt->errNo != XML_ERR_ENTITY_LOOP)) {
143 unsigned long oldnbent = ctxt->nbentities; 147 unsigned long oldnbent = ctxt->nbentities;
144 xmlChar *rep; 148 xmlChar *rep;
145 149
150 ent->guard = XML_ENTITY_BEING_CHECKED;
146 ent->checked = 1; 151 ent->checked = 1;
147 152
148 ++ctxt->depth; 153 ++ctxt->depth;
149 rep = xmlStringDecodeEntities(ctxt, ent->content, 154 rep = xmlStringDecodeEntities(ctxt, ent->content,
150 XML_SUBSTITUTE_REF, 0, 0, 0); 155 XML_SUBSTITUTE_REF, 0, 0, 0);
151 --ctxt->depth; 156 --ctxt->depth;
157 ent->guard = XML_ENTITY_NOT_BEING_CHECKED;
152 if (ctxt->errNo == XML_ERR_ENTITY_LOOP) { 158 if (ctxt->errNo == XML_ERR_ENTITY_LOOP) {
153 ent->content[0] = 0; 159 ent->content[0] = 0;
154 } 160 }
155 161
156 ent->checked = (ctxt->nbentities - oldnbent + 1) * 2; 162 ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
157 if (rep != NULL) { 163 if (rep != NULL) {
158 if (xmlStrchr(rep, '<')) 164 if (xmlStrchr(rep, '<'))
159 ent->checked |= 1; 165 ent->checked |= 1;
160 xmlFree(rep); 166 xmlFree(rep);
161 rep = NULL; 167 rep = NULL;
(...skipping 7160 matching lines...) Expand 10 before | Expand all | Expand 10 after
7322 user_data = NULL; 7328 user_data = NULL;
7323 else 7329 else
7324 user_data = ctxt->userData; 7330 user_data = ctxt->userData;
7325 7331
7326 /* 7332 /*
7327 * Check that this entity is well formed 7333 * Check that this entity is well formed
7328 * 4.3.2: An internal general parsed entity is well-formed 7334 * 4.3.2: An internal general parsed entity is well-formed
7329 * if its replacement text matches the production labeled 7335 * if its replacement text matches the production labeled
7330 * content. 7336 * content.
7331 */ 7337 */
7332 » if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) { 7338 if (ent->guard == XML_ENTITY_BEING_CHECKED) {
7333 » ctxt->depth++; 7339 ret = XML_ERR_ENTITY_LOOP;
7334 » ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content, 7340 } else {
7335 » user_data, &list); 7341 ent->guard = XML_ENTITY_BEING_CHECKED;
7336 » ctxt->depth--; 7342 if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7337 7343 ctxt->depth++;
7338 » } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) { 7344 ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
7339 » ctxt->depth++; 7345 user_data, &list);
7340 » ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax, 7346 ctxt->depth--;
7341 » user_data, ctxt->depth, ent->URI, 7347 } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7342 » » » » » ent->ExternalID, &list); 7348 ctxt->depth++;
7343 » ctxt->depth--; 7349 ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax ,
7344 » } else { 7350 user_data, ctxt->depth, ent->URI,
7345 » ret = XML_ERR_ENTITY_PE_INTERNAL; 7351 ent->ExternalID, &list);
7346 » xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR, 7352 ctxt->depth--;
7347 » » » "invalid entity type found\n", NULL); 7353 } else {
7348 » } 7354 ret = XML_ERR_ENTITY_PE_INTERNAL;
7355 xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7356 "invalid entity type found\n", NULL);
7357 }
7358 ent->guard = XML_ENTITY_NOT_BEING_CHECKED;
7359 }
7349 7360
7350 /* 7361 /*
7351 * Store the number of entities needing parsing for this entity 7362 * Store the number of entities needing parsing for this entity
7352 * content and do checkings 7363 * content and do checkings
7353 */ 7364 */
7354 ent->checked = (ctxt->nbentities - oldnbent + 1) * 2; 7365 ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
7355 if ((ent->content != NULL) && (xmlStrchr(ent->content, '<'))) 7366 if ((ent->content != NULL) && (xmlStrchr(ent->content, '<')))
7356 ent->checked |= 1; 7367 ent->checked |= 1;
7357 if (ret == XML_ERR_ENTITY_LOOP) { 7368 if (ret == XML_ERR_ENTITY_LOOP) {
7358 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); 7369 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
7441 /* 7452 /*
7442 * This is a bit hackish but this seems the best 7453 * This is a bit hackish but this seems the best
7443 * way to make sure both SAX and DOM entity support 7454 * way to make sure both SAX and DOM entity support
7444 * behaves okay. 7455 * behaves okay.
7445 */ 7456 */
7446 if (ctxt->userData == ctxt) 7457 if (ctxt->userData == ctxt)
7447 user_data = NULL; 7458 user_data = NULL;
7448 else 7459 else
7449 user_data = ctxt->userData; 7460 user_data = ctxt->userData;
7450 7461
7451 » if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) { 7462 if (ent->guard == XML_ENTITY_BEING_CHECKED) {
7452 » » ctxt->depth++; 7463 ret = XML_ERR_ENTITY_LOOP;
7453 » » ret = xmlParseBalancedChunkMemoryInternal(ctxt, 7464 } else {
7454 » » » » ent->content, user_data, NULL); 7465 ent->guard = XML_ENTITY_BEING_CHECKED;
7455 » » ctxt->depth--; 7466 if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7456 » } else if (ent->etype == 7467 ctxt->depth++;
7457 » » XML_EXTERNAL_GENERAL_PARSED_ENTITY) { 7468 ret = xmlParseBalancedChunkMemoryInternal(ctxt,
7458 » » ctxt->depth++; 7469 ent->content, user_data, NULL);
7459 » » ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, 7470 ctxt->depth--;
7460 » » » ctxt->sax, user_data, ctxt->depth, 7471 } else if (ent->etype ==
7461 » » » ent->URI, ent->ExternalID, NULL); 7472 XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7462 » » ctxt->depth--; 7473 ctxt->depth++;
7463 » } else { 7474 ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
7464 » » ret = XML_ERR_ENTITY_PE_INTERNAL; 7475 ctxt->sax, user_data, ctxt->depth,
7465 » » xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR, 7476 ent->URI, ent->ExternalID, NULL);
7466 » » » "invalid entity type found\n", NULL); 7477 ctxt->depth--;
7467 » } 7478 } else {
7479 ret = XML_ERR_ENTITY_PE_INTERNAL;
7480 xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7481 "invalid entity type found\n", NULL);
7482 }
7483 ent->guard = XML_ENTITY_NOT_BEING_CHECKED;
7484 }
7468 if (ret == XML_ERR_ENTITY_LOOP) { 7485 if (ret == XML_ERR_ENTITY_LOOP) {
7469 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); 7486 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7470 return; 7487 return;
7471 } 7488 }
7472 } 7489 }
7473 if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) && 7490 if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7474 (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) { 7491 (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7475 /* 7492 /*
7476 * Entity reference callback comes second, it's somewhat 7493 * Entity reference callback comes second, it's somewhat
7477 * superfluous but a compatibility to historical behaviour 7494 * superfluous but a compatibility to historical behaviour
(...skipping 8330 matching lines...) Expand 10 before | Expand all | Expand 10 after
15808 if (stream == NULL) { 15825 if (stream == NULL) {
15809 xmlFreeParserInputBuffer(input); 15826 xmlFreeParserInputBuffer(input);
15810 return (NULL); 15827 return (NULL);
15811 } 15828 }
15812 inputPush(ctxt, stream); 15829 inputPush(ctxt, stream);
15813 return (xmlDoRead(ctxt, URL, encoding, options, 1)); 15830 return (xmlDoRead(ctxt, URL, encoding, options, 1));
15814 } 15831 }
15815 15832
15816 #define bottom_parser 15833 #define bottom_parser
15817 #include "elfgcchack.h" 15834 #include "elfgcchack.h"
OLDNEW
« no previous file with comments | « third_party/libxml/src/include/libxml/entities.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698