GhostManager / Ghostwriter

The SpecterOps project management and reporting engine
https://ghostwriter.wiki
BSD 3-Clause "New" or "Revised" License
1.32k stars 181 forks source link

Nesting Blockquote Inside List Breaks Export #516

Closed er4z0r closed 3 weeks ago

er4z0r commented 3 weeks ago

Describe the bug A colleague of mine has managed (according to them using only copy & paste + editor) to produce an issue description that broke the document export.

To Reproduce Steps to reproduce the behavior:

  1. Create an issue
  2. Set the following as the content for description (im pasting the HTML here, so use the HTML mode)
    <p>yadda yadda yadda yadda yadda yadda yadda://yadda.yadda-yadda.yadda/yadda/ yadda. yadda yadda
    yadda yadda yadda yadda yadda yadda:</p>\n<p>\xa0</p>\n<blockquote class="blockquote"><span class="italic">yadda
        yadda yadda yadda yadda yadda yadda yaddayadda yadda yadda yadda yadda yadda. yadda yadda yadda yadda yadda
        yadda yadda yadda yadda yadda yadda yadda yadda yadda:yadda yadda yadda yadda. yadda yadda yadda yadda
        yadda yadda yadda yadda yadda yadda yaddayadda yadda yadda-/yadda. yadda yaddayadda:</span>
    </blockquote>\n<blockquote class="blockquote">\n<ul>\n<li><span class="italic">yadda (yadda)</span></li>\n<li><span
                class="italic">yadda</span></li>\n<li><span class="italic">yadda (yadda)</span></li>\n
    </ul>\n</blockquote>\n<blockquote class="blockquote"><br /><span class="italic">yadda yadda yadda yadda yadda yadda
        yaddayadda yadda yadda yadda yadda yadda yadda yadda yadda yadda yadda. yadda yadda/e yadda:yadda
        yadda yadda yadda, yadda yadda yadda yadda yadda yadda yadda yadda yadda yadda yadda yadda
        yadda.</span></blockquote>\n<blockquote class="blockquote"><span class="italic">yadda yadda yadda yadda
        yadda yadda yadda yadda yadda yadda yadda:</span></blockquote>\n<ul>\n<li>\n<blockquote
            class="blockquote"><span class="italic">yadda yadda-yadda yadda Nutzers</span></blockquote>\n</li>\n<li>\n
        <blockquote class="blockquote"><span class="italic">yadda yadda yadda yadda Anforderung</span></blockquote>\n</li>
    \n</ul>\n<p>\xa0</p>\n<p>yadda yadda yaddat yadda yadda yadda yadda yadda yadda yadda yadda
    (yadda.yadda.yadda) yadda yadda syadda yadda yadda. yaddayadda yadda yadda yadda yadda yadda
    yadda yadda yadda yadda-yadda yadda - yadda yadda (yadda yadda yadda). yadda yadda yadda yadda yadda yadda
    yadda yadda yadda yadda. yadda yadda yadda yadda yaddayadda yadda yadda (yadda yadda
    yadda yadda yadda yaddat yadda yadda yadda yadda yadda yaddayadda yadda yadda).</p>\n<p>yadda yadda yadda
    yadda yadda yadda yadda yadda yaddayadda yadda yadda yadda yadda yadda yadda yadda
    yadda yadda yadda yaddayadda.</p>\n<p>\xa0</p>\n<p>\xa0</p>'
  3. Save the issue
  4. Generate the report
  5. Receive the following error: TypeError: ghostwriter.modules.reportwriter.html_to_ooxml.BaseHtmlToOOXML.process_children() got multiple values for keyword argument 'par'

Here's the full stack-trace:

Traceback (most recent call last):
  File "/app/ghostwriter/reporting/views.py", line 2110, in get
    docx = ExportReportDocx(obj, template_loc).run()
  File "/app/ghostwriter/modules/reportwriter/export_report_docx.py", line 291, in run
    context = self._process_richtext(context)
  File "/app/ghostwriter/modules/reportwriter/export_report_docx.py", line 137, in _process_richtext
    finding["description_rt"] = finding_render(finding["description"])
  File "/app/ghostwriter/modules/reportwriter/export_report_docx.py", line 127, in finding_render
    return self._process_rich_text_docx(text, finding_context, finding_evidences, p_style)
  File "/app/ghostwriter/modules/reportwriter/export_report_docx.py", line 73, in _process_rich_text_docx
    HtmlToDocxWithEvidence.run(
  File "/app/ghostwriter/modules/reportwriter/html_to_ooxml.py", line 104, in run
    instance.process_children(tag.children)
  File "/app/ghostwriter/modules/reportwriter/html_to_ooxml.py", line 118, in process_children
    self.process(ch, **kwargs)
  File "/app/ghostwriter/modules/reportwriter/html_to_ooxml.py", line 110, in process
    getattr(self, "tag_" + el.name)(el, **kwargs)
  File "/app/ghostwriter/modules/reportwriter/html_to_docx.py", line 166, in tag_ul
    self.process_children(
  File "/app/ghostwriter/modules/reportwriter/html_to_ooxml.py", line 118, in process_children
    self.process(ch, **kwargs)
  File "/app/ghostwriter/modules/reportwriter/html_to_ooxml.py", line 110, in process
    getattr(self, "tag_" + el.name)(el, **kwargs)
  File "/app/ghostwriter/modules/reportwriter/html_to_docx.py", line 184, in tag_blockquote
    self.process_children(el.children, par=par, **kwargs)

Looks like the issue arises when a blockquote is used inside an unordered list. Expected Behavior TBH I'm not sure. I have no idea how he managed to create that mess. Maybe give a hint to recheck formatting?

Workaround Use "View > Show Blocks" in Editor or modify HTML directly. Change code so blockquote includes the ul if that is what you need.

Server Specs:

Additional context I still have to check this one on 4.2.5 but since that currently breaks my export (see #499) it will take time. Could you please try to reproduce it on 4.2.5 in the meantime? Confirmed to also affect 4.2.5

chrismaddalena commented 3 weeks ago

Thanks for providing the sample, @er4z0r! This is fixed as part of #513.

er4z0r commented 3 weeks ago

Added the stacktrace. Just for sake of completeness. Also here is a minimized code sample for testing:

<ul>
<li>
<blockquote class="blockquote"><span class="italic">yadda yadda-yadda yadda</span></blockquote>
</li>
</ul>

Looks like it only happens with blockquote inside ul/li. I tried the other way around and it did not trigger.

er4z0r commented 3 weeks ago

Hey, I just tested this on my installation updated to 4.2.5 and it seems the issue still persists.


ERROR 2024-09-11 08:56:50,418 __init__ 16 140347578334008 Template TypeError, may be a bug or an issue with the template
Traceback (most recent call last):
  File "/app/ghostwriter/modules/reportwriter/base/__init__.py", line 62, in map_jinja2_render_errors
    return callback()
  File "/app/ghostwriter/modules/reportwriter/base/docx.py", line 227, in <lambda>
    lambda: HtmlToDocxWithEvidence.run(
  File "/app/ghostwriter/modules/reportwriter/richtext/ooxml.py", line 111, in run
    instance.process_children(tag.children)
  File "/app/ghostwriter/modules/reportwriter/richtext/ooxml.py", line 125, in process_children
    self.process(ch, **kwargs)
  File "/app/ghostwriter/modules/reportwriter/richtext/ooxml.py", line 117, in process
    getattr(self, "tag_" + el.name)(el, **kwargs)
  File "/app/ghostwriter/modules/reportwriter/richtext/docx.py", line 199, in tag_ul
    self.process_children(
  File "/app/ghostwriter/modules/reportwriter/richtext/ooxml.py", line 125, in process_children
    self.process(ch, **kwargs)
  File "/app/ghostwriter/modules/reportwriter/richtext/ooxml.py", line 117, in process
    getattr(self, "tag_" + el.name)(el, **kwargs)
  File "/app/ghostwriter/modules/reportwriter/richtext/docx.py", line 221, in tag_blockquote
    self.process_children(el.children, par=par, **kwargs)
TypeError: ghostwriter.modules.reportwriter.richtext.ooxml.BaseHtmlToOOXML.process_children() got multiple values for keyword argument 'par'
ColonelThirtyTwo commented 3 weeks ago

To clarify, v4.3.0-rc1 has a patch that fixes the error, but blockquotes-in-lists and vice versa aren't really supported in Word, so the output isn't amazing. Both "blockquote" and "list paragraph" are "styles" and a Word paragraph can only have one. You can try it yourself by trying to apply a Quote style in Word onto a list - at least for me, it strips the list bullets when doing so.

Specifically commit 3646614b2de97f9flc20, which should have mentioned this issue in its description.

er4z0r commented 3 weeks ago

Ah okay that explains it. I had misread the comment by chris. Probably undercaffeinated. I'll check in the pre-release. As long as it does not break report generation I'm good. The resulting word document needs some finishing touches anyway.

ColonelThirtyTwo commented 3 weeks ago

Whoops that's not actually true... I don't think I actually pushed the commit I was thinking of.