python / cpython

The Python programming language
https://www.python.org
Other
62.39k stars 29.96k forks source link

mimetypes.init() fails if no access to one of known files #82853

Open 39ff2633-50b5-4d1f-8bb8-ca6cecafc921 opened 4 years ago

39ff2633-50b5-4d1f-8bb8-ca6cecafc921 commented 4 years ago
BPO 38672
Nosy @terryjreedy, @bitdancer, @maxking

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields: ```python assignee = None closed_at = None created_at = labels = ['3.7', '3.8', 'type-bug', 'library', '3.9'] title = 'mimetypes.init() fails if no access to one of known files' updated_at = user = 'https://bugs.python.org/MichaSzymaniak' ``` bugs.python.org fields: ```python activity = actor = 'r.david.murray' assignee = 'none' closed = False closed_date = None closer = None components = ['Library (Lib)'] creation = creator = 'Micha\xc5\x82 Szymaniak' dependencies = [] files = [] hgrepos = [] issue_num = 38672 keywords = [] message_count = 4.0 messages = ['355897', '355907', '356260', '357406'] nosy_count = 5.0 nosy_names = ['terry.reedy', 'r.david.murray', 'SilentGhost', 'maxking', 'Micha\xc5\x82 Szymaniak'] pr_nums = [] priority = 'normal' resolution = None stage = 'test needed' status = 'open' superseder = None type = 'behavior' url = 'https://bugs.python.org/issue38672' versions = ['Python 3.7', 'Python 3.8', 'Python 3.9'] ```

39ff2633-50b5-4d1f-8bb8-ca6cecafc921 commented 4 years ago

When user lacks rights to read on of the mimetypes.knownfiles, mimetypes init() will throw PermissionError and library becomes unusable.

Reproduction steps:
# mkdir -p /etc/httpd/conf/
# touch /etc/httpd/conf/mime.types
# chmod a-r /etc/httpd/conf/mime.types
$ python
>>> import mimetypes
>>> mimetypes.init()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.7/mimetypes.py", line 355, in init
    db.read(file)
  File "/usr/lib/python3.7/mimetypes.py", line 204, in read
    with open(filename, encoding='utf-8') as fp:
PermissionError: [Errno 13] Permission denied: '/etc/httpd/conf/mime.types'
8977102d-e623-4805-b309-cd0ad35b0d72 commented 4 years ago

The fix seems fairly obvious: replacing isfile check with try-catch statement for all OSErrors. Would you like to submit a pull request, Michał?

terryjreedy commented 4 years ago

An exception report is a failure to finish but not a crash as meant here.

The current code requires all known files and any file explicitly passes to be readable. The proposed simple change would make it OK if none of them are. But is this really OK?

Is it really OK if known files are not readable? Should they not be readable by all?

Removing the isfile call would allow directories to be passed through to db.readfp. This might not be a good idea. We would definitely have to think about what errors might be raised on different systems.

I think the try-except should be in init rather than db.read. The latter can be called directly and I think a user explicitly passing an filename should be notified. This comment actually also applies to files passed to init.

[Sidenote: the doc says that MimeTypes "provides an interface similar to the one of the mimetypes module." The mimetypes.db used by mimetypes functions *is* a MimeTypes instance and the user can call db methods anything after init().]

Overall, I am not convinced that the current behavior is a bug, in which case this is an 'enhancement' request that changes the current API. I am not at all a mimetypes expert, so I nosied a couple of email people who have worked on the module and should know more.

bitdancer commented 4 years ago

I haven't looked at this in detail, but here are my general thoughts: I think it would be reasonable to expect that the module would function even if the file permissions are screwed up, similar to how unix commands that try to read .netrc will (try to) function even if its permissions are wrong. I would, however, expect the module to emit a warning in that case. I'm of two minds about the behavior when the caller specifies filenames explicitly. I could see that going either way, but I lean slightly toward making the behavior consistent. While the programmer might appreciate the traceback, the user of the program would probably appreciate the "try to keep going" behavior, since the filenames provided will often be in the same class of "standard defaults" as the existing well known files are, just in the context of that particular application. But like I said, that is just a lean, and I could go the other way on this as well :)

I haven't looked at the isflie issue, but it seems reasonable that if the path exists we should make sure it is a file before reading it...but perhaps readfp will effectively do that? Write a test and see what happens :)

I don't know whether to call this change a bug fix or a feature, so I guess we'd default to feature unless someone can tilt the balance with an argument :)