* xmlParserEntityCheck: * @ctxt: parser context * @extra: sum of unexpanded entity sizes * * Check for non-linear entity expansion behaviour. * * In some cases like xmlExpandEntityInAttValue, this function is called * for each, possibly nested entity and its unexpanded content length. * * In other cases like xmlParseReference, it's only called for each * top-level entity with its unexp
| 453 | * Returns 1 on error, 0 on success. |
| 454 | */ |
| 455 | static int |
| 456 | xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long extra) |
| 457 | { |
| 458 | unsigned long consumed; |
| 459 | unsigned long *expandedSize; |
| 460 | xmlParserInputPtr input = ctxt->input; |
| 461 | xmlEntityPtr entity = input->entity; |
| 462 | |
| 463 | if ((entity) && (entity->flags & XML_ENT_CHECKED)) |
| 464 | return(0); |
| 465 | |
| 466 | /* |
| 467 | * Compute total consumed bytes so far, including input streams of |
| 468 | * external entities. |
| 469 | */ |
| 470 | consumed = input->consumed; |
| 471 | xmlSaturatedAddSizeT(&consumed, input->cur - input->base); |
| 472 | xmlSaturatedAdd(&consumed, ctxt->sizeentities); |
| 473 | |
| 474 | if (entity) |
| 475 | expandedSize = &entity->expandedSize; |
| 476 | else |
| 477 | expandedSize = &ctxt->sizeentcopy; |
| 478 | |
| 479 | /* |
| 480 | * Add extra cost and some fixed cost. |
| 481 | */ |
| 482 | xmlSaturatedAdd(expandedSize, extra); |
| 483 | xmlSaturatedAdd(expandedSize, XML_ENT_FIXED_COST); |
| 484 | |
| 485 | /* |
| 486 | * It's important to always use saturation arithmetic when tracking |
| 487 | * entity sizes to make the size checks reliable. If "sizeentcopy" |
| 488 | * overflows, we have to abort. |
| 489 | */ |
| 490 | if ((*expandedSize > XML_PARSER_ALLOWED_EXPANSION) && |
| 491 | ((*expandedSize >= ULONG_MAX) || |
| 492 | (*expandedSize / ctxt->maxAmpl > consumed))) { |
| 493 | xmlFatalErrMsg(ctxt, XML_ERR_RESOURCE_LIMIT, |
| 494 | "Maximum entity amplification factor exceeded, see " |
| 495 | "xmlCtxtSetMaxAmplification.\n"); |
| 496 | xmlHaltParser(ctxt); |
| 497 | return(1); |
| 498 | } |
| 499 | |
| 500 | return(0); |
| 501 | } |
| 502 | |
| 503 | /************************************************************************ |
| 504 | * * |
no test coverage detected