| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9fe42b4 commit 894263b
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -429,11 +429,18 @@ def test_lone_surrogates(self): | |||
| 429 | 429 | def test_incremental_surrogatepass(self): | |
| 430 | 430 | # Test incremental decoder for surrogatepass handler: | |
| 431 | 431 | # see issue #24214 | |
| 432 | + # High surrogate | ||
| 432 | 433 | data = '\uD901'.encode(self.encoding, 'surrogatepass') | |
| 433 | 434 | for i in range(1, len(data)): | |
| 434 | 435 | dec = codecs.getincrementaldecoder(self.encoding)('surrogatepass') | |
| 435 | 436 | self.assertEqual(dec.decode(data[:i]), '') | |
| 436 | 437 | self.assertEqual(dec.decode(data[i:], True), '\uD901') | |
| 438 | + # Low surrogate | ||
| 439 | + data = '\uDC02'.encode(self.encoding, 'surrogatepass') | ||
| 440 | + for i in range(1, len(data)): | ||
| 441 | + dec = codecs.getincrementaldecoder(self.encoding)('surrogatepass') | ||
| 442 | + self.assertEqual(dec.decode(data[:i]), '') | ||
| 443 | + self.assertEqual(dec.decode(data[i:]), '\uDC02') | ||
| 437 | 444 | ||
| 438 | 445 | ||
| 439 | 446 | class UTF32Test(ReadTest, unittest.TestCase): | |
@@ -874,6 +881,23 @@ def test_surrogatepass_handler(self): | |||
| 874 | 881 | with self.assertRaises(UnicodeDecodeError): | |
| 875 | 882 | b"abc\xed\xa0z".decode(self.encoding, "surrogatepass") | |
| 876 | 883 | ||
| 884 | + def test_incremental_errors(self): | ||
| 885 | + # Test that the incremental decoder can fail with final=False. | ||
| 886 | + # See issue #24214 | ||
| 887 | + cases = [b'\x80', b'\xBF', b'\xC0', b'\xC1', b'\xF5', b'\xF6', b'\xFF'] | ||
| 888 | + for prefix in (b'\xC2', b'\xDF', b'\xE0', b'\xE0\xA0', b'\xEF', | ||
| 889 | + b'\xEF\xBF', b'\xF0', b'\xF0\x90', b'\xF0\x90\x80', | ||
| 890 | + b'\xF4', b'\xF4\x8F', b'\xF4\x8F\xBF'): | ||
| 891 | + for suffix in b'\x7F', b'\xC0': | ||
| 892 | + cases.append(prefix + suffix) | ||
| 893 | + cases.extend((b'\xE0\x80', b'\xE0\x9F', b'\xED\xA0\x80', | ||
| 894 | + b'\xED\xBF\xBF', b'\xF0\x80', b'\xF0\x8F', b'\xF4\x90')) | ||
| 895 | + | ||
| 896 | + for data in cases: | ||
| 897 | + with self.subTest(data=data): | ||
| 898 | + dec = codecs.getincrementaldecoder(self.encoding)() | ||
| 899 | + self.assertRaises(UnicodeDecodeError, dec.decode, data) | ||
| 900 | + | ||
| 877 | 901 | ||
| 878 | 902 | class UTF7Test(ReadTest, unittest.TestCase): | |
| 879 | 903 | encoding = "utf-7" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Improved support of the surrogatepass error handler in the UTF-8 and UTF-16 | ||
| 2 | + incremental decoders. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -207,7 +207,7 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, | |||
| 207 | 207 | goto InvalidContinuation1; | |
| 208 | 208 | } else if (ch == 0xF4 && ch2 >= 0x90) { | |
| 209 | 209 | /* invalid sequence | |
| 210 | - \xF4\x90\x80\80- -- 110000- overflow */ | ||
| 210 | + \xF4\x90\x80\x80- -- 110000- overflow */ | ||
| 211 | 211 | goto InvalidContinuation1; | |
| 212 | 212 | } | |
| 213 | 213 | if (!IS_CONTINUATION_BYTE(ch3)) { | |
@@ -573,10 +573,10 @@ STRINGLIB(utf16_decode)(const unsigned char **inptr, const unsigned char *e, | |||
| 573 | 573 | } | |
| 574 | 574 | ||
| 575 | 575 | /* UTF-16 code pair: */ | |
| 576 | - if (q >= e) | ||
| 577 | - goto UnexpectedEnd; | ||
| 578 | 576 | if (!Py_UNICODE_IS_HIGH_SURROGATE(ch)) | |
| 579 | 577 | goto IllegalEncoding; | |
| 578 | + if (q >= e) | ||
| 579 | + goto UnexpectedEnd; | ||
| 580 | 580 | ch2 = (q[ihi] << 8) | q[ilo]; | |
| 581 | 581 | q += 2; | |
| 582 | 582 | if (!Py_UNICODE_IS_LOW_SURROGATE(ch2)) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4945,11 +4945,15 @@ unicode_decode_utf8(const char *s, Py_ssize_t size, | |||
| 4945 | 4945 | endinpos = startinpos + 1; | |
| 4946 | 4946 | break; | |
| 4947 | 4947 | case 2: | |
| 4948 | - case 3: | ||
| 4949 | - case 4: | ||
| 4950 | - if (s == end || consumed) { | ||
| 4948 | + if (consumed && (unsigned char)s[0] == 0xED && end - s == 2 | ||
| 4949 | + && (unsigned char)s[1] >= 0xA0 && (unsigned char)s[1] <= 0xBF) | ||
| 4950 | + { | ||
| 4951 | + /* Truncated surrogate code in range D800-DFFF */ | ||
| 4951 | 4952 | goto End; | |
| 4952 | 4953 | } | |
| 4954 | + /* fall through */ | ||
| 4955 | + case 3: | ||
| 4956 | + case 4: | ||
| 4953 | 4957 | errmsg = "invalid continuation byte"; | |
| 4954 | 4958 | startinpos = s - starts; | |
| 4955 | 4959 | endinpos = startinpos + ch - 1; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments