GeezerVison is showing github.com — review · gitpython-developers/GitPython@2c9b9a9
File tree
Expand file treeCollapse file tree
Open diff view settings
Expand file treeCollapse file tree
Open diff view settings
Collapse file
Copy file name to clipboardExpand all lines: git/objects/commit.py +6-4Lines changed: 6 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -897,14 +897,16 @@ def _deserialize(self, stream: BytesIO) -> "Commit": |
897 | 897 | buf = enc.strip() |
898 | 898 | while buf: |
899 | 899 | if buf[0:9] == b"encoding ": |
900 | | - encoding = buf[buf.find(b" ") + 1 :].decode(self.encoding, "ignore") |
| 900 | + raw_encoding = buf[9:] |
901 | 901 | try: |
| 902 | + # Codec names are ASCII, independent of the content encoding. |
| 903 | + encoding = raw_encoding.decode("ascii") |
902 | 904 | # Probe one byte: decoding b"" skips the codec lookup entirely. |
903 | 905 | b" ".decode(encoding, "replace") |
904 | 906 | except (LookupError, ValueError): |
905 | | - # The encoding is not a text encoding Python knows; keep the |
906 | | - # default so the identity and message lines still decode below. |
907 | | - _logger.error("Ignoring unknown commit encoding %r", encoding) |
| 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) |
908 | 910 | else: |
909 | 911 | self.encoding = encoding |
910 | 912 | elif buf[0:7] == b"gpgsig ": |
|
Collapse file
Copy file name to clipboardExpand all lines: test/test_commit.py +20Lines changed: 20 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -493,6 +493,26 @@ def test_deserialization_unknown_declared_encoding(self): |
493 | 493 | self.assertEqual(cmt.author.name, "Andr�") |
494 | 494 | self.assertEqual(cmt.message, "R�sum�\n") |
495 | 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 | + |
| 505 | + |
| 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 | + |
496 | 516 | @with_rw_directory |
497 | 517 | def test_identity_cannot_alter_headers(self, rw_dir): |
498 | 518 | """A name or email must not add header lines or present another identity.""" |
|