diff --git a/scour/scour.py b/scour/scour.py index 15e0fa0..f27d7e6 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -647,7 +647,7 @@ def removeUnusedDefs(doc, defElem, elemsToRemove=None): for elem in defElem.childNodes: # only look at it if an element and not referenced anywhere else if elem.nodeType == Node.ELEMENT_NODE and (elem.getAttribute('id') == '' or - elem.getAttribute('id') not in referencedIDs): + elem.getAttribute('id') not in referencedIDs): # we only inspect the children of a group in a defs if the group # is not referenced anywhere else if elem.nodeName == 'g' and elem.namespaceURI == NS['SVG']: @@ -3597,9 +3597,7 @@ def scourString(in_string, options=None): # used mostly by unit tests -# input is a filename -# returns the minidom doc representation of the SVG -def scourXmlFile(filename, options=None): +def scourXmlFileAndReturnString(filename, options=None): # sanitize options (take missing attributes from defaults, discard unknown attributes) options = sanitizeOptions(options) # we need to make sure infilename is set correctly (otherwise relative references in the SVG won't work) @@ -3608,7 +3606,14 @@ def scourXmlFile(filename, options=None): # open the file and scour it with open(filename, "rb") as f: in_string = f.read() - out_string = scourString(in_string, options) + + return scourString(in_string, options) + + +# used mostly by unit tests +# returns the minidom doc representation of the SVG +def scourXmlFile(filename, options=None): + out_string = scourXmlFileAndReturnString(filename, options) # prepare the output xml.dom.minidom object doc = xml.dom.minidom.parseString(out_string.encode('utf-8')) diff --git a/testscour.py b/testscour.py index 8ebaf9d..d04fd75 100755 --- a/testscour.py +++ b/testscour.py @@ -30,7 +30,12 @@ import unittest import six from six.moves import map, range -from scour.scour import makeWellFormed, parse_args, scourString, scourXmlFile, start, run +from scour.scour import ( + makeWellFormed, parse_args, scourString, + scourXmlFileAndReturnString, scourXmlFile, + start, run +) + from scour.svg_regex import svg_parser from scour import __version__ @@ -1779,7 +1784,42 @@ class XmlEntities(unittest.TestCase): def runTest(self): self.assertEqual(makeWellFormed('<>&'), '<>&', - 'Incorrectly translated XML entities') + 'Incorrectly translated unquoted XML entities') + self.assertEqual(makeWellFormed('<>&', "'"), '<>&', + 'Incorrectly translated single-quoted XML entities') + self.assertEqual(makeWellFormed('<>&', '"'), '<>&', + 'Incorrectly translated double-quoted XML entities') + + self.assertEqual(makeWellFormed("'"), "'", + 'Incorrectly translated unquoted single quote') + self.assertEqual(makeWellFormed('"'), '"', + 'Incorrectly translated unquoted double quote') + + self.assertEqual(makeWellFormed("'", '"'), "'", + 'Incorrectly translated double-quoted single quote') + self.assertEqual(makeWellFormed('"', "'"), '"', + 'Incorrectly translated single-quoted double quote') + + self.assertEqual(makeWellFormed("'", "'"), ''', + 'Incorrectly translated single-quoted single quote') + self.assertEqual(makeWellFormed('"', '"'), '"', + 'Incorrectly translated double-quoted double quote') + + +class HandleQuotesInAttributes(unittest.TestCase): + + def runTest(self): + output = scourXmlFileAndReturnString('unittests/entities.svg') + self.assertTrue('a="\'"' in output, + 'Failed on attribute value with non-double quote') + self.assertTrue("b='\"'" in output, + 'Failed on attribute value with non-single quote') + self.assertTrue("c=\"''"\"" in output, + 'Failed on attribute value with more single quotes than double quotes') + self.assertTrue('d=\'""'\'' in output, + 'Failed on attribute value with more double quotes than single quotes') + self.assertTrue("e=\"''""\"" in output, + 'Failed on attribute value with the same number of double quotes as single quotes') class DoNotStripCommentsOutsideOfRoot(unittest.TestCase): diff --git a/unittests/entities.svg b/unittests/entities.svg new file mode 100644 index 0000000..2308b46 --- /dev/null +++ b/unittests/entities.svg @@ -0,0 +1,8 @@ + +