From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Fri, 4 Apr 2025 14:49:48 +0000 (+0200) Subject: [3.12] gh-130655: Add a test for corrupt `.mo` files in `gettext` (GH-131911) (#132080) X-Git-Tag: v3.12.10~29 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=05213afaa741444543eb69c34347cc55b2b77494;p=thirdparty%2FPython%2Fcpython.git [3.12] gh-130655: Add a test for corrupt `.mo` files in `gettext` (GH-131911) (#132080) gh-130655: Add a test for corrupt `.mo` files in `gettext` (GH-131911) (cherry picked from commit a126cefc176a7ddbd1a09ce560195f6fd81a5c92) Co-authored-by: Tomas R --- diff --git a/Lib/test/test_gettext.py b/Lib/test/test_gettext.py index 33961bcd1b07..0cb1c904c25b 100644 --- a/Lib/test/test_gettext.py +++ b/Lib/test/test_gettext.py @@ -90,6 +90,32 @@ IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1 ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA== ''' +# Corrupt .mo file +# Generated from +# +# msgid "foo" +# msgstr "bar" +# +# with msgfmt --no-hash +# +# The translation offset is changed to 0xFFFFFFFF, +# making it larger than the file size, which should +# raise an error when parsing. +GNU_MO_DATA_CORRUPT = base64.b64encode(bytes([ + 0xDE, 0x12, 0x04, 0x95, # Magic + 0x00, 0x00, 0x00, 0x00, # Version + 0x01, 0x00, 0x00, 0x00, # Message count + 0x1C, 0x00, 0x00, 0x00, # Message offset + 0x24, 0x00, 0x00, 0x00, # Translation offset + 0x00, 0x00, 0x00, 0x00, # Hash table size + 0x2C, 0x00, 0x00, 0x00, # Hash table offset + 0x03, 0x00, 0x00, 0x00, # 1st message length + 0x2C, 0x00, 0x00, 0x00, # 1st message offset + 0x03, 0x00, 0x00, 0x00, # 1st trans length + 0xFF, 0xFF, 0xFF, 0xFF, # 1st trans offset (Modified to make it invalid) + 0x66, 0x6F, 0x6F, 0x00, # Message data + 0x62, 0x61, 0x72, 0x00, # Message data +])) UMO_DATA = b'''\ 3hIElQAAAAADAAAAHAAAADQAAAAAAAAAAAAAAAAAAABMAAAABAAAAE0AAAAQAAAAUgAAAA8BAABj @@ -117,6 +143,7 @@ MOFILE = os.path.join(LOCALEDIR, 'gettext.mo') MOFILE_BAD_MAGIC_NUMBER = os.path.join(LOCALEDIR, 'gettext_bad_magic_number.mo') MOFILE_BAD_MAJOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_major_version.mo') MOFILE_BAD_MINOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_minor_version.mo') +MOFILE_CORRUPT = os.path.join(LOCALEDIR, 'gettext_corrupt.mo') UMOFILE = os.path.join(LOCALEDIR, 'ugettext.mo') MMOFILE = os.path.join(LOCALEDIR, 'metadata.mo') @@ -141,6 +168,8 @@ class GettextBaseTest(unittest.TestCase): fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MAJOR_VERSION)) with open(MOFILE_BAD_MINOR_VERSION, 'wb') as fp: fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MINOR_VERSION)) + with open(MOFILE_CORRUPT, 'wb') as fp: + fp.write(base64.decodebytes(GNU_MO_DATA_CORRUPT)) with open(UMOFILE, 'wb') as fp: fp.write(base64.decodebytes(UMO_DATA)) with open(MMOFILE, 'wb') as fp: @@ -280,6 +309,16 @@ class GettextTestCase2(GettextBaseTest): # Check that no error is thrown with a bad minor version number gettext.GNUTranslations(fp) + def test_corrupt_file(self): + with open(MOFILE_CORRUPT, 'rb') as fp: + with self.assertRaises(OSError) as cm: + gettext.GNUTranslations(fp) + + exception = cm.exception + self.assertEqual(exception.errno, 0) + self.assertEqual(exception.strerror, "File is corrupt") + self.assertEqual(exception.filename, MOFILE_CORRUPT) + def test_some_translations(self): eq = self.assertEqual # test some translations