summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Golden <mail@timgolden.me.uk>2014-04-27 15:36:47 (GMT)
committerTim Golden <mail@timgolden.me.uk>2014-04-27 15:36:47 (GMT)
commit3c5816f5e64ed36a0309309606c7123e70fb23c5 (patch)
treeda9d6ffa4f0b5e93255ac62174160137d036d803
parent9b244ad12d72af666586eeddde30e30e5ff0035a (diff)
downloadcpython-3c5816f5e64ed36a0309309606c7123e70fb23c5.zip
cpython-3c5816f5e64ed36a0309309606c7123e70fb23c5.tar.gz
cpython-3c5816f5e64ed36a0309309606c7123e70fb23c5.tar.bz2
Issue #9291 Do not attempt to re-encode mimetype data read from registry in ANSI mode. Initial patches by Dmitry Jemerov & Vladimir Iofik
-rw-r--r--Lib/mimetypes.py38
-rw-r--r--Lib/test/test_mimetypes.py50
2 files changed, 58 insertions, 30 deletions
diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py
index f04f569..7f28b89 100644
--- a/Lib/mimetypes.py
+++ b/Lib/mimetypes.py
@@ -242,38 +242,28 @@ class MimeTypes:
i = 0
while True:
try:
- ctype = _winreg.EnumKey(mimedb, i)
+ yield _winreg.EnumKey(mimedb, i)
except EnvironmentError:
break
- try:
- ctype = ctype.encode(default_encoding) # omit in 3.x!
- except UnicodeEncodeError:
- pass
- else:
- yield ctype
i += 1
- default_encoding = sys.getdefaultencoding()
with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, '') as hkcr:
for subkeyname in enum_types(hkcr):
- try:
- with _winreg.OpenKey(hkcr, subkeyname) as subkey:
- # Only check file extensions
- if not subkeyname.startswith("."):
- continue
- # raises EnvironmentError if no 'Content Type' value
+ # 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:
mimetype, datatype = _winreg.QueryValueEx(
subkey, 'Content Type')
- if datatype != _winreg.REG_SZ:
- continue
- try:
- mimetype = mimetype.encode(default_encoding)
- subkeyname = subkeyname.encode(default_encoding)
- except UnicodeEncodeError:
- continue
- self.add_type(mimetype, subkeyname, strict)
- except EnvironmentError:
- continue
+ except EnvironmentError:
+ continue
+ if datatype != _winreg.REG_SZ:
+ continue
+ self.add_type(mimetype, subkeyname, strict)
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 f8e1e63..d5a8a31 100644
--- a/Lib/test/test_mimetypes.py
+++ b/Lib/test/test_mimetypes.py
@@ -71,8 +71,6 @@ class Win32MimeTypesTestCase(unittest.TestCase):
# ensure all entries actually come from the Windows registry
self.original_types_map = mimetypes.types_map.copy()
mimetypes.types_map.clear()
- mimetypes.init()
- self.db = mimetypes.MimeTypes()
def tearDown(self):
# restore default settings
@@ -84,14 +82,54 @@ class Win32MimeTypesTestCase(unittest.TestCase):
# Windows registry is undocumented AFAIK.
# Use file types that should *always* exist:
eq = self.assertEqual
- eq(self.db.guess_type("foo.txt"), ("text/plain", None))
- eq(self.db.guess_type("image.jpg"), ("image/jpeg", None))
- eq(self.db.guess_type("image.png"), ("image/png", None))
+ mimetypes.init()
+ db = mimetypes.MimeTypes()
+ eq(db.guess_type("foo.txt"), ("text/plain", None))
+ eq(db.guess_type("image.jpg"), ("image/jpeg", None))
+ eq(db.guess_type("image.png"), ("image/png", None))
+
+ def test_non_latin_extension(self):
+ import _winreg
+
+ class MockWinreg(object):
+ def __getattr__(self, name):
+ if name == 'EnumKey':
+ return lambda key, i: _winreg.EnumKey(key, i) + "\xa3"
+ 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 getattr(_winreg, name)
+
+ mimetypes._winreg = MockWinreg()
+ try:
+ # this used to throw an exception if registry contained non-Latin
+ # characters in extensions (issue #9291)
+ mimetypes.init()
+ finally:
+ mimetypes._winreg = _winreg
+
+ def test_non_latin_type(self):
+ import _winreg
+
+ class MockWinreg(object):
+ def __getattr__(self, name):
+ if name == 'QueryValueEx':
+ return lambda subkey, label: (label + "\xa3", _winreg.REG_SZ)
+ return getattr(_winreg, name)
+
+ mimetypes._winreg = MockWinreg()
+ try:
+ # this used to throw an exception if registry contained non-Latin
+ # characters in content types (issue #9291)
+ mimetypes.init()
+ finally:
+ mimetypes._winreg = _winreg
def test_main():
test_support.run_unittest(MimeTypesTestCase,
Win32MimeTypesTestCase
- )
+ )
if __name__ == "__main__":