@@ -82,6 +82,13 @@ class HTMLSanitizerMixin(object):
82
82
83
83
attr_val_is_uri = ['href' ,'src' ,'cite' ,'action' ,'longdesc' ,
84
84
'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' ]
85
92
86
93
acceptable_css_properties = ['azimuth' ,'background-color' ,
87
94
'border-bottom-color' ,'border-collapse' ,'border-color' ,
@@ -136,10 +143,18 @@ def sanitize_token(self, token):
136
143
if token .has_key ("data" ):
137
144
attrs = dict ([(name ,val )for name ,val in token ["data" ][::- 1 ]if name in self .allowed_attributes ])
138
145
for attr in self .attr_val_is_uri :
139
- if not attrs .has_key (attr ):continue
146
+ if not attrs .has_key (attr ):
147
+ continue
140
148
val_unescaped = re .sub ("[`\000 -\040 \177 -\240 \s]+" ,'' ,unescape (attrs [attr ])).lower ()
141
149
if re .match ("^[a-z0-9][-+.a-z0-9]*:" ,val_unescaped )and (val_unescaped .split (':' )[0 ]not in self .allowed_protocols ):
142
150
del 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' ]
143
158
if attrs .has_key ('style' ):
144
159
attrs ['style' ]= self .sanitize_css (attrs ['style' ])
145
160
token ["data" ]= [[name ,val ]for name ,val in attrs .items ()]