| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -896,8 +896,19 @@ def _deserialize(self, stream: BytesIO) -> "Commit": | |||
| 896 | 896 | enc = next_line | |
| 897 | 897 | buf = enc.strip() | |
| 898 | 898 | while buf: | |
| 899 | - if buf[0:10] == b"encoding ": | ||
| 900 | - self.encoding = buf[buf.find(b" ") + 1 :].decode(self.encoding, "ignore") | ||
| 899 | + if buf[0:9] == b"encoding ": | ||
| 900 | + raw_encoding = buf[9:] | ||
| 901 | + try: | ||
| 902 | + # Codec names are ASCII, independent of the content encoding. | ||
| 903 | + encoding = raw_encoding.decode("ascii") | ||
| 904 | + # Probe one byte: decoding b"" skips the codec lookup entirely. | ||
| 905 | + b" ".decode(encoding, "replace") | ||
| 906 | + except (LookupError, ValueError): | ||
| 907 | + # Reject malformed names and non-text codecs without changing | ||
| 908 | + # the current encoding (the default unless a valid header was read). | ||
| 909 | + _logger.error("Ignoring invalid commit encoding %r", raw_encoding) | ||
| 910 | + else: | ||
| 911 | + self.encoding = encoding | ||
| 901 | 912 | elif buf[0:7] == b"gpgsig ": | |
| 902 | 913 | sig_lines = [buf[buf.find(b" ") + 1 :] + b"\n"] | |
| 903 | 914 | is_next_header = False | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -458,6 +458,61 @@ def test_invalid_commit(self): | |||
| 458 | 458 | self.assertEqual(cmt.author.name, "E.Azer Ko�o�o�oculu", cmt.author.name) | |
| 459 | 459 | self.assertEqual(cmt.author.email, "azer@kodfabrik.com", cmt.author.email) | |
| 460 | 460 | ||
| 461 | + def test_deserialization_declared_encoding(self): | ||
| 462 | + # The "encoding" header names the encoding of the identity and message bytes. | ||
| 463 | + data = ( | ||
| 464 | + b"tree 3385f7b1e5f91930a3bd3e07105e113fca29981d\n" | ||
| 465 | + b"author Andr\xe9 <andre@example.com> 1112591163 +0200\n" | ||
| 466 | + b"committer Andr\xe9 <andre@example.com> 1112591163 +0200\n" | ||
| 467 | + b"encoding ISO-8859-1\n" | ||
| 468 | + b"\n" | ||
| 469 | + b"R\xe9sum\xe9\n" | ||
| 470 | + ) | ||
| 471 | + cmt = self.rorepo.commit() | ||
| 472 | + cmt._deserialize(BytesIO(data)) | ||
| 473 | + | ||
| 474 | + self.assertEqual(cmt.encoding, "ISO-8859-1") | ||
| 475 | + self.assertEqual(cmt.author.name, "André") | ||
| 476 | + self.assertEqual(cmt.committer.name, "André") | ||
| 477 | + self.assertEqual(cmt.message, "Résumé\n") | ||
| 478 | + | ||
| 479 | + def test_deserialization_unknown_declared_encoding(self): | ||
| 480 | + # An encoding Python has no text codec for falls back to the default encoding. | ||
| 481 | + data = ( | ||
| 482 | + b"tree 3385f7b1e5f91930a3bd3e07105e113fca29981d\n" | ||
| 483 | + b"author Andr\xe9 <andre@example.com> 1112591163 +0200\n" | ||
| 484 | + b"committer Andr\xe9 <andre@example.com> 1112591163 +0200\n" | ||
| 485 | + b"encoding pony-speak\n" | ||
| 486 | + b"\n" | ||
| 487 | + b"R\xe9sum\xe9\n" | ||
| 488 | + ) | ||
| 489 | + cmt = self.rorepo.commit() | ||
| 490 | + cmt._deserialize(BytesIO(data)) | ||
| 491 | + | ||
| 492 | + self.assertEqual(cmt.encoding, cmt.default_encoding) | ||
| 493 | + self.assertEqual(cmt.author.name, "Andr�") | ||
| 494 | + self.assertEqual(cmt.message, "R�sum�\n") | ||
| 495 | + | ||
| 496 | + def test_deserialization_multiple_encoding_headers(self): | ||
| 497 | + for headers in ( | ||
| 498 | + b"encoding utf-16-be\nencoding ISO-8859-1\n", | ||
| 499 | + b"encoding ISO-8859-1\nencoding utf-\xff8\n", | ||
| 500 | + ): | ||
| 501 | + with self.subTest(headers=headers): | ||
| 502 | + data = ( | ||
| 503 | + b"tree 3385f7b1e5f91930a3bd3e07105e113fca29981d\n" | ||
| 504 | + b"author Andr\xe9 <andre@example.com> 1112591163 +0200\n" | ||
| 505 | + b"committer Andr\xe9 <andre@example.com> 1112591163 +0200\n" + headers + b"\n" | ||
| 506 | + b"R\xe9sum\xe9\n" | ||
| 507 | + ) | ||
| 508 | + cmt = self.rorepo.commit() | ||
| 509 | + cmt._deserialize(BytesIO(data)) | ||
| 510 | + | ||
| 511 | + self.assertEqual(cmt.encoding, "ISO-8859-1") | ||
| 512 | + self.assertEqual(cmt.author.name, "André") | ||
| 513 | + self.assertEqual(cmt.committer.name, "André") | ||
| 514 | + self.assertEqual(cmt.message, "Résumé\n") | ||
| 515 | + | ||
| 461 | 516 | @with_rw_directory | |
| 462 | 517 | def test_identity_cannot_alter_headers(self, rw_dir): | |
| 463 | 518 | """A name or email must not add header lines or present another identity.""" | |
| Back | FazBrowse Home | New Git URL |
0 commit comments