* xmlURIEscapeStr: * @str: string to escape * @list: exception list string of chars not to escape * * This routine escapes a string to hex, ignoring unreserved characters * a-z, A-Z, 0-9, "-._~", a few sub-delims "!*'()", the gen-delim "@" * (why?) and the characters in the exception list. * * Returns a new escaped string or NULL in case of error. */
| 1674 | * Returns a new escaped string or NULL in case of error. |
| 1675 | */ |
| 1676 | xmlChar * |
| 1677 | xmlURIEscapeStr(const xmlChar *str, const xmlChar *list) { |
| 1678 | xmlChar *ret, ch; |
| 1679 | xmlChar *temp; |
| 1680 | const xmlChar *in; |
| 1681 | int len, out; |
| 1682 | |
| 1683 | if (str == NULL) |
| 1684 | return(NULL); |
| 1685 | if (str[0] == 0) |
| 1686 | return(xmlStrdup(str)); |
| 1687 | len = xmlStrlen(str); |
| 1688 | |
| 1689 | len += 20; |
| 1690 | ret = (xmlChar *) xmlMallocAtomic(len); |
| 1691 | if (ret == NULL) |
| 1692 | return(NULL); |
| 1693 | in = (const xmlChar *) str; |
| 1694 | out = 0; |
| 1695 | while(*in != 0) { |
| 1696 | if (len - out <= 3) { |
| 1697 | if (len > INT_MAX / 2) |
| 1698 | return(NULL); |
| 1699 | temp = xmlRealloc(ret, len * 2); |
| 1700 | if (temp == NULL) { |
| 1701 | xmlFree(ret); |
| 1702 | return(NULL); |
| 1703 | } |
| 1704 | ret = temp; |
| 1705 | len *= 2; |
| 1706 | } |
| 1707 | |
| 1708 | ch = *in; |
| 1709 | |
| 1710 | if ((ch != '@') && (!IS_UNRESERVED(ch)) && (!xmlStrchr(list, ch))) { |
| 1711 | unsigned char val; |
| 1712 | ret[out++] = '%'; |
| 1713 | val = ch >> 4; |
| 1714 | if (val <= 9) |
| 1715 | ret[out++] = '0' + val; |
| 1716 | else |
| 1717 | ret[out++] = 'A' + val - 0xA; |
| 1718 | val = ch & 0xF; |
| 1719 | if (val <= 9) |
| 1720 | ret[out++] = '0' + val; |
| 1721 | else |
| 1722 | ret[out++] = 'A' + val - 0xA; |
| 1723 | in++; |
| 1724 | } else { |
| 1725 | ret[out++] = *in++; |
| 1726 | } |
| 1727 | |
| 1728 | } |
| 1729 | ret[out] = 0; |
| 1730 | return(ret); |
| 1731 | } |
| 1732 | |
| 1733 | /** |
no test coverage detected