fix zero-radius arc crashes and crashes related to use of degenerate Path.closed attribute in parse_path()

pull/130/head
Andrew Port 2020-11-15 16:23:27 -08:00
parent cae729bd48
commit 45dc873f82
3 changed files with 37 additions and 2 deletions

BIN
dist/svgpathtools-1.4.1-py3.7.egg vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,22 @@
<svg version="1.1"
baseProfile="full"
width="1000" height="1000"
xmlns="http://www.w3.org/2000/svg">
<path d="M50,50 A 40 40 0 1 0 100 100Z" stroke="blue" stroke-width="4" fill="yellow"/>
<circle cx="50" cy="50" r="5" stroke="green" stroke-width="1" fill="none"/>
<circle cx="100" cy="100" r="5" stroke="red" stroke-width="1" fill="none"/>
<path d="M150,150 A 0 40 0 1 0 200 200Z" stroke="beige" stroke-width="4" fill="yellow"/>
<circle cx="150" cy="150" r="5" stroke="green" stroke-width="1" fill="none"/>
<circle cx="200" cy="200" r="5" stroke="red" stroke-width="1" fill="none"/>
<path d="M250,250 A 40 0 0 1 0 300 300Z" stroke="purple" stroke-width="4" fill="yellow"/>
<circle cx="250" cy="250" r="5" stroke="green" stroke-width="1" fill="none"/>
<circle cx="300" cy="300" r="5" stroke="red" stroke-width="1" fill="none"/>
<path d="M350,350 A 0 0 0 1 0 400 400Z" stroke="orange" stroke-width="4" fill="yellow"/>
<circle cx="350" cy="350" r="5" stroke="green" stroke-width="1" fill="none"/>
<circle cx="400" cy="400" r="5" stroke="red" stroke-width="1" fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -2967,7 +2967,7 @@ class Path(MutableSequence):
# Close path # Close path
if not (current_pos == start_pos): if not (current_pos == start_pos):
segments.append(Line(current_pos, start_pos)) segments.append(Line(current_pos, start_pos))
self.closed = True self._closed = True
current_pos = start_pos current_pos = start_pos
command = None command = None
@ -3069,6 +3069,7 @@ class Path(MutableSequence):
current_pos = end current_pos = end
elif command == 'A': elif command == 'A':
radius = float(elements.pop()) + float(elements.pop()) * 1j radius = float(elements.pop()) + float(elements.pop()) * 1j
rotation = float(elements.pop()) rotation = float(elements.pop())
arc = float(elements.pop()) arc = float(elements.pop())
@ -3078,7 +3079,19 @@ class Path(MutableSequence):
if not absolute: if not absolute:
end += current_pos end += current_pos
segments.append(Arc(current_pos, radius, rotation, arc, sweep, end)) if radius.real == 0 or radius.imag == 0:
# Note: In browsers AFAIK, zero radius arcs are displayed
# as lines (see "examples/zero-radius-arcs.svg").
# Thus zero radius arcs are substituted for lines here.
warn(f'Replacing degenerate (zero radius) Arc with a '
f'Line: Arc(start={current_pos}, radius={radius}, '
f'rotation={rotation}, large_arc={arc}, '
f'sweep={sweep}, end={end}) -> '
f'Line(start={current_pos}, end={end})')
segments.append(Line(current_pos, end))
else:
segments.append(
Arc(current_pos, radius, rotation, arc, sweep, end))
current_pos = end current_pos = end
return segments return segments