Project

General

Profile

Actions

Defect #44483

open

Infinite loop and memory exhaustion on issue PDF export when an image has width/height attributes

Added by Mohamed Lahssini 21 days ago. Updated 19 days ago.

Status:
Confirmed
Priority:
Normal
Assignee:
-
Category:
PDF export
Resolution:
Affected version:

Description

Exporting an issue to PDF never completes when the issue contains an image with explicit width/height attributes. The Ruby process stays busy in RBPDF text layout, its memory grows to several GB, and on our server several concurrent exports ended in a system-wide OOM kill.

This looks very similar to #36452, which was fixed in RBPDF 1.21.0, but we are running RBPDF 1.21.4.

Environment
Redmine 6.1.4
Ruby 3.4.10
Rails 7.2.3.2
RBPDF 1.21.4
Phusion Passenger 6.1.7 + nginx
Database: MySQL
Plugins: [TO COMPLETE, including redmine_ckeditor]
Reproduced without plugins: [YES / NO / NOT TESTED]
Steps to reproduce
  1. Create an issue with a note containing an image with explicit dimensions wider than the page.
  1. Export the issue to PDF (/issues/ID.pdf)

In our case the notes were written with the CKEditor plugin, which stores the image with an inline style setting the same width and height.

Expected result

The PDF is generated, the image being scaled to the page width (or skipped).

Actual result

The request never ends. On our production instance, one export ran for about 50 minutes before being killed, with very little database time and a very large GC time:

Completed in 3051801ms (ActiveRecord: 15.5ms (58 queries, 7 cached) | GC: 265517.7ms)

Each image of the issue logs the following error at the beginning of the export:

pdf: Image: error: wrong number of arguments (given 3, expected 0..2)

Removing the width/height attributes from the two images wider than the page makes the export complete almost instantly.

Backtrace of the busy thread (captured with SIGQUIT while looping)
rbpdf-1.21.4/lib/rbpdf.rb:16139:in 'RBPDF#setFontSubBuffer'
rbpdf-1.21.4/lib/rbpdf.rb:10332:in 'RBPDF#utf8Bidi'
rbpdf-1.21.4/lib/rbpdf.rb:3601:in 'RBPDF#getCellCode'
rbpdf-1.21.4/lib/rbpdf.rb:3395:in 'RBPDF#Cell'
rbpdf-1.21.4/lib/rbpdf.rb:4639:in 'RBPDF#Write'
rbpdf-1.21.4/lib/rbpdf.rb:14441:in 'RBPDF#writeHTML'
rbpdf-1.21.4/lib/rbpdf.rb:3924:in 'RBPDF#MultiCell'
rbpdf-1.21.4/lib/rbpdf.rb:13418:in 'RBPDF#writeHTMLCell'
lib/redmine/export/pdf.rb:95:in 'Redmine::Export::PDF::ITCPDF#RDMwriteFormattedCell'
lib/redmine/export/pdf/issues_pdf_helper.rb:231:in 'block in Redmine::Export::PDF::IssuesPdfHelper#issue_to_pdf'
lib/redmine/export/pdf/issues_pdf_helper.rb:217:in 'Array#each'
lib/redmine/export/pdf/issues_pdf_helper.rb:217:in 'Redmine::Export::PDF::IssuesPdfHelper#issue_to_pdf'
app/views/issues/show.pdf.erb:1

Notes

Only the two images declared at 1000px wide trigger the loop. Images declared at 600px and 700px in the same issue do not.
Removing the PNG alpha channel from the images did not change anything: the declared width is what matters.
The "wrong number of arguments" error when loading the images may be what prevents RBPDF from scaling them to the page, leaving the layout with no available width.


Related issues

Related to Redmine - Defect #36452: Infinite loop on PDF export if image included with attributes ClosedGo MAEDAActions
Actions #1

Updated by Mohamed Lahssini 21 days ago

Plugins: [redmine_ckeditor (RedmineX)]
Reproduced without plugins: NOT TESTED

Actions #2

Updated by Go MAEDA 19 days ago

  • Category set to PDF export
  • Status changed from New to Confirmed

Thank you for reporting this issue. I was able to reproduce it on the current trunk with RBPDF 1.21.4.

The cause is in RBPDF's writeHTML. When an image with both width and height does not fit in the rest of the line, RBPDF inserts a line break and then writes the text before the image again. The image still does not fit after that text, so this repeats until memory is exhausted.

Steps to reproduce:

1. Attach any image (e.g. any_image.png) to an issue.
2. Set the description to one of the following, depending on the text formatting:

CommonMark Markdown:

Text followed by an image that has width and height and does not fit in the rest of the line: <img src="any_image.png" width="1000" height="1000">

Textile:

Text followed by an image that has width and height and does not fit in the rest of the line: !{width:1000px;height:1000px}any_image.png!

3 Export the issue to PDF.

Temporary workaround:

Please omit the height and specify only the width of the image. RBPDF inserts the line break described above only when both the width and the height are specified. Without the height, RBPDF instead scales the image down, keeping its aspect ratio, to fit in the rest of the line, so the loop does not occur.

Actions #3

Updated by Go MAEDA 19 days ago

  • Subject changed from Infinite loop and memory exhaustion on issue PDF export when an image has width/height attributes (regression of #36452?) to Infinite loop and memory exhaustion on issue PDF export when an image has width/height attributes

Mohamed Lahssini wrote:

This looks very similar to #36452, which was fixed in RBPDF 1.21.0, but we are running RBPDF 1.21.4.

This is very similar to #36452, but it is not a regression. The example given in #36452 no longer reproduces the problem. The case reported here, an image with both width and height placed after text on the same line, was not covered by the fix for #36452.

Actions #4

Updated by Go MAEDA 19 days ago

  • Related to Defect #36452: Infinite loop on PDF export if image included with attributes added
Actions #5

Updated by Go MAEDA 19 days ago

  • Target version set to Candidate for next minor release

RBPDF is based on TCPDF, a PDF library for PHP. The same problem was reported to TCPDF in January 2011 as Bugs / #518 writeHTMLCell Loop and was fixed in TCPDF 5.9.044, released in the same month.

I have confirmed that applying the same change to RBPDF resolves this issue, and I have reported it to RBPDF: naitoh/rbpdf#112. Please see that issue for details, including the proposed fix.

Once a new version of RBPDF with the fix is released as 1.21.x, you will be able to fix this issue by running bundle update rbpdf in the Redmine installation directory. I will also update the Gemfile of Redmine at that time so that it requires the fixed version of RBPDF.

Until this is fixed in RBPDF, the temporary workaround described in #note-2 can be used.

Actions

Also available in: Atom PDF