Skip to content

Improve filename detection for attachments#2844

Merged
liZe merged 2 commits into
mainfrom
attachment-filenames
Jul 22, 2026
Merged

Improve filename detection for attachments#2844
liZe merged 2 commits into
mainfrom
attachment-filenames

Conversation

@liZe

@liZe liZe commented Jul 17, 2026

Copy link
Copy Markdown
Member

Fix #1862.

@liZe liZe added this to the 70.0 milestone Jul 17, 2026
@liZe liZe added the feature New feature that should be supported label Jul 17, 2026
@wtschueller

Copy link
Copy Markdown

I modified the new test into

import weasyprint
import base64

data = base64.encodebytes(b'Weasyprint!\n').decode("utf-8")

html = f'''
  <title>Test document</title>
  <meta charset="utf-8">
  <a
    rel="attachment"
    href="data:text/plain;base64,{data}"
    download>A link that lets you download an attachment</a>
'''

weasyprint.HTML(string=html).write_pdf('test_data_url_with_line_break.pdf') 

Then there is no attachment. I think it is the line break at the end of data resulting in the following html

  <title>Test document</title>
  <meta charset="utf-8">
  <a
    rel="attachment"
    href="data:text/plain;base64,V2Vhc3lwcmludCEK
"
    download>A link that lets you download an attachment</a>

This works with 69.0.

@liZe

liZe commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

I think it is the line break at the end of data resulting in the following html

Oh, you’re right, thanks for the report. That’s because of other, unrelated changes in current main branch.

liZe added a commit that referenced this pull request Jul 21, 2026
That’s another tricky rule of HTML parsing: href attributes are "valid URLs potentially
surrounded by spaces."

Note that other attributes like id or lang don’t accept these spaces.

Related to #2844.
@liZe
liZe force-pushed the attachment-filenames branch from aa7c82d to 7c6e35d Compare July 21, 2026 08:51
@liZe

liZe commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

@wtschueller I updated the main branch and this pull request to handle these spaces correctly and test this case to avoid regressions. Everything should work now, thanks a lot for the report!

@wtschueller

Copy link
Copy Markdown

I think there is still some odd behaviour:

import weasyprint
import base64

data = base64.encodebytes(b'Weasyprint!\n'*5).decode("utf-8")

html = f'''
  <title>Test document</title>
  <meta charset="utf-8">
  <a
    rel="attachment"
    href="data:text/plain;base64,{data}"
    download>A link that lets you download an attachment</a>
'''

weasyprint.HTML(string=html).write_pdf('test_data_url_with_inner_line_break.pdf')

produces an inner line break

  <title>Test document</title>
  <meta charset="utf-8">
  <a
    rel="attachment"
    href="data:text/plain;base64,V2Vhc3lwcmludCEKV2Vhc3lwcmludCEKV2Vhc3lwcmludCEKV2Vhc3lwcmludCEKV2Vhc3lwcmlu
dCEK
"
    download>A link that lets you download an attachment</a>

and then there is still no attachment for download. If I use the same procedure for <img src=".."> then everytthing works as expected.

@liZe

liZe commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

I learned so many details thanks to this example, thanks a lot…

In href attributes we have valid URL potentially surrounded by spaces. Then, let’s remove the leading and trailing spaces and it will work, right?

No.

From the URL specification:

  1. If input contains any ASCII tab or newline, invalid-URL-unit validation error.
  2. Remove all ASCII tab or newline from input.

So, if a URL contains a newline, it should be an error, but we should remove the newline to give this poor URL a chance to be valid.

It works in WeasyPrint for non-href attributes (href puts the link in CSS, that’s a hack that fails for all newlines), but only for base64 URLs, because Python’s function allows newlines in the base64 strings.

I’ll open a new issue to allow URLs to be surrounded by spaces and to ignore ASCII tab and newline characters in them.

@liZe

liZe commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

Merging, as the remaining problems are in #2851, to be solved before next version.

Thanks again for testing and reporting!

@liZe
liZe merged commit 515f676 into main Jul 22, 2026
17 checks passed
@liZe
liZe deleted the attachment-filenames branch July 22, 2026 11:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature that should be supported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Follow HTML specification to set attachments filenames

2 participants