<s> """<STR_LIT>""" <EOL> import re <EOL> from genshi . core import Attrs , QName , stripentities <EOL> from genshi . core import END , START , TEXT , COMMENT <EOL> __all__ = [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> __docformat__ = '<STR_LIT>' <EOL> class HTMLFormFiller ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , name = None , id = None , data = None ) : <EOL> """<STR_LIT>""" <EOL> self . name = name <EOL> self . id = id <EOL> if data is None : <EOL> data = { } <EOL> self . data = data <EOL> def __call__ ( self , stream ) : <EOL> """<STR_LIT>""" <EOL> in_form = in_select = in_option = in_textarea = False <EOL> select_value = option_value = textarea_value = None <EOL> option_start = None <EOL> option_text = [ ] <EOL> no_option_value = False <EOL> for kind , data , pos in stream : <EOL> if kind is START : <EOL> tag , attrs = data <EOL> tagname = tag . localname <EOL> if tagname == '<STR_LIT>' and ( <EOL> self . name and attrs . get ( '<STR_LIT:name>' ) == self . name or <EOL> self . id and attrs . get ( '<STR_LIT:id>' ) == self . id or <EOL> not ( self . id or self . name ) ) : <EOL> in_form = True <EOL> elif in_form : <EOL> if tagname == '<STR_LIT:input>' : <EOL> type = attrs . get ( '<STR_LIT:type>' ) <EOL> if type in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> name = attrs . get ( '<STR_LIT:name>' ) <EOL> if name and name in self . data : <EOL> value = self . data [ name ] <EOL> declval = attrs . get ( '<STR_LIT:value>' ) <EOL> checked = False <EOL> if isinstance ( value , ( list , tuple ) ) : <EOL> if declval : <EOL> checked = declval in [ unicode ( v ) for v <EOL> in value ] <EOL> else : <EOL> checked = bool ( filter ( None , value ) ) <EOL> else : <EOL> if declval : <EOL> checked = declval == unicode ( value ) <EOL> elif type == '<STR_LIT>' : <EOL> checked = bool ( value ) <EOL> if checked : <EOL> attrs |= [ ( QName ( '<STR_LIT>' ) , '<STR_LIT>' ) ] <EOL> elif '<STR_LIT>' in attrs : <EOL> attrs -= '<STR_LIT>' <EOL> elif type in ( None , '<STR_LIT>' , '<STR_LIT:text>' ) : <EOL> name = attrs . get ( '<STR_LIT:name>' ) <EOL> if name and name in self . data : <EOL> value = self . data [ name ] <EOL> if isinstance ( value , ( list , tuple ) ) : <EOL> value = value [ <NUM_LIT:0> ] <EOL> if value is not None : <EOL> attrs |= [ ( QName ( '<STR_LIT:value>' ) , unicode ( value ) ) ] <EOL> elif tagname == '<STR_LIT>' : <EOL> name = attrs . get ( '<STR_LIT:name>' ) <EOL> if name in self . data : <EOL> select_value = self . data [ name ] <EOL> in_select = True <EOL> elif tagname == '<STR_LIT>' : <EOL> name = attrs . get ( '<STR_LIT:name>' ) <EOL> if name in self . data : <EOL> textarea_value = self . data . get ( name ) <EOL> if isinstance ( textarea_value , ( list , tuple ) ) : <EOL> textarea_value = textarea_value [ <NUM_LIT:0> ] <EOL> in_textarea = True <EOL> elif in_select and tagname == '<STR_LIT>' : <EOL> option_start = kind , data , pos <EOL> option_value = attrs . get ( '<STR_LIT:value>' ) <EOL> if option_value is None : <EOL> no_option_value = True <EOL> option_value = '<STR_LIT>' <EOL> in_option = True <EOL> continue <EOL> yield kind , ( tag , attrs ) , pos <EOL> elif in_form and kind is TEXT : <EOL> if in_select and in_option : <EOL> if no_option_value : <EOL> option_value += data <EOL> option_text . append ( ( kind , data , pos ) ) <EOL> continue <EOL> elif in_textarea : <EOL> continue <EOL> yield kind , data , pos <EOL> elif in_form and kind is END : <EOL> tagname = data . localname <EOL> if tagname == '<STR_LIT>' : <EOL> in_form = False <EOL> elif tagname == '<STR_LIT>' : <EOL> in_select = False <EOL> select_value = None <EOL> elif in_select and tagname == '<STR_LIT>' : <EOL> if isinstance ( select_value , ( tuple , list ) ) : <EOL> selected = option_value in [ unicode ( v ) for v <EOL> in select_value ] <EOL> else : <EOL> selected = option_value == unicode ( select_value ) <EOL> okind , ( tag , attrs ) , opos = option_start <EOL> if selected : <EOL> attrs |= [ ( QName ( '<STR_LIT>' ) , '<STR_LIT>' ) ] <EOL> elif '<STR_LIT>' in attrs : <EOL> attrs -= '<STR_LIT>' <EOL> yield okind , ( tag , attrs ) , opos <EOL> if option_text : <EOL> for event in option_text : <EOL> yield event <EOL> in_option = False <EOL> no_option_value = False <EOL> option_start = option_value = None <EOL> option_text = [ ] <EOL> elif tagname == '<STR_LIT>' : <EOL> if textarea_value : <EOL> yield TEXT , unicode ( textarea_value ) , pos <EOL> in_textarea = False <EOL> yield kind , data , pos <EOL> else : <EOL> yield kind , data , pos <EOL> class HTMLSanitizer ( object ) : <EOL> """<STR_LIT>""" <EOL> SAFE_TAGS = frozenset ( [ '<STR_LIT:a>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:address>' , '<STR_LIT>' , '<STR_LIT:b>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT:code>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT:i>' , '<STR_LIT>' , '<STR_LIT:input>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:label>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:p>' , '<STR_LIT>' , '<STR_LIT:q>' , '<STR_LIT:s>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:u>' , <EOL> '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> SAFE_ATTRS = frozenset ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT:action>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:class>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:id>' , '<STR_LIT>' , '<STR_LIT:label>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:name>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:size>' , <EOL> '<STR_LIT>' , '<STR_LIT:src>' , '<STR_LIT:start>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:target>' , '<STR_LIT:title>' , <EOL> '<STR_LIT:type>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:value>' , '<STR_LIT>' , '<STR_LIT:width>' ] ) <EOL> SAFE_SCHEMES = frozenset ( [ '<STR_LIT:file>' , '<STR_LIT>' , '<STR_LIT:http>' , '<STR_LIT>' , '<STR_LIT>' , None ] ) <EOL> URI_ATTRS = frozenset ( [ '<STR_LIT:action>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT:src>' ] ) <EOL> def __init__ ( self , safe_tags = SAFE_TAGS , safe_attrs = SAFE_ATTRS , <EOL> safe_schemes = SAFE_SCHEMES , uri_attrs = URI_ATTRS ) : <EOL> """<STR_LIT>""" <EOL> self . safe_tags = safe_tags <EOL> "<STR_LIT>" <EOL> self . safe_attrs = safe_attrs <EOL> "<STR_LIT>" <EOL> self . uri_attrs = uri_attrs <EOL> "<STR_LIT>" <EOL> self . safe_schemes = safe_schemes <EOL> "<STR_LIT>" <EOL> def __call__ ( self , stream ) : <EOL> """<STR_LIT>""" <EOL> waiting_for = None <EOL> for kind , data , pos in stream : <EOL> if kind is START : <EOL> if waiting_for : <EOL> continue <EOL> tag , attrs = data <EOL> if tag not in self . safe_tags : <EOL> waiting_for = tag <EOL> continue <EOL> new_attrs = [ ] <EOL> for attr , value in attrs : <EOL> value = stripentities ( value ) <EOL> if attr not in self . safe_attrs : <EOL> continue <EOL> elif attr in self . uri_attrs : <EOL> if not self . is_safe_uri ( value ) : <EOL> continue <EOL> elif attr == '<STR_LIT>' : <EOL> decls = self . sanitize_css ( value ) <EOL> if not decls : <EOL> continue <EOL> value = '<STR_LIT>' . join ( decls ) <EOL> new_attrs . append ( ( attr , value ) ) <EOL> yield kind , ( tag , Attrs ( new_attrs ) ) , pos <EOL> elif kind is END : <EOL> tag = data <EOL> if waiting_for : <EOL> if waiting_for == tag : <EOL> waiting_for = None <EOL> else : <EOL> yield kind , data , pos <EOL> elif kind is not COMMENT : <EOL> if not waiting_for : <EOL> yield kind , data , pos <EOL> def is_safe_uri ( self , uri ) : <EOL> """<STR_LIT>""" <EOL> if '<STR_LIT::>' not in uri : <EOL> return True <EOL> chars = [ char for char in uri . split ( '<STR_LIT::>' , <NUM_LIT:1> ) [ <NUM_LIT:0> ] if char . isalnum ( ) ] <EOL> return '<STR_LIT>' . join ( chars ) . lower ( ) in self . safe_schemes <EOL> def sanitize_css ( self , text ) : <EOL> """<STR_LIT>""" <EOL> decls = [ ] <EOL> text = self . _strip_css_comments ( self . _replace_unicode_escapes ( text ) ) <EOL> for decl in filter ( None , text . split ( '<STR_LIT:;>' ) ) : <EOL> decl = decl . strip ( ) <EOL> if not decl : <EOL> continue <EOL> is_evil = False <EOL> if '<STR_LIT>' in decl : <EOL> is_evil = True <EOL> for match in re . finditer ( r'<STR_LIT>' , decl ) : <EOL> if not self . is_safe_uri ( match . group ( <NUM_LIT:1> ) ) : <EOL> is_evil = True <EOL> break <EOL> if not is_evil : <EOL> decls . append ( decl . strip ( ) ) <EOL> return decls <EOL> _NORMALIZE_NEWLINES = re . compile ( r'<STR_LIT:\r\n>' ) . sub <EOL> _UNICODE_ESCAPE = re . compile ( r'<STR_LIT>' ) . sub <EOL> def _replace_unicode_escapes ( self , text ) : <EOL> def _repl ( match ) : <EOL> return unichr ( int ( match . group ( <NUM_LIT:1> ) , <NUM_LIT:16> ) ) <EOL> return self . _UNICODE_ESCAPE ( _repl , self . _NORMALIZE_NEWLINES ( '<STR_LIT:\n>' , text ) ) <EOL> _CSS_COMMENTS = re . compile ( r'<STR_LIT>' ) . sub <EOL> def _strip_css_comments ( self , text ) : <EOL> return self . _CSS_COMMENTS ( '<STR_LIT>' , text ) </s>
