@@ -82,6 +82,13 @@ class HTMLSanitizerMixin(object):
8282
8383attr_val_is_uri = ['href' ,'src' ,'cite' ,'action' ,'longdesc' ,
8484'xlink:href' ,'xml:base' ]
85+
86+ svg_attr_val_allows_ref = ['clip-path' ,'color-profile' ,'cursor' ,'fill' ,
87+ 'filter' ,'marker' ,'marker-start' ,'marker-mid' ,'marker-end' ,'mask' ,'stroke' ]
88+
89+ svg_allow_local_href = ['altGlyph' ,'animate' ,'animateColor' ,'animateMotion' ,
90+ 'animateTransform' ,'cursor' ,'feImage' ,'filter' ,'linearGradient' ,'pattern' ,
91+ 'radialGradient' ,'textpath' ,'tref' ,'set' ,'use' ]
8592
8693acceptable_css_properties = ['azimuth' ,'background-color' ,
8794'border-bottom-color' ,'border-collapse' ,'border-color' ,
@@ -136,10 +143,18 @@ def sanitize_token(self, token):
136143if token .has_key ("data" ):
137144attrs = dict ([(name ,val )for name ,val in token ["data" ][::- 1 ]if name in self .allowed_attributes ])
138145for attr in self .attr_val_is_uri :
139- if not attrs .has_key (attr ):continue
146+ if not attrs .has_key (attr ):
147+ continue
140148val_unescaped = re .sub ("[`\000 -\040 \177 -\240 \s]+" ,'' ,unescape (attrs [attr ])).lower ()
141149if re .match ("^[a-z0-9][-+.a-z0-9]*:" ,val_unescaped )and (val_unescaped .split (':' )[0 ]not in self .allowed_protocols ):
142150del attrs [attr ]
151+ for attr in self .svg_attr_val_allows_ref :
152+ if attr in attrs :
153+ attrs [attr ]= re .sub (r'url\s*\(\s*[^#\s][^)]+?\)' ,' ' ,
154+ unescape (attrs [attr ]))
155+ if (token ["name" ]in self .svg_allow_local_href and
156+ 'xlink:href' in attrs and re .find ('^\s*[^#\s].*' ,attrs ['xlink:href' ])):
157+ del attrs ['xlink:href' ]
143158if attrs .has_key ('style' ):
144159attrs ['style' ]= self .sanitize_css (attrs ['style' ])
145160token ["data" ]= [[name ,val ]for name ,val in attrs .items ()]