deeplook / svglib

Read SVG files and convert them to other formats.
GNU Lesser General Public License v3.0
307 stars 79 forks source link

Error exporting SVG to PDF when certain CSS selectors are used #351

Closed JonathanHolvey closed 1 year ago

JonathanHolvey commented 1 year ago

I'm seeing an error when exporting a simple SVG file to PDF using the renderPDF.drawToFile method. The error occurs when using the wildcard selector * to target all children of a certain element, along with another element directly. The SVG and Python code below demonstrate how to reproduce the issue.

The SVG file test.svg:

<svg version="1.1" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <style>
    #foo,
    #bar * {
      fill: none;
    }
  </style>
  <rect id="foo" x="4" y="4" width="4" height="4"/>
</svg>

Python code to reproduce the issue:

from lxml import etree
from svglib.svglib import SvgRenderer
from reportlab.graphics import renderPDF

document = etree.parse(str('./test.svg'))
svg = document.getroot()

renderer = SvgRenderer(None)
drawing = renderer.render(svg)
renderPDF.drawToFile(drawing, 'test.pdf')

The resulting error:

raceback (most recent call last):
  File "/home/jon/svglib-test/./test.py", line 10, in <module>
    drawing = renderer.render(svg)
  File "/home/jon/.local/share/virtualenvs/svglib-test-ghcUX1K3/lib/python3.10/site-packages/svglib/svglib.py", line 553, in render
    main_group = self.renderSvg(node, outermost=True)
  File "/home/jon/.local/share/virtualenvs/svglib-test-ghcUX1K3/lib/python3.10/site-packages/svglib/svglib.py", line 834, in renderSvg
    self.renderNode(child, group)
  File "/home/jon/.local/share/virtualenvs/svglib-test-ghcUX1K3/lib/python3.10/site-packages/svglib/svglib.py", line 621, in renderNode
    item = self.shape_converter.convertShape(name, n, clipping)
  File "/home/jon/.local/share/virtualenvs/svglib-test-ghcUX1K3/lib/python3.10/site-packages/svglib/svglib.py", line 948, in convertShape
    self.applyStyleOnShape(shape, node)
  File "/home/jon/.local/share/virtualenvs/svglib-test-ghcUX1K3/lib/python3.10/site-packages/svglib/svglib.py", line 1405, in applyStyleOnShape
    svgAttrValue = ac.findAttr(node, svgAttrName)
  File "/home/jon/.local/share/virtualenvs/svglib-test-ghcUX1K3/lib/python3.10/site-packages/svglib/svglib.py", line 194, in findAttr
    svgNode.apply_rules(self.css_rules)
  File "/home/jon/.local/share/virtualenvs/svglib-test-ghcUX1K3/lib/python3.10/site-packages/svglib/svglib.py", line 468, in apply_rules
    matches = rules.match(self)
  File "/home/jon/.local/share/virtualenvs/svglib-test-ghcUX1K3/lib/python3.10/site-packages/cssselect2/__init__.py", line 111, in match
    self.add_relevant_selectors(
  File "/home/jon/.local/share/virtualenvs/svglib-test-ghcUX1K3/lib/python3.10/site-packages/cssselect2/__init__.py", line 120, in add_relevant_selectors
    if test(element):
  File "<string>", line 1, in <lambda>
  File "/home/jon/.local/share/virtualenvs/svglib-test-ghcUX1K3/lib/python3.10/site-packages/svglib/svglib.py", line 503, in __getattr__
    return getattr(self.object, name)
AttributeError: 'lxml.etree._Element' object has no attribute 'ancestors'. Did you mean: 'iterancestors'?

This is a new issue that didn't previously occur with svglib 1.1.0, however, due to updates to dependency packages, it's no longer possible to get this working just by installing that version of svglib. I have a Pipenv lock file in the project that I first saw this issue in, which can be used to install a working set of packages. In that project, I was able to work around the issue by changing the #bar * selector to target direct children only; #bar > *.

github-actions[bot] commented 1 year ago

Thank you for raising your first issue! Your help to improve svglib is much appreciated!

claudep commented 1 year ago

I suppose you are testing with the latest published svglib (1.3.0), right? In that case, could you please test with code from master, as I just pushed a commit that most probably changed the part of the code responsible for the crash.

JonathanHolvey commented 1 year ago

Yes, I was testing with v1.3.0. I can confirm that the test code above works without any errors when using the master branch.

claudep commented 1 year ago

Many thanks for testing, that may mean that a new release should be done soon, I'll plan that.

JonathanHolvey commented 1 year ago

Thanks for the quick response!

claudep commented 1 year ago

1.4.0 was released today.