From e7e2f3c31646f6c48d14fff9f16007c99ece7dc7 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 29 Jun 2014 12:58:16 -0700 Subject: don't allow unicode into type_map on Windows (closes #21652) Patch from Vladimir Iofik. --- Lib/mimetypes.py | 29 ++++++++++++++++------------- Lib/test/test_mimetypes.py | 24 +++++++++++++++++++++--- Misc/NEWS | 3 +++ 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 7f28b89651..ec8fd995ee 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -247,23 +247,26 @@ class MimeTypes: break i += 1 + default_encoding = sys.getdefaultencoding() with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, '') as hkcr: for subkeyname in enum_types(hkcr): - # Only check file extensions, not all possible classes - if not subkeyname.startswith("."): - continue - - with _winreg.OpenKey(hkcr, subkeyname) as subkey: - # If there is no "Content Type" value, or if it is not - # a simple string, simply skip - try: + try: + with _winreg.OpenKey(hkcr, subkeyname) as subkey: + # Only check file extensions + if not subkeyname.startswith("."): + continue + # raises EnvironmentError if no 'Content Type' value mimetype, datatype = _winreg.QueryValueEx( subkey, 'Content Type') - except EnvironmentError: - continue - if datatype != _winreg.REG_SZ: - continue - self.add_type(mimetype, subkeyname, strict) + if datatype != _winreg.REG_SZ: + continue + try: + mimetype = mimetype.encode(default_encoding) + except UnicodeEncodeError: + continue + self.add_type(mimetype, subkeyname, strict) + except EnvironmentError: + continue def guess_type(url, strict=True): """Guess the type of a file based on its URL. diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index d5a8a31023..8de42588f6 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + import mimetypes import StringIO import unittest @@ -95,10 +97,10 @@ class Win32MimeTypesTestCase(unittest.TestCase): def __getattr__(self, name): if name == 'EnumKey': return lambda key, i: _winreg.EnumKey(key, i) + "\xa3" - elif name == "OpenKey": + elif name == 'OpenKey': return lambda key, name: _winreg.OpenKey(key, name.rstrip("\xa3")) elif name == 'QueryValueEx': - return lambda subkey, label: (label + "\xa3", _winreg.REG_SZ) + return lambda subkey, label: (u'текст/простой' , _winreg.REG_SZ) return getattr(_winreg, name) mimetypes._winreg = MockWinreg() @@ -115,7 +117,7 @@ class Win32MimeTypesTestCase(unittest.TestCase): class MockWinreg(object): def __getattr__(self, name): if name == 'QueryValueEx': - return lambda subkey, label: (label + "\xa3", _winreg.REG_SZ) + return lambda subkey, label: (u'текст/простой', _winreg.REG_SZ) return getattr(_winreg, name) mimetypes._winreg = MockWinreg() @@ -126,6 +128,22 @@ class Win32MimeTypesTestCase(unittest.TestCase): finally: mimetypes._winreg = _winreg + def test_type_map_values(self): + import _winreg + + class MockWinreg(object): + def __getattr__(self, name): + if name == 'QueryValueEx': + return lambda subkey, label: (u'text/plain', _winreg.REG_SZ) + return getattr(_winreg, name) + + mimetypes._winreg = MockWinreg() + try: + mimetypes.init() + self.assertTrue(isinstance(mimetypes.types_map.values()[0], str)) + finally: + mimetypes._winreg = _winreg + def test_main(): test_support.run_unittest(MimeTypesTestCase, Win32MimeTypesTestCase diff --git a/Misc/NEWS b/Misc/NEWS index 4f86a51fcf..982bf30760 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -35,6 +35,9 @@ Core and Builtins Library ------- +- Issue #21652: Prevent mimetypes.type_map from containing unicode keys on + Windows. + - Issue #21729: Used the "with" statement in the dbm.dumb module to ensure files closing. -- cgit v1.2.1