| 863 | } |
| 864 | |
| 865 | static int |
| 866 | xmlUTF8MultibyteLen(xmlParserCtxtPtr ctxt, const xmlChar *str, |
| 867 | const char *errMsg) { |
| 868 | int c = str[0]; |
| 869 | int c1 = str[1]; |
| 870 | |
| 871 | if ((c1 & 0xC0) != 0x80) |
| 872 | goto encoding_error; |
| 873 | |
| 874 | if (c < 0xE0) { |
| 875 | /* 2-byte sequence */ |
| 876 | if (c < 0xC2) |
| 877 | goto encoding_error; |
| 878 | |
| 879 | return(2); |
| 880 | } else { |
| 881 | int c2 = str[2]; |
| 882 | |
| 883 | if ((c2 & 0xC0) != 0x80) |
| 884 | goto encoding_error; |
| 885 | |
| 886 | if (c < 0xF0) { |
| 887 | /* 3-byte sequence */ |
| 888 | if (c == 0xE0) { |
| 889 | /* overlong */ |
| 890 | if (c1 < 0xA0) |
| 891 | goto encoding_error; |
| 892 | } else if (c == 0xED) { |
| 893 | /* surrogate */ |
| 894 | if (c1 >= 0xA0) |
| 895 | goto encoding_error; |
| 896 | } else if (c == 0xEF) { |
| 897 | /* U+FFFE and U+FFFF are invalid Chars */ |
| 898 | if ((c1 == 0xBF) && (c2 >= 0xBE)) |
| 899 | xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR, errMsg); |
| 900 | } |
| 901 | |
| 902 | return(3); |
| 903 | } else { |
| 904 | /* 4-byte sequence */ |
| 905 | if ((str[3] & 0xC0) != 0x80) |
| 906 | goto encoding_error; |
| 907 | if (c == 0xF0) { |
| 908 | /* overlong */ |
| 909 | if (c1 < 0x90) |
| 910 | goto encoding_error; |
| 911 | } else if (c >= 0xF4) { |
| 912 | /* greater than 0x10FFFF */ |
| 913 | if ((c > 0xF4) || (c1 >= 0x90)) |
| 914 | goto encoding_error; |
| 915 | } |
| 916 | |
| 917 | return(4); |
| 918 | } |
| 919 | } |
| 920 | |
| 921 | encoding_error: |
| 922 | /* Only report the first error */ |
no test coverage detected