11from __future__ import print_function
2+ import six
23import base64
34import gzip
45import os
56import os .path
67import io
78from io import BytesIO
9+ import re
810import sys
911from xml .dom .minidom import parseString
1012
@@ -16,7 +18,7 @@ def __init__(self, name, value):
1618
1719 def write_xml (self , parent_element , dom ):
1820 d_elem = dom .createElement ('custom_data' )
19- d_elem .setAttribute ('name' , self .name )
21+ d_elem .setAttribute ('name' , XmlWriter . invalid_xml_remove ( self .name ) )
2022 cdata = dom .createCDATASection (self .value )
2123 d_elem .appendChild (cdata )
2224 parent_element .appendChild (d_elem )
@@ -78,9 +80,9 @@ def set_link_annotation(self, path=None):
7880
7981 def write_xml (self , parent_element , dom ):
8082 annotation = dom .createElement ("annotation" )
81- annotation .setAttribute ("description" , self .description )
83+ annotation .setAttribute ("description" , XmlWriter . invalid_xml_remove ( self .description ) )
8284 annotation .setAttribute ("level" , self .level )
83- annotation .setAttribute ("name" , self .name )
85+ annotation .setAttribute ("name" , XmlWriter . invalid_xml_remove ( self .name ) )
8486
8587 if self .file_path is not None :
8688 if self .link_file :
@@ -100,7 +102,7 @@ def write_xml(self, parent_element, dom):
100102 # add comments
101103 for comment in self .comments :
102104 c_elem = dom .createElement ("comment" )
103- c_elem .setAttribute ("label" , comment .name )
105+ c_elem .setAttribute ("label" , XmlWriter . invalid_xml_remove ( comment .name ) )
104106 cdata = dom .createCDATASection (comment .comment )
105107 c_elem .appendChild (cdata )
106108 annotation .appendChild (c_elem )
@@ -292,8 +294,8 @@ def _write_suite(self, parent_node, test_suite):
292294 suite_elem = parent_node
293295 if not test_suite .is_root_suite :
294296 suite_elem = self .dom .createElement ('test_suite' )
295- suite_elem .setAttribute ('name' , test_suite .name )
296- suite_elem .setAttribute ('description' , test_suite .description )
297+ suite_elem .setAttribute ('name' , XmlWriter . invalid_xml_remove ( test_suite .name ) )
298+ suite_elem .setAttribute ('description' , XmlWriter . invalid_xml_remove ( test_suite .description ) )
297299 suite_elem .setAttribute ('start_time' , str (test_suite .start_time ))
298300 parent_node .appendChild (suite_elem )
299301 if test_suite .duration > 0 :
@@ -315,8 +317,8 @@ def _write_suite(self, parent_node, test_suite):
315317 def _write_test_case (self , parent_node , test_case ):
316318 elem_tc = self .dom .createElement ('test_case' )
317319
318- elem_tc .setAttribute ('name' , test_case .name )
319- elem_tc .setAttribute ('description' , test_case .description )
320+ elem_tc .setAttribute ('name' , XmlWriter . invalid_xml_remove ( test_case .name ) )
321+ elem_tc .setAttribute ('description' , XmlWriter . invalid_xml_remove ( test_case .description ) )
320322 elem_tc .setAttribute ('status' , test_case .status )
321323 elem_tc .setAttribute ('start_time' , test_case .start_time )
322324 elem_tc .setAttribute ('duration' , str (test_case .duration ))
@@ -328,6 +330,26 @@ def _write_test_case(self, parent_node, test_case):
328330 for d in test_case .custom_data :
329331 d .write_xml (elem_tc , self .dom )
330332
333+ @staticmethod
334+ def invalid_xml_remove (string_to_clean ):
335+ # http://stackoverflow.com/questions/1707890/fast-way-to-filter-illegal-xml-unicode-chars-in-python
336+ illegal_unichrs = [
337+ (0x00 , 0x08 ), (0x0B , 0x1F ), (0x7F , 0x84 ), (0x86 , 0x9F ),
338+ (0xD800 , 0xDFFF ), (0xFDD0 , 0xFDDF ), (0xFFFE , 0xFFFF ),
339+ (0x1FFFE , 0x1FFFF ), (0x2FFFE , 0x2FFFF ), (0x3FFFE , 0x3FFFF ),
340+ (0x4FFFE , 0x4FFFF ), (0x5FFFE , 0x5FFFF ), (0x6FFFE , 0x6FFFF ),
341+ (0x7FFFE , 0x7FFFF ), (0x8FFFE , 0x8FFFF ), (0x9FFFE , 0x9FFFF ),
342+ (0xAFFFE , 0xAFFFF ), (0xBFFFE , 0xBFFFF ), (0xCFFFE , 0xCFFFF ),
343+ (0xDFFFE , 0xDFFFF ), (0xEFFFE , 0xEFFFF ), (0xFFFFE , 0xFFFFF ),
344+ (0x10FFFE , 0x10FFFF )]
345+
346+ illegal_ranges = ["%s-%s" % (six .unichr (low ), six .unichr (high ))
347+ for (low , high ) in illegal_unichrs
348+ if low < sys .maxunicode ]
349+
350+ illegal_xml_re = re .compile (six .u ('[%s]' ) % six .u ('' ).join (illegal_ranges ))
351+ return illegal_xml_re .sub ('' , string_to_clean )
352+
331353
332354class TestspaceReport (TestSuite ):
333355 def __init__ (self ):
0 commit comments