Commit 2455b31e authored by Tim Golden's avatar Tim Golden

Issue #9291 Do not attempt to re-encode mimetype data read from registry in...

Issue #9291 Do not attempt to re-encode mimetype data read from registry in ANSI mode. Initial patches by Dmitry Jemerov & Vladimir Iofik
parent 990334e1
...@@ -242,38 +242,28 @@ class MimeTypes: ...@@ -242,38 +242,28 @@ class MimeTypes:
i = 0 i = 0
while True: while True:
try: try:
ctype = _winreg.EnumKey(mimedb, i) yield _winreg.EnumKey(mimedb, i)
except EnvironmentError: except EnvironmentError:
break break
try:
ctype = ctype.encode(default_encoding) # omit in 3.x!
except UnicodeEncodeError:
pass
else:
yield ctype
i += 1 i += 1
default_encoding = sys.getdefaultencoding()
with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, '') as hkcr: with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, '') as hkcr:
for subkeyname in enum_types(hkcr): for subkeyname in enum_types(hkcr):
try: # Only check file extensions, not all possible classes
with _winreg.OpenKey(hkcr, subkeyname) as subkey: if not subkeyname.startswith("."):
# Only check file extensions continue
if not subkeyname.startswith("."):
continue with _winreg.OpenKey(hkcr, subkeyname) as subkey:
# raises EnvironmentError if no 'Content Type' value # If there is no "Content Type" value, or if it is not
# a simple string, simply skip
try:
mimetype, datatype = _winreg.QueryValueEx( mimetype, datatype = _winreg.QueryValueEx(
subkey, 'Content Type') subkey, 'Content Type')
if datatype != _winreg.REG_SZ: except EnvironmentError:
continue continue
try: if datatype != _winreg.REG_SZ:
mimetype = mimetype.encode(default_encoding) continue
subkeyname = subkeyname.encode(default_encoding) self.add_type(mimetype, subkeyname, strict)
except UnicodeEncodeError:
continue
self.add_type(mimetype, subkeyname, strict)
except EnvironmentError:
continue
def guess_type(url, strict=True): def guess_type(url, strict=True):
"""Guess the type of a file based on its URL. """Guess the type of a file based on its URL.
......
...@@ -71,8 +71,6 @@ class Win32MimeTypesTestCase(unittest.TestCase): ...@@ -71,8 +71,6 @@ class Win32MimeTypesTestCase(unittest.TestCase):
# ensure all entries actually come from the Windows registry # ensure all entries actually come from the Windows registry
self.original_types_map = mimetypes.types_map.copy() self.original_types_map = mimetypes.types_map.copy()
mimetypes.types_map.clear() mimetypes.types_map.clear()
mimetypes.init()
self.db = mimetypes.MimeTypes()
def tearDown(self): def tearDown(self):
# restore default settings # restore default settings
...@@ -84,14 +82,54 @@ class Win32MimeTypesTestCase(unittest.TestCase): ...@@ -84,14 +82,54 @@ class Win32MimeTypesTestCase(unittest.TestCase):
# Windows registry is undocumented AFAIK. # Windows registry is undocumented AFAIK.
# Use file types that should *always* exist: # Use file types that should *always* exist:
eq = self.assertEqual eq = self.assertEqual
eq(self.db.guess_type("foo.txt"), ("text/plain", None)) mimetypes.init()
eq(self.db.guess_type("image.jpg"), ("image/jpeg", None)) db = mimetypes.MimeTypes()
eq(self.db.guess_type("image.png"), ("image/png", None)) 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(): def test_main():
test_support.run_unittest(MimeTypesTestCase, test_support.run_unittest(MimeTypesTestCase,
Win32MimeTypesTestCase Win32MimeTypesTestCase
) )
if __name__ == "__main__": if __name__ == "__main__":
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment