* xmlExpandPEsInEntityValue: * @ctxt: parser context * @buf: string buffer * @str: entity value * @length: size of entity value * @depth: nesting depth * * Validate an entity value and expand parameter entities. */
| 3739 | * Validate an entity value and expand parameter entities. |
| 3740 | */ |
| 3741 | static void |
| 3742 | xmlExpandPEsInEntityValue(xmlParserCtxtPtr ctxt, xmlSBuf *buf, |
| 3743 | const xmlChar *str, int length, int depth) { |
| 3744 | int maxDepth = (ctxt->options & XML_PARSE_HUGE) ? 40 : 20; |
| 3745 | const xmlChar *end, *chunk; |
| 3746 | int c, l; |
| 3747 | |
| 3748 | if (str == NULL) |
| 3749 | return; |
| 3750 | |
| 3751 | depth += 1; |
| 3752 | if (depth > maxDepth) { |
| 3753 | xmlFatalErrMsg(ctxt, XML_ERR_RESOURCE_LIMIT, |
| 3754 | "Maximum entity nesting depth exceeded"); |
| 3755 | return; |
| 3756 | } |
| 3757 | |
| 3758 | end = str + length; |
| 3759 | chunk = str; |
| 3760 | |
| 3761 | while ((str < end) && (!PARSER_STOPPED(ctxt))) { |
| 3762 | c = *str; |
| 3763 | |
| 3764 | if (c >= 0x80) { |
| 3765 | l = xmlUTF8MultibyteLen(ctxt, str, |
| 3766 | "invalid character in entity value\n"); |
| 3767 | if (l == 0) { |
| 3768 | if (chunk < str) |
| 3769 | xmlSBufAddString(buf, chunk, str - chunk); |
| 3770 | xmlSBufAddReplChar(buf); |
| 3771 | str += 1; |
| 3772 | chunk = str; |
| 3773 | } else { |
| 3774 | str += l; |
| 3775 | } |
| 3776 | } else if (c == '&') { |
| 3777 | if (str[1] == '#') { |
| 3778 | if (chunk < str) |
| 3779 | xmlSBufAddString(buf, chunk, str - chunk); |
| 3780 | |
| 3781 | c = xmlParseStringCharRef(ctxt, &str); |
| 3782 | if (c == 0) |
| 3783 | return; |
| 3784 | |
| 3785 | xmlSBufAddChar(buf, c); |
| 3786 | |
| 3787 | chunk = str; |
| 3788 | } else { |
| 3789 | xmlChar *name; |
| 3790 | |
| 3791 | /* |
| 3792 | * General entity references are checked for |
| 3793 | * syntactic validity. |
| 3794 | */ |
| 3795 | str++; |
| 3796 | name = xmlParseStringName(ctxt, &str); |
| 3797 | |
| 3798 | if ((name == NULL) || (*str++ != ';')) { |
no test coverage detected