mathandy / svgpathtools

A collection of tools for manipulating and analyzing SVG Path objects and Bezier curves.
MIT License
557 stars 142 forks source link

Fixed crash with inconsistent yet valid paths #123

Closed abey79 closed 4 years ago

abey79 commented 4 years ago

Path._parse_path() currently crashes when it encounters inconsistent, yet valid path commands, such as:

Although such SVG shouldn't be generated, they are not an uncommon sight in procedurally generated files. The above examples actually are real world example (related bugs: abey79/vpype#58, abey79/vpype#59).

This fix avoids setting self.closed=True with such spurious path commands and uses a Line instead of an Arc if either of the radii is 0 (consistently with how macOS/Safari/Chrome handles such issue).

abey79 commented 4 years ago

@mathandy Any chance you could have a look at this PR and possibly release it? That's currently the last thing keeping me from dropping my fork as a dependancy.

mathandy commented 4 years ago

@abey79 thanks for the report/pr. I just pushed fixes for these problems. Now zero radius arcs are replaced with lines as you suggested and a warning is issued when this happens. I changed the self.closed = True to self._closed=True to prevent the Z-related crashes.

Please let me know if this solution works for you. If it does, I'll upload to PyPI.

abey79 commented 4 years ago

Thanks for looking at this!

Everything looks good on my side. The only thing would be this somewhat strange warning I get with degenerate arcs (see the second line):

$ vpype read tests/data/test_svg/issue_59/minimal.svg 
/Users/hhip/Library/Caches/pypoetry/virtualenvs/vpype-l5n3HO8W-py3.8/lib/python3.8/site-packages/svgpathtools/path.py:3086: UserWarning: Replacing degenerate (zero radius) Arc with a Line: Arc(start=(1.77+1.77j), radius=0j, rotation=0.0, large_arc=1.0, sweep=0.0, end=(101.77+101.77j)) -> Line(start=(1.77+1.77j), end=(101.77+101.77j))
  warn(f'Replacing degenerate (zero radius) Arc with a '