static_noinline bool is_truncated_end()

in include/yyjson/yyjson.c [3998:4081]


static_noinline bool is_truncated_end(u8 *hdr, u8 *cur, u8 *end,
                                      yyjson_read_code code,
                                      yyjson_read_flag flg) {
    if (cur >= end) return true;
    if (code == YYJSON_READ_ERROR_LITERAL) {
        if (is_truncated_str(cur, end, "true", true) ||
            is_truncated_str(cur, end, "false", true) ||
            is_truncated_str(cur, end, "null", true)) {
            return true;
        }
    }
    if (code == YYJSON_READ_ERROR_UNEXPECTED_CHARACTER ||
        code == YYJSON_READ_ERROR_INVALID_NUMBER ||
        code == YYJSON_READ_ERROR_LITERAL) {
        if (true) {
            if (*cur == '-') cur++;
            if (is_truncated_str(cur, end, "infinity", false) ||
                is_truncated_str(cur, end, "nan", false)) {
                return true;
            }
        }
    }
    if (code == YYJSON_READ_ERROR_UNEXPECTED_CONTENT) {
        if (true) {
            if (hdr + 3 <= cur &&
                is_truncated_str(cur - 3, end, "infinity", false)) {
                return true; /* e.g. infin would be read as inf + in */
            }
        }
    }
    if (code == YYJSON_READ_ERROR_INVALID_STRING) {
        usize len = (usize)(end - cur);
        
        /* unicode escape sequence */
        if (*cur == '\\') {
            if (len == 1) return true;
            if (len <= 5) {
                if (*++cur != 'u') return false;
                for (++cur; cur < end; cur++) {
                    if (!char_is_hex(*cur)) return false;
                }
                return true;
            }
            return false;
        }
        
        /* 2 to 4 bytes UTF-8, see `read_string()` for details. */
        if (*cur & 0x80) {
            u8 c0 = cur[0], c1 = cur[1], c2 = cur[2];
            if (len == 1) {
                /* 2 bytes UTF-8, truncated */
                if ((c0 & 0xE0) == 0xC0 && (c0 & 0x1E) != 0x00) return true;
                /* 3 bytes UTF-8, truncated */
                if ((c0 & 0xF0) == 0xE0) return true;
                /* 4 bytes UTF-8, truncated */
                if ((c0 & 0xF8) == 0xF0 && (c0 & 0x07) <= 0x04) return true;
            }
            if (len == 2) {
                /* 3 bytes UTF-8, truncated */
                if ((c0 & 0xF0) == 0xE0 &&
                    (c1 & 0xC0) == 0x80) {
                    u8 pat = (u8)(((c0 & 0x0F) << 1) | ((c1 & 0x20) >> 5));
                    return 0x01 <= pat && pat != 0x1B;
                }
                /* 4 bytes UTF-8, truncated */
                if ((c0 & 0xF8) == 0xF0 &&
                    (c1 & 0xC0) == 0x80) {
                    u8 pat = (u8)(((c0 & 0x07) << 2) | ((c1 & 0x30) >> 4));
                    return 0x01 <= pat && pat <= 0x10;
                }
            }
            if (len == 3) {
                /* 4 bytes UTF-8, truncated */
                if ((c0 & 0xF8) == 0xF0 &&
                    (c1 & 0xC0) == 0x80 &&
                    (c2 & 0xC0) == 0x80) {
                    u8 pat = (u8)(((c0 & 0x07) << 2) | ((c1 & 0x30) >> 4));
                    return 0x01 <= pat && pat <= 0x10;
                }
            }
        }
    }
    return false;
}