| 367 | } |
| 368 | |
| 369 | int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end, |
| 370 | unsigned int flags) |
| 371 | { |
| 372 | const uint8_t *p = *bufp; |
| 373 | uint32_t top; |
| 374 | uint64_t code; |
| 375 | int ret = 0, tail_len; |
| 376 | uint32_t overlong_encoding_mins[6] = { |
| 377 | 0x00000000, 0x00000080, 0x00000800, 0x00010000, 0x00200000, 0x04000000, |
| 378 | }; |
| 379 | |
| 380 | if (p >= buf_end) |
| 381 | return 0; |
| 382 | |
| 383 | code = *p++; |
| 384 | |
| 385 | /* first sequence byte starts with 10, or is 1111-1110 or 1111-1111, |
| 386 | which is not admitted */ |
| 387 | if ((code & 0xc0) == 0x80 || code >= 0xFE) { |
| 388 | ret = AVERROR(EILSEQ); |
| 389 | goto end; |
| 390 | } |
| 391 | top = (code & 128) >> 1; |
| 392 | |
| 393 | tail_len = 0; |
| 394 | while (code & top) { |
| 395 | int tmp; |
| 396 | tail_len++; |
| 397 | if (p >= buf_end) { |
| 398 | (*bufp) ++; |
| 399 | return AVERROR(EILSEQ); /* incomplete sequence */ |
| 400 | } |
| 401 | |
| 402 | /* we assume the byte to be in the form 10xx-xxxx */ |
| 403 | tmp = *p++ - 128; /* strip leading 1 */ |
| 404 | if (tmp>>6) { |
| 405 | (*bufp) ++; |
| 406 | return AVERROR(EILSEQ); |
| 407 | } |
| 408 | code = (code<<6) + tmp; |
| 409 | top <<= 5; |
| 410 | } |
| 411 | code &= (top << 1) - 1; |
| 412 | |
| 413 | /* check for overlong encodings */ |
| 414 | av_assert0(tail_len <= 5); |
| 415 | if (code < overlong_encoding_mins[tail_len]) { |
| 416 | ret = AVERROR(EILSEQ); |
| 417 | goto end; |
| 418 | } |
| 419 | |
| 420 | if (code >= 1U<<31) { |
| 421 | ret = AVERROR(EILSEQ); /* out-of-range value */ |
| 422 | goto end; |
| 423 | } |
| 424 | |
| 425 | *codep = code; |
| 426 |
no outgoing calls