* Parse a numeric character reference (e.g., "/" or "/"). * The "&#" has already been consumed. */
| 874 | * The "&#" has already been consumed. |
| 875 | */ |
| 876 | static const char *Html_parse_numeric_charref(DilloHtml *html, char *tok, |
| 877 | bool_t is_attr, int *entsize) |
| 878 | { |
| 879 | static char buf[5]; |
| 880 | char *s = tok; |
| 881 | int n, codepoint = -1; |
| 882 | |
| 883 | errno = 0; |
| 884 | |
| 885 | if (*s == 'x' || *s == 'X') { |
| 886 | if (isxdigit(*++s)) { |
| 887 | /* strtol with base 16 accepts leading "0x" - we don't */ |
| 888 | if (*s == '0' && s[1] == 'x') { |
| 889 | s++; |
| 890 | codepoint = 0; |
| 891 | } else { |
| 892 | codepoint = strtol(s, &s, 16); |
| 893 | } |
| 894 | } |
| 895 | } else if (isdigit(*s)) { |
| 896 | codepoint = strtol(s, &s, 10); |
| 897 | } |
| 898 | if (errno) |
| 899 | codepoint = -1; |
| 900 | |
| 901 | if (*s == ';') |
| 902 | s++; |
| 903 | else { |
| 904 | if (prefs.show_extra_warnings && (html->DocType == DT_XHTML || |
| 905 | (html->DocType == DT_HTML && html->DocTypeVersion <= 4.01f))) { |
| 906 | char c = *s; |
| 907 | *s = '\0'; |
| 908 | BUG_MSG("Character reference '&#%s' lacks ';'.", tok); |
| 909 | *s = c; |
| 910 | } |
| 911 | /* Don't require ';' for old HTML, except that our current heuristic |
| 912 | * is to require it in attributes to avoid cases like "©=1" found |
| 913 | * in URLs. |
| 914 | */ |
| 915 | if (is_attr || html->DocType == DT_XHTML || |
| 916 | (html->DocType == DT_HTML && html->DocTypeVersion >= 5.0f)) { |
| 917 | return NULL; |
| 918 | } |
| 919 | |
| 920 | } |
| 921 | if ((codepoint < 0x20 && codepoint != '\t' && codepoint != '\n' && |
| 922 | codepoint != '\f') || |
| 923 | (codepoint >= 0x7f && codepoint <= 0x9f) || |
| 924 | (codepoint >= 0xd800 && codepoint <= 0xdfff) || codepoint > 0x10ffff || |
| 925 | ((codepoint & 0xfffe) == 0xfffe) || |
| 926 | (!(html->DocType == DT_HTML && html->DocTypeVersion >= 5.0f) && |
| 927 | codepoint > 0xffff)) { |
| 928 | /* this catches null bytes, errors, codes out of range, disallowed |
| 929 | * control chars, permanently undefined chars, and surrogates. |
| 930 | */ |
| 931 | char c = *s; |
| 932 | *s = '\0'; |
| 933 | BUG_MSG("Numeric character reference '&#%s' is not valid.", tok); |
no test coverage detected