Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for _get_attachment, and do not use attachment filename for temporary storage #1553

Merged
merged 5 commits into from
Feb 22, 2022
Merged

Add tests for _get_attachment, and do not use attachment filename for temporary storage #1553

merged 5 commits into from
Feb 22, 2022

Conversation

jwhitlock
Copy link
Member

This PR fixes #1551 by using the prefix "relay_attachment_", and not basing the filename prefix or suffix on user data from the attachment filename. It also adds some tests for _get_attachment().

_get_attachment() uses SpooledTemporaryFile, which holds an attachment in memory until it reaches 150 KiB, when it is stored in a temporary file. Previously, we used the attachment filename to make the prefix and suffix for the temporary file. However, this fails when the attachment filename has invalid characters, such as a colon (:). Now that we support larger files, we're starting to see some large attachments with a URL for the filename (https://example.com/image.jpg), and failures when writing to a tempfile with that name, such as:

FileNotFoundError: [Errno 2] No such file or directory: '/var/folders/_y/72__kkbs2tqd5ch4gwrgnwtr0000gn/T/https://example.com/image7piavr1v.jpg`

With this change, the temporary file will now have a randomly generated name, not related to the attachment name.

There is another potential bug for attachments with no filename, but I have not seen the signature in production yet, where calling prefix=os.path.splitext(fn)[0] results in the error:

TypeError: expected str, bytes or os.PathLike object, not NoneType

emails/tests/views_tests.py Outdated Show resolved Hide resolved
@jwhitlock
Copy link
Member Author

jwhitlock commented Feb 19, 2022

I found Sentry issues for omitted filenames as well

https://sentry.prod.mozaws.net/operations/fx-private-relay-prod/issues/16863848

The line is:

prefix=os.path.splitext(fn)[0]

and the exception is:

TypeError: expected str, bytes or os.PathLike object, not NoneType

This change should also fix that, but we should have a test case for omitted filenames as well. Any, we may need to adjust downstream processing of attachments without filenames, but let's deal with that later.

_get_attachment uses SpooledTemporaryFile, which keeps data in memory
until it exceeds a minumum size. Test a short file, a long file, and a
file with a URL for a name (currently fails).
Do not use the filename of the attachment when creating a
SpooledTemporaryFile. This allows an attachment with a filename, like a
URL, that contains characters like a colon (:) not allowed in some file
systems.
@jwhitlock
Copy link
Member Author

I've rebased on main, refactored the common code to GetAttachmentTests.get_name_and_stream(), and added a test for an omitted filename.

Copy link
Contributor

@say-yawn say-yawn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@jwhitlock jwhitlock dismissed groovecoder’s stale review February 22, 2022 18:38

Changes made, reviewer is unavailable for re-review

@jwhitlock jwhitlock merged commit 87bc277 into mozilla:main Feb 22, 2022
@jwhitlock jwhitlock deleted the attachment_filename_1551 branch February 22, 2022 18:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Attachment name used in temporary local file leads to invalid filenames
3 participants