Skip to content

Commit a5f05df

Browse files
committed
fix: scanny#758 quote in autoshape name must be escaped
At least one autoshape name ('"No" Symbol') contains the double-quote character which raises an XML exception when it prematurely terminates the `name="..."` attribute of the autoshape. Escape autoshape basename to avoid this problem, specifically targetting the double-quote character.
1 parent df5e968 commit a5f05df

File tree

4 files changed

+19
-11
lines changed

4 files changed

+19
-11
lines changed

pptx/enum/shapes.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ class MSO_AUTO_SHAPE_TYPE(XmlEnumeration):
501501
"notchedRightArrow",
502502
"Notched block arrow that points right",
503503
),
504-
XmlMappedEnumMember("NO_SYMBOL", 19, "noSmoking", '"No" symbol'),
504+
XmlMappedEnumMember("NO_SYMBOL", 19, "noSmoking", '"No" Symbol'),
505505
XmlMappedEnumMember("OCTAGON", 6, "octagon", "Octagon"),
506506
XmlMappedEnumMember("OVAL", 9, "ellipse", "Oval"),
507507
XmlMappedEnumMember(
@@ -858,11 +858,7 @@ def width(self):
858858
return self._width
859859

860860
def __contains__(self, item):
861-
return item in (
862-
self.DOCX,
863-
self.PPTX,
864-
self.XLSX,
865-
)
861+
return item in (self.DOCX, self.PPTX, self.XLSX,)
866862

867863
def __repr__(self):
868864
return "%s.PROG_ID" % __name__

pptx/shapes/autoshape.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from __future__ import absolute_import, division, print_function, unicode_literals
66

77
from numbers import Number
8+
import xml.sax.saxutils as saxutils
89

910
from pptx.dml.fill import FillFormat
1011
from pptx.dml.line import LineFormat
@@ -234,11 +235,14 @@ def autoshape_type_id(self):
234235

235236
@property
236237
def basename(self):
238+
"""Base of shape name for this auto shape type.
239+
240+
A shape name is like "Rounded Rectangle 7" and appears as an XML attribute for
241+
example at `p:sp/p:nvSpPr/p:cNvPr{name}`. This basename value is the name less
242+
the distinguishing integer. This value is escaped because at least one
243+
autoshape-type name includes double quotes ('"No" Symbol').
237244
"""
238-
Base of shape name (less the distinguishing integer) for this auto
239-
shape type
240-
"""
241-
return self._basename
245+
return saxutils.escape(self._basename, {'"': """})
242246

243247
@classmethod
244248
def default_adjustment_values(cls, prst):

pptx/spec.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@
468468
"basename": "Notched Right Arrow",
469469
"avLst": (("adj1", 50000), ("adj2", 50000)),
470470
},
471-
MSO_SHAPE.NO_SYMBOL: {"basename": '"No" symbol', "avLst": (("adj", 18750),)},
471+
MSO_SHAPE.NO_SYMBOL: {"basename": '"No" Symbol', "avLst": (("adj", 18750),)},
472472
MSO_SHAPE.OCTAGON: {"basename": "Octagon", "avLst": (("adj", 29289),)},
473473
MSO_SHAPE.OVAL: {"basename": "Oval", "avLst": ()},
474474
MSO_SHAPE.OVAL_CALLOUT: {

tests/shapes/test_autoshape.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,12 +260,20 @@ def indexed_assignment_fixture_(self, request):
260260

261261

262262
class DescribeAutoShapeType(object):
263+
"""Unit-test suite for `pptx.shapes.autoshape.AutoShapeType`"""
264+
263265
def it_knows_the_details_of_the_auto_shape_type_it_represents(self):
264266
autoshape_type = AutoShapeType(MSO_SHAPE.ROUNDED_RECTANGLE)
265267
assert autoshape_type.autoshape_type_id == MSO_SHAPE.ROUNDED_RECTANGLE
266268
assert autoshape_type.prst == "roundRect"
267269
assert autoshape_type.basename == "Rounded Rectangle"
268270

271+
def it_xml_escapes_the_basename_when_the_name_contains_special_characters(self):
272+
autoshape_type = AutoShapeType(MSO_SHAPE.NO_SYMBOL)
273+
assert autoshape_type.autoshape_type_id == MSO_SHAPE.NO_SYMBOL
274+
assert autoshape_type.prst == "noSmoking"
275+
assert autoshape_type.basename == ""No" Symbol"
276+
269277
def it_knows_the_default_adj_vals_for_its_autoshape_type(
270278
self, default_adj_vals_fixture_
271279
):

0 commit comments

Comments
 (0)