PK!Tt*Gqq)__pycache__/__init__.cpython-36.opt-1.pycnu[3 B;W@sdS)Nrrr/usr/lib/python3.6/__init__.pysPK!Tt*Gqq#__pycache__/__init__.cpython-36.pycnu[3 B;W@sdS)Nrrr/usr/lib/python3.6/__init__.pysPK!Z7__pycache__/alphabeticalattributes.cpython-36.opt-1.pycnu[3 B;Wm @shddlmZmZmZddlmZyddlmZWn ek rPddl mZYnXGdddej Z dS))absolute_importdivisionunicode_literals)base) OrderedDictc@seZdZddZdS)Filterccshxbtjj|D]R}|ddkrZt}x,t|djdddD]\}}|||<q>W||d<|VqWdS) NtypeStartTagEmptyTagdatacSs|dS)Nr)xr r ,/usr/lib/python3.6/alphabeticalattributes.pysz!Filter.__iter__..)key)r r )rr__iter__rsorteditems)selftokenZattrsnamevaluer r rr s  zFilter.__iter__N)__name__ __module__ __qualname__rr r r rr srN) Z __future__rrrr collectionsr ImportErrorZ ordereddictrr r r rs  PK!Z1__pycache__/alphabeticalattributes.cpython-36.pycnu[3 B;Wm @shddlmZmZmZddlmZyddlmZWn ek rPddl mZYnXGdddej Z dS))absolute_importdivisionunicode_literals)base) OrderedDictc@seZdZddZdS)Filterccshxbtjj|D]R}|ddkrZt}x,t|djdddD]\}}|||<q>W||d<|VqWdS) NtypeStartTagEmptyTagdatacSs|dS)Nr)xr r ,/usr/lib/python3.6/alphabeticalattributes.pysz!Filter.__iter__..)key)r r )rr__iter__rsorteditems)selftokenZattrsnamevaluer r rr s  zFilter.__iter__N)__name__ __module__ __qualname__rr r r rr srN) Z __future__rrrr collectionsr ImportErrorZ ordereddictrr r r rs  PK!<%__pycache__/base.cpython-36.opt-1.pycnu[3 B;W@s(ddlmZmZmZGdddeZdS))absolute_importdivisionunicode_literalsc@s$eZdZddZddZddZdS)FiltercCs ||_dS)N)source)selfrr/usr/lib/python3.6/base.py__init__szFilter.__init__cCs t|jS)N)iterr)rrrr __iter__szFilter.__iter__cCs t|j|S)N)getattrr)rnamerrr __getattr__ szFilter.__getattr__N)__name__ __module__ __qualname__r r rrrrr rsrN)Z __future__rrrobjectrrrrr sPK!<__pycache__/base.cpython-36.pycnu[3 B;W@s(ddlmZmZmZGdddeZdS))absolute_importdivisionunicode_literalsc@s$eZdZddZddZddZdS)FiltercCs ||_dS)N)source)selfrr/usr/lib/python3.6/base.py__init__szFilter.__init__cCs t|jS)N)iterr)rrrr __iter__szFilter.__iter__cCs t|j|S)N)getattrr)rnamerrr __getattr__ szFilter.__getattr__N)__name__ __module__ __qualname__r r rrrrr rsrN)Z __future__rrrobjectrrrrr sPK!lNN4__pycache__/inject_meta_charset.cpython-36.opt-1.pycnu[3 B;W @s6ddlmZmZmZddlmZGdddejZdS))absolute_importdivisionunicode_literals)basec@seZdZddZddZdS)FiltercCstjj||||_dS)N)rr__init__encoding)selfsourcer r )/usr/lib/python3.6/inject_meta_charset.pyrszFilter.__init__c csd}|jdk}g}xtjj|D]}|d}|dkrP|djdkrLd}np|dkrV|djdkrd }x|d jD]V\\}}} |dk rq~q~|jd kr|j|d ||f<d }Pq~|d kr~| jdkr~d }q~W|od|d krTd|j|d d<d }nR|djdkr| rdd|d dVddd|jidVdddVd }q"nj|dkr|djdkr|r|jdV|sddd|jidVx|r|jdVqWd }d}|dkr|j|q"|Vq"WdS)NZpre_headtypeZStartTagnameheadZin_headZEmptyTagmetaFdatacharsetTz http-equivz content-typecontentztext/html; charset=%s)rrrZEndTag)rrrZ post_head)Nr)Nr)Nr)Nr)r rr__iter__loweritemspopappend) r stateZ meta_foundpendingtokenrZhas_http_equiv_content_type namespacervaluer r r r sX        zFilter.__iter__N)__name__ __module__ __qualname__rrr r r r rsrN)Z __future__rrrrrr r r r s PK!lNN.__pycache__/inject_meta_charset.cpython-36.pycnu[3 B;W @s6ddlmZmZmZddlmZGdddejZdS))absolute_importdivisionunicode_literals)basec@seZdZddZddZdS)FiltercCstjj||||_dS)N)rr__init__encoding)selfsourcer r )/usr/lib/python3.6/inject_meta_charset.pyrszFilter.__init__c csd}|jdk}g}xtjj|D]}|d}|dkrP|djdkrLd}np|dkrV|djdkrd }x|d jD]V\\}}} |dk rq~q~|jd kr|j|d ||f<d }Pq~|d kr~| jdkr~d }q~W|od|d krTd|j|d d<d }nR|djdkr| rdd|d dVddd|jidVdddVd }q"nj|dkr|djdkr|r|jdV|sddd|jidVx|r|jdVqWd }d}|dkr|j|q"|Vq"WdS)NZpre_headtypeZStartTagnameheadZin_headZEmptyTagmetaFdatacharsetTz http-equivz content-typecontentztext/html; charset=%s)rrrZEndTag)rrrZ post_head)Nr)Nr)Nr)Nr)r rr__iter__loweritemspopappend) r stateZ meta_foundpendingtokenrZhas_http_equiv_content_type namespacervaluer r r r sX        zFilter.__iter__N)__name__ __module__ __qualname__rrr r r r rsrN)Z __future__rrrrrr r r r s PK!e  %__pycache__/lint.cpython-36.opt-1.pycnu[3 B;W @shddlmZmZmZddlmZddlmZddlm Z m Z ddlm Z dj e Z Gd d d ej Z d S) )absolute_importdivisionunicode_literals) text_type)base) namespaces voidElements)spaceCharacterscs&eZdZdfdd ZddZZS)FilterTcstt|j|||_dS)N)superr __init__require_matching_tags)selfsourcer) __class__/usr/lib/python3.6/lint.pyr szFilter.__init__c cs@g}x4tjj|D]"}|d}|dkr|d}|d}| sL|tdkrV|tkrVn|dkrr|jrr|j||fx|djD] \\}}}qWn|dkr|d}|d}| s|tdkr|tkrn|jr|j}n\|d kr|d}nJ|dkr|d}|d kr2n,|d kr|d}n|d kr&n |dkr2n|VqWdS)NtypeStartTagEmptyTag namespacenameZhtmldataZEndTagComment CharactersSpaceCharactersZDoctypeZEntityZSerializerError)rr)rr) rr __iter__r r rappenditemspop) rZ open_elementstokenrrrvaluestartrrrrrsF     zFilter.__iter__)T)__name__ __module__ __qualname__rr __classcell__rr)rrr sr N)Z __future__rrrZsixrr rZ constantsr r r joinr rrrrs     PK!__pycache__/lint.cpython-36.pycnu[3 B;W @shddlmZmZmZddlmZddlmZddlm Z m Z ddlm Z dj e Z Gd d d ej Z d S) )absolute_importdivisionunicode_literals) text_type)base) namespaces voidElements)spaceCharacterscs&eZdZdfdd ZddZZS)FilterTcstt|j|||_dS)N)superr __init__require_matching_tags)selfsourcer) __class__/usr/lib/python3.6/lint.pyr szFilter.__init__c csRg}xFtjj|D]4}|d}|dkrP|d}|d}|dksRt|tsRt|dks^tt|tslt|dksxtt|dtst| s|tdkr|tkr|dkstn |dkst|dkr|j r|j ||fxp|dj D]`\\}}}|dkst|tst|dkstt|ts,t|dks:tt|tstqWn|d kr|d}|d}|dkst|tst|dkstt|tst|dkst| s|tdkr|tkrd s td d |in"|j rD|j }|||fksDtn6|d kr4|d}t|tsDtn|dkr|d}t|tsVt|dksdt|dkrD|j tdksDtn|dkr|d}|dkst|tst|ddkst|tst|ddksDt|tsDtnV|dkrt|dtsDtn6|dkr.t|dtsDtnd sDtdd|i|VqWdS)NtypeStartTagEmptyTag namespacenamer dataZhtmlZEndTagFz.Void element reported as EndTag token: %(tag)stagComment CharactersSpaceCharactersZDoctypeZpublicIdZsystemIdZEntityZSerializerErrorzUnknown token type: %(type)s)rr)rr)rr __iter__ isinstancerAssertionErrordictr r rappenditemspopstripr ) rZ open_elementstokenrrrvaluestartrrrrr sl             zFilter.__iter__)T)__name__ __module__ __qualname__rr __classcell__rr)rrr sr N)Z __future__rrrZsixrr rZ constantsr r r joinr rrrrs     PK!э -__pycache__/optionaltags.cpython-36.opt-1.pycnu[3 B;W&)@s6ddlmZmZmZddlmZGdddejZdS))absolute_importdivisionunicode_literals)basec@s,eZdZddZddZddZddZd S) FilterccsLd}}x*|jD] }|dk r(|||fV|}|}qW|dk rH||dfVdS)N)source)selfZ previous1Z previous2tokenr "/usr/lib/python3.6/optionaltags.pysliders  z Filter.sliderccsvxp|jD]d\}}}|d}|dkrH|ds@|j|d|| rn|Vq |dkrh|j|d|sn|Vq |Vq WdS)NtypeStartTagdatanameEndTag)r is_optional_startis_optional_end)r previousr nextrr r r __iter__szFilter.__iter__cCs|r |dpd}|dkr |dkS|dkrJ|dkr4dS|d krH|d dkSn|d krx|dkr^d S|dkrr|d dkSdSnd|dkr|dkr|d dkSd SnB|dkr|dkr|r|dd kr|d dkrd S|d dkSd Sd S)NrhtmlCommentSpaceCharactersheadrEmptyTagTrrbodyFscriptstylecolgroupcoltbodytheadtfoottr)rr)rr)rr)rr)rr)r"r#r$r )r tagnamerrrr r r rs4     zFilter.is_optional_startcCs |r |dpd}|d7kr |d8kS|d9krP|d kr<|d |kS|d kpJ|dkSn|d:kr|d krl|d d;kS|dkr|d kp|dkSdSn||dkr|dkS|d kp|dkSn|d?kr,|d kr|d d@kS|d kp(|dkSn|d0kr`|dAkrDdS|d krZ|d d0kSd1Sn|dBkr|d kr|d dCkS|d3kr|d kp|dkSdSnf|d4kr|d kr|d d3kS|d kp|dkSn2|dDkr|d kr|d dEkS|d kp|dkSdS)FNrrrrrrlioptgroupr%rrrdtddFpraddressarticleaside blockquotedatagriddialogdirdivdlfieldsetfooterformh1h2h3h4h5h6headerhrmenunavolpresectiontableuloptionrtrpr Tr#r"r$tdth)rrr)rr)r'r(r%)r)r*)r)r*)rr)r,r-r.r/r0r1r2r3r4r5r6r7r8r9r:r;r<r=r>r?r@rArBr+rCrDrErF)rGr()rHrI)rHrI)rr)r#r")r"r$)rJrK)rJrKr )r r&rrr r r rWsf                        zFilter.is_optional_endN)__name__ __module__ __qualname__r rrrr r r r rs  9rN)Z __future__rrrrrr r r r s PK!э '__pycache__/optionaltags.cpython-36.pycnu[3 B;W&)@s6ddlmZmZmZddlmZGdddejZdS))absolute_importdivisionunicode_literals)basec@s,eZdZddZddZddZddZd S) FilterccsLd}}x*|jD] }|dk r(|||fV|}|}qW|dk rH||dfVdS)N)source)selfZ previous1Z previous2tokenr "/usr/lib/python3.6/optionaltags.pysliders  z Filter.sliderccsvxp|jD]d\}}}|d}|dkrH|ds@|j|d|| rn|Vq |dkrh|j|d|sn|Vq |Vq WdS)NtypeStartTagdatanameEndTag)r is_optional_startis_optional_end)r previousr nextrr r r __iter__szFilter.__iter__cCs|r |dpd}|dkr |dkS|dkrJ|dkr4dS|d krH|d dkSn|d krx|dkr^d S|dkrr|d dkSdSnd|dkr|dkr|d dkSd SnB|dkr|dkr|r|dd kr|d dkrd S|d dkSd Sd S)NrhtmlCommentSpaceCharactersheadrEmptyTagTrrbodyFscriptstylecolgroupcoltbodytheadtfoottr)rr)rr)rr)rr)rr)r"r#r$r )r tagnamerrrr r r rs4     zFilter.is_optional_startcCs |r |dpd}|d7kr |d8kS|d9krP|d kr<|d |kS|d kpJ|dkSn|d:kr|d krl|d d;kS|dkr|d kp|dkSdSn||dkr|dkS|d kp|dkSn|d?kr,|d kr|d d@kS|d kp(|dkSn|d0kr`|dAkrDdS|d krZ|d d0kSd1Sn|dBkr|d kr|d dCkS|d3kr|d kp|dkSdSnf|d4kr|d kr|d d3kS|d kp|dkSn2|dDkr|d kr|d dEkS|d kp|dkSdS)FNrrrrrrlioptgroupr%rrrdtddFpraddressarticleaside blockquotedatagriddialogdirdivdlfieldsetfooterformh1h2h3h4h5h6headerhrmenunavolpresectiontableuloptionrtrpr Tr#r"r$tdth)rrr)rr)r'r(r%)r)r*)r)r*)rr)r,r-r.r/r0r1r2r3r4r5r6r7r8r9r:r;r<r=r>r?r@rArBr+rCrDrErF)rGr()rHrI)rHrI)rr)r#r")r"r$)rJrK)rJrKr )r r&rrr r r rWsf                        zFilter.is_optional_endN)__name__ __module__ __qualname__r rrrr r r r rs  9rN)Z __future__rrrrrr r r r s PK!AEE*__pycache__/sanitizer.cpython-36.opt-1.pycnu[3 B;W bE@s ddlmZmZmZddlZddlmZmZddlm Z ddl m Z ddl mZmZd gZeed d fed d fed d fed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed d fed d!fed d"fed d#fed d$fed d%fed d&fed d'fed d(fed d)fed d*fed d+fed d,fed d-fed d.fed d/fed d0fed d1fed d2fed d3fed d4fed d5fed d6fed d7fed d8fed d9fed d:fed d;fed dfed d?fed d@fed dAfed dBfed dCfed dDfed dEfed dFfed dGfed dHfed dIfed dJfed dKfed dLfed dMfed dNfed dOfed dPfed dQfed dRfed dSfed dTfed dUfed dVfed dWfed dXfed dYfed dZfed d[fed d\fed d]fed d^fed d_fed d`fed dafed dbfed dcfed ddfed defed dffed dgfed dhfed difed djfed dkfed dlfed dmfedndofedndpfedndqfedndrfedndsfedndtfedndufedndvfedndwfedndxfedndyfedndzfednd{fednd|fednd}fednd~fedndfedndfedndfedndfedndfedndfedndfedndfedndfedndfedndfedd feddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddffZed3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddded1dfdddddÐdĐdŐdƐdǐdȐdɐdʐdːd̐d͐dΐdϐdАdѐdҐdӐdԐdՐd֐dאdؐdِdڐdېdܐdݐdސdߐdddddddedOdfedOdPfedOd%fddddddddddddddddddddddddddddddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcedOdfedOdfedOdfedOdfedOdPfedOdfedOd%fed1dfed1dfed1dfdddedfdgfCZedhdidjdkdldmdndodpdqdredOdfed1dff Zed~ZedZedZedZedZedZedZejd1ejZGd2d d e jZdS()absolute_importdivisionunicode_literalsN)escapeunescape) urllib_parse)base) namespacesprefixesFilterhtmlaabbrZacronymZaddressZareaZarticleZasideZaudiobZbigZ blockquotebrZbuttonZcanvasZcaptioncentercitecodecolZcolgroupZcommandZdatagridZdatalistZdddelZdetailsZdfnZdialogdirZdivZdlZdtZemz event-sourceZfieldsetZ figcaptionZfigureZfooterfontformheaderZh1Zh2Zh3Zh4Zh5Zh6ZhriZimginputZinsZkeygenZkbdlabelZlegendZlimmapZmenuZmeterZmulticolZnavZnextidZoloutputZoptgroupZoptionpZpreZprogressqsZsampZsectionZselectZsmallZsoundsourceZspacerspanZstrikeZstrongsubZsuptableZtbodyZtdZtextareaZtimeZtfootZthZtheadZtrZttuZulvarZvideoZmathmlZmactionZmathZmerrorZmfracZmiZ mmultiscriptsZmnmoZmoverZmpaddedZmphantomZ mprescriptsZmrootZmrowZmspaceZmsqrtZmstyleZmsubZmsubsupZmsupZmtableZmtdZmtextZmtrZmunderZ munderovernoneZsvganimate animateColor animateMotionanimateTransformZclipPathZcircleZdefsZdescZellipsez font-facezfont-face-namez font-face-srcgZglyphZhkernlinearGradientlinemarkerZmetadataz missing-glyphZmpathpathZpolygonZpolylineradialGradientZrectsetstopZswitchtexttitleZtspanuseacceptaccept-charset accesskeyactionalignalt autocomplete autofocusaxis backgroundbalancebgcolor bgpropertiesborder bordercolorbordercolordarkbordercolorlight bottompadding cellpadding cellspacingch challengecharcharoffchoffcharsetcheckedclassclearcolorcolscolspancompactcontenteditablecontrolscoordsdatadatafld datapagesizedatasrcdatetimedefaultdelaydisabled draggabledynsrcenctypeendfaceforframe galleryimggutterheadersheight hidefocushiddenhighhrefhreflanghspaceiconid inputmodeismapkeytype leftspacinglanglistlongdescloop loopcountloopend loopstartlowlowsrcmax maxlengthmediamethodminmultiplenamenohrefnoshadenowrapopenoptimumpatternping point-sizeposterpqgpreloadprompt radiogroupreadonlyrel repeat-max repeat-minreplacerequiredrev rightspacingrowsrowspanrulesscopeselectedshapesizesrcstartstepstylesummarysuppresstabindextargettemplate toppaddingtype unselectableusemapurnvalignvaluevariablevolumevspacevrmlwidthwrapZxml actiontype columnalign columnlines columnspacing columnspandepthdisplay displaystyle equalcolumns equalrowsfence fontstyle fontweight linethicknesslspacemathbackground mathcolor mathvariantmaxsizeminsizeotherrowalignrowlines rowspacingrspace scriptlevel selection separatorstretchyxlinkZshow accent-height accumulateadditive alphabetic arabic-formascent attributeName attributeType baseProfilebboxbeginbycalcMode cap-height clip-pathcolor-renderingcontentcxcyddxdydescentdurfill fill-opacity fill-rule font-family font-size font-stretch font-style font-variant font-weightfromfxfyg1g2 glyph-name gradientUnitshanging horiz-adv-xhoriz-origin-x ideographick keyPoints keySplineskeyTimes marker-end marker-mid marker-start markerHeight markerUnits markerWidth mathematicaloffsetopacityorientoriginoverline-positionoverline-thicknesspanose-1 pathLengthpointspreserveAspectRatiorrefXrefY repeatCount repeatDurrequiredExtensionsrequiredFeaturesrestartrotaterxryslopestemhstemv stop-color stop-opacitystrikethrough-positionstrikethrough-thicknessstrokestroke-dasharraystroke-dashoffsetstroke-linecapstroke-linejoinstroke-miterlimitstroke-opacity stroke-widthsystemLanguage text-anchorto transformu1u2underline-positionunderline-thicknessunicode unicode-range units-per-emvaluesversionviewBox visibilitywidthsxx-heightx1x2ZactuateZarcroleZroler Zspaceyy1y2 zoomAndPan color-profilecursorfiltermaskaltGlyphfeImagetextpathtrefazimuthbackground-colorborder-bottom-colorborder-collapse border-colorborder-left-colorborder-right-colorborder-top-color direction elevationfloatletter-spacing line-heightoverflowpause pause-after pause-beforepitch pitch-rangerichnessspeak speak-header speak-numeralspeak-punctuation speech-ratestress text-aligntext-decoration text-indent unicode-bidivertical-align voice-family white-spaceautoaquablackblockblueboldbothbottombrowncollapsedasheddottedfuchsiagraygreen !importantitalicleftlimemaroonmediumnavynormalolivepointerpurpleredrightsolidsilvertealtop transparent underlinewhiteyellowed2kftphttphttpsircmailtonewsgophernntptelnetwebcalxmppcalltofeedaimrsynctagsshsftprtspafs image/png image/jpeg image/gif image/webp image/bmp text/plainaL ^ # Match a content type / (?P[-a-zA-Z0-9.]+/[-a-zA-Z0-9.]+) # Match any character set and encoding (?:(?:;charset=(?:[-a-zA-Z0-9]+)(?:;(?:base64))?) |(?:;(?:base64))?(?:;charset=(?:[-a-zA-Z0-9]+))?) # Assume the rest is data ,.* $ c s^eZdZdZeeeeee e e e e f fdd ZddZddZdd Zd d Zd d ZZS)r zA sanitization of XHTML+MathML+SVG and of inline style attributes.c sPtt|j|||_||_||_||_||_||_||_ | |_ | |_ | |_ dS)N) superr __init__allowed_elementsallowed_attributesallowed_css_propertiesallowed_css_keywordsallowed_svg_propertiesallowed_protocolsallowed_content_typesattr_val_is_urisvg_attr_val_allows_refsvg_allow_local_href) selfr%rrrrrrrrrr) __class__/usr/lib/python3.6/sanitizer.pyrs zFilter.__init__ccs.x(tjj|D]}|j|}|r|VqWdS)N)r r __iter__sanitize_token)rtokenrrrrs zFilter.__iter__cCsp|d}|d kr^|d}|d}||f|jksH|dkrRtd|f|jkrR|j|S|j|Sn|dkrhn|SdS) NrStartTagEndTagEmptyTagr namespacerComment)rrr)rr allowed_tokendisallowed_token)rr token_typerrrrrrs  zFilter.sanitize_tokenc Csd|kr|d}t|j}x&||jD]}|d|=|j|q*Wx||j@D]}tjddt||j}|j dd}yt j |}Wnt k rd}||=YnX|o|j rR|j |j kr||=|j dkrRtj|j}|s||=qR|jd|jkrR||=qRWx4|jD]*}||kr tjddt||||<q W|d|jkrtd d f|krtjd |td d fr|td d f=d |kr|j|d|d<||d<|S)Nr`u [`- - \s]+u�Z content_typezurl\s*\(\s*[^#\s][^)]+?\) rrrvz ^\s*[^#\s].*r)Nr)Nr)Nr)r7keysrremoverrer'rlowerrurlparse ValueErrorschemerdata_content_typematchr5grouprrrr search sanitize_css) rrattrsZ attr_namesZ to_removeattrZ val_unescapedZurirrrrrsJ             zFilter.allowed_tokencCs|d}|dkr"d|d|d<n|drg}xJ|djD]:\\}}}|jd|dkrZ|ndt||ft|fqrr`z %s="%s"z%s:%sz<%s%s>rz<%s>Z selfClosingrz/>Z Characters)itemsappendr rjoinget)rrrrnsrvrrrr2s2 zFilter.disallowed_tokencCstjdjd|}tjd|s"dStjd|s2dSg}xtjd|D]\}}|sRqD|j|jkrx|j|d|dqD|jd d jdkrxf|jD]}||j krtjd| rPqW|j|d|dqD|j|j krD|j|d|dqDWdj |S)Nzurl\s*\(\s*[^\s)]+?\s*\)\s*rz@^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$rz ^\s*([-\w]+\s*:[^:;]*(;\s*|$))*$z([-\w]+)\s*:\s*([^:;]*)z: ;-rrErImarginpaddingz\^(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$)rErIrr) rcompiler'rfindallrrrsplitrrr)rrZcleanZproprkeywordrrrrFs*   zFilter.sanitize_css)__name__ __module__ __qualname____doc__rrrrrrrrrrrrrrrr __classcell__rr)rrr s  2)Nr)Nr<)Nr=)Nr>)Nr?)Nr@)NrA)NrB)NrC)NrD)NrE)NrF)NrG)NrH)NrI)NrJ)NrK)NrL)NrM)NrN)NrO)NrP)NrQ)NrR)NrS)NrT)NrU)NrV)Nr)NrW)NrX)NrY)NrZ)Nr[)Nr\)Nr])Nr^)Nr_)Nr`)Nra)Nrb)Nrc)Nrd)Nre)Nrf)Nr)Nrg)Nrh)Nri)Nrj)Nrk)Nrl)Nrm)Nr)Nrn)Nro)Nrp)Nrq)Nrr)Nrs)Nrt)Nru)Nrv)Nrw)Nrx)Nry)Nrz)Nr{)Nr|)Nr})Nr)Nr~)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr&)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr:)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr@)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nrn)Nrr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)NrW)Nr)NrY)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nrk)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nrr)Nr)Nr )Nrz)Nr )Nr )Nr )Nr )Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr5)Nr)Nr)Nr)Nr )Nr!)Nr")Nr#)Nr$)Nr%)Nr&)Nr')Nr()Nr))Nr*)Nr+)Nr,)Nr-)Nr.)Nr/)Nr0)Nr1)Nr2)Nr3)Nr4)Nr5)Nr6)Nr7)Nr8)Nr9)Nr:)Nr)Nr;)Nr<)Nr=)Nr)Nr>)Nr?)Nr@)NrA)NrB)NrC)NrD)NrE)NrF)NrG)NrH)Nr)NrI)NrJ)NrK)NrL)NrM)NrN)NrO)NrP)NrQ)Nrv)Nr)Nr)Nr?)Nr)Nr)NrE)Nrc)Nri)Nr)NrNrNrRNrSNrNrTNr4NrNrNrNrUNr2) rrrrrrrrrrrNrVNr-Nr.Nr/Nr0NrSNrWNrTNr2NrNr6NrXNrYNr7Nr;)rrrrrr r r r r rrrrr).rZr[r\r]r^r_r`rarXrYrSrbrrcrdrrrrrrrrrerfrgrhrirjrkrlrmrnrorprqrrrsrtrurvrwrxryrrzr)'r{r|r}r~rrrrrrrrrrrrrrrrrrr,rrrrrrrrrrrrrrrr)rrrr2r9r5r6r8)rrrrrrrrrrrrrrrrrrrrrrr`)rrrrrr) Z __future__rrrrZxml.sax.saxutilsrrZ six.movesrrrr Z constantsr r __all__ frozensetrrrrrrrrrrrVERBOSErr rrrrs2                                                                                                                                                                          PK!0FF$__pycache__/sanitizer.cpython-36.pycnu[3 B;W bE@s ddlmZmZmZddlZddlmZmZddlm Z ddl m Z ddl mZmZd gZeed d fed d fed d fed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed dfed d fed d!fed d"fed d#fed d$fed d%fed d&fed d'fed d(fed d)fed d*fed d+fed d,fed d-fed d.fed d/fed d0fed d1fed d2fed d3fed d4fed d5fed d6fed d7fed d8fed d9fed d:fed d;fed dfed d?fed d@fed dAfed dBfed dCfed dDfed dEfed dFfed dGfed dHfed dIfed dJfed dKfed dLfed dMfed dNfed dOfed dPfed dQfed dRfed dSfed dTfed dUfed dVfed dWfed dXfed dYfed dZfed d[fed d\fed d]fed d^fed d_fed d`fed dafed dbfed dcfed ddfed defed dffed dgfed dhfed difed djfed dkfed dlfed dmfedndofedndpfedndqfedndrfedndsfedndtfedndufedndvfedndwfedndxfedndyfedndzfednd{fednd|fednd}fednd~fedndfedndfedndfedndfedndfedndfedndfedndfedndfedndfedndfedd feddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddffZed3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddded1dfdddddÐdĐdŐdƐdǐdȐdɐdʐdːd̐d͐dΐdϐdАdѐdҐdӐdԐdՐd֐dאdؐdِdڐdېdܐdݐdސdߐdddddddedOdfedOdPfedOd%fddddddddddddddddddddddddddddddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcedOdfedOdfedOdfedOdfedOdPfedOdfedOd%fed1dfed1dfed1dfdddedfdgfCZedhdidjdkdldmdndodpdqdredOdfed1dff Zed~ZedZedZedZedZedZedZejd1ejZGd2d d e jZdS()absolute_importdivisionunicode_literalsN)escapeunescape) urllib_parse)base) namespacesprefixesFilterhtmlaabbrZacronymZaddressZareaZarticleZasideZaudiobZbigZ blockquotebrZbuttonZcanvasZcaptioncentercitecodecolZcolgroupZcommandZdatagridZdatalistZdddelZdetailsZdfnZdialogdirZdivZdlZdtZemz event-sourceZfieldsetZ figcaptionZfigureZfooterfontformheaderZh1Zh2Zh3Zh4Zh5Zh6ZhriZimginputZinsZkeygenZkbdlabelZlegendZlimmapZmenuZmeterZmulticolZnavZnextidZoloutputZoptgroupZoptionpZpreZprogressqsZsampZsectionZselectZsmallZsoundsourceZspacerspanZstrikeZstrongsubZsuptableZtbodyZtdZtextareaZtimeZtfootZthZtheadZtrZttuZulvarZvideoZmathmlZmactionZmathZmerrorZmfracZmiZ mmultiscriptsZmnmoZmoverZmpaddedZmphantomZ mprescriptsZmrootZmrowZmspaceZmsqrtZmstyleZmsubZmsubsupZmsupZmtableZmtdZmtextZmtrZmunderZ munderovernoneZsvganimate animateColor animateMotionanimateTransformZclipPathZcircleZdefsZdescZellipsez font-facezfont-face-namez font-face-srcgZglyphZhkernlinearGradientlinemarkerZmetadataz missing-glyphZmpathpathZpolygonZpolylineradialGradientZrectsetstopZswitchtexttitleZtspanuseacceptaccept-charset accesskeyactionalignalt autocomplete autofocusaxis backgroundbalancebgcolor bgpropertiesborder bordercolorbordercolordarkbordercolorlight bottompadding cellpadding cellspacingch challengecharcharoffchoffcharsetcheckedclassclearcolorcolscolspancompactcontenteditablecontrolscoordsdatadatafld datapagesizedatasrcdatetimedefaultdelaydisabled draggabledynsrcenctypeendfaceforframe galleryimggutterheadersheight hidefocushiddenhighhrefhreflanghspaceiconid inputmodeismapkeytype leftspacinglanglistlongdescloop loopcountloopend loopstartlowlowsrcmax maxlengthmediamethodminmultiplenamenohrefnoshadenowrapopenoptimumpatternping point-sizeposterpqgpreloadprompt radiogroupreadonlyrel repeat-max repeat-minreplacerequiredrev rightspacingrowsrowspanrulesscopeselectedshapesizesrcstartstepstylesummarysuppresstabindextargettemplate toppaddingtype unselectableusemapurnvalignvaluevariablevolumevspacevrmlwidthwrapZxml actiontype columnalign columnlines columnspacing columnspandepthdisplay displaystyle equalcolumns equalrowsfence fontstyle fontweight linethicknesslspacemathbackground mathcolor mathvariantmaxsizeminsizeotherrowalignrowlines rowspacingrspace scriptlevel selection separatorstretchyxlinkZshow accent-height accumulateadditive alphabetic arabic-formascent attributeName attributeType baseProfilebboxbeginbycalcMode cap-height clip-pathcolor-renderingcontentcxcyddxdydescentdurfill fill-opacity fill-rule font-family font-size font-stretch font-style font-variant font-weightfromfxfyg1g2 glyph-name gradientUnitshanging horiz-adv-xhoriz-origin-x ideographick keyPoints keySplineskeyTimes marker-end marker-mid marker-start markerHeight markerUnits markerWidth mathematicaloffsetopacityorientoriginoverline-positionoverline-thicknesspanose-1 pathLengthpointspreserveAspectRatiorrefXrefY repeatCount repeatDurrequiredExtensionsrequiredFeaturesrestartrotaterxryslopestemhstemv stop-color stop-opacitystrikethrough-positionstrikethrough-thicknessstrokestroke-dasharraystroke-dashoffsetstroke-linecapstroke-linejoinstroke-miterlimitstroke-opacity stroke-widthsystemLanguage text-anchorto transformu1u2underline-positionunderline-thicknessunicode unicode-range units-per-emvaluesversionviewBox visibilitywidthsxx-heightx1x2ZactuateZarcroleZroler Zspaceyy1y2 zoomAndPan color-profilecursorfiltermaskaltGlyphfeImagetextpathtrefazimuthbackground-colorborder-bottom-colorborder-collapse border-colorborder-left-colorborder-right-colorborder-top-color direction elevationfloatletter-spacing line-heightoverflowpause pause-after pause-beforepitch pitch-rangerichnessspeak speak-header speak-numeralspeak-punctuation speech-ratestress text-aligntext-decoration text-indent unicode-bidivertical-align voice-family white-spaceautoaquablackblockblueboldbothbottombrowncollapsedasheddottedfuchsiagraygreen !importantitalicleftlimemaroonmediumnavynormalolivepointerpurpleredrightsolidsilvertealtop transparent underlinewhiteyellowed2kftphttphttpsircmailtonewsgophernntptelnetwebcalxmppcalltofeedaimrsynctagsshsftprtspafs image/png image/jpeg image/gif image/webp image/bmp text/plainaL ^ # Match a content type / (?P[-a-zA-Z0-9.]+/[-a-zA-Z0-9.]+) # Match any character set and encoding (?:(?:;charset=(?:[-a-zA-Z0-9]+)(?:;(?:base64))?) |(?:;(?:base64))?(?:;charset=(?:[-a-zA-Z0-9]+))?) # Assume the rest is data ,.* $ c s^eZdZdZeeeeee e e e e f fdd ZddZddZdd Zd d Zd d ZZS)r zA sanitization of XHTML+MathML+SVG and of inline style attributes.c sPtt|j|||_||_||_||_||_||_||_ | |_ | |_ | |_ dS)N) superr __init__allowed_elementsallowed_attributesallowed_css_propertiesallowed_css_keywordsallowed_svg_propertiesallowed_protocolsallowed_content_typesattr_val_is_urisvg_attr_val_allows_refsvg_allow_local_href) selfr%rrrrrrrrrr) __class__/usr/lib/python3.6/sanitizer.pyrs zFilter.__init__ccs.x(tjj|D]}|j|}|r|VqWdS)N)r r __iter__sanitize_token)rtokenrrrrs zFilter.__iter__cCsp|d}|d kr^|d}|d}||f|jksH|dkrRtd|f|jkrR|j|S|j|Sn|dkrhn|SdS) NrStartTagEndTagEmptyTagr namespacerComment)rrr)rr allowed_tokendisallowed_token)rr token_typerrrrrrs  zFilter.sanitize_tokenc Csd|kr|d}t|j}x&||jD]}|d|=|j|q*Wx||j@D]}||ksbttjddt||j }|j dd}yt j |}Wnt k rd}||=YnX|o|j rR|j |jkr||=|j dkrRtj|j}|s||=qR|jd|jkrR||=qRWx4|jD]*}||krtjddt||||<qW|d|jkrtd d f|krtjd |td d fr|td d f=d |kr|j|d|d<||d<|S)Nr`u [`- - \s]+u�Z content_typezurl\s*\(\s*[^#\s][^)]+?\) rrrvz ^\s*[^#\s].*r)Nr)Nr)Nr)r7keysrremoverAssertionErrorrer'rlowerrurlparse ValueErrorschemerdata_content_typematchr5grouprrrr search sanitize_css) rrattrsZ attr_namesZ to_removeattrZ val_unescapedZurirrrrrsL              zFilter.allowed_tokencCs|d}|dkr"d|d|d<n|dr|dks6tg}xJ|djD]:\\}}}|jd|dkrf|nd t||ft|fqHWd |dd j|f|d<nd |d|d<|jd r|dddd|d<d|d<|d=|S)Nrrzrr`rrz %s="%s"z%s:%sz<%s%s>rz<%s>Z selfClosingrz/>Z Characters)rr)ritemsappendr rjoinget)rrrrnsrvrrrr2s 2 zFilter.disallowed_tokencCstjdjd|}tjd|s"dStjd|s2dSg}xtjd|D]\}}|sRqD|j|jkrx|j|d|dqD|jd d jdkrxf|jD]}||j krtjd| rPqW|j|d|dqD|j|j krD|j|d|dqDWdj |S)Nzurl\s*\(\s*[^\s)]+?\s*\)\s*rz@^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$rz ^\s*([-\w]+\s*:[^:;]*(;\s*|$))*$z([-\w]+)\s*:\s*([^:;]*)z: ;-rrErImarginpaddingz\^(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$)rErIrr) rcompiler'rfindallrrrsplitrrr)rrZcleanZproprkeywordrrrrFs*   zFilter.sanitize_css)__name__ __module__ __qualname____doc__rrrrrrrrrrrrrrrr __classcell__rr)rrr s  2)Nr)Nr<)Nr=)Nr>)Nr?)Nr@)NrA)NrB)NrC)NrD)NrE)NrF)NrG)NrH)NrI)NrJ)NrK)NrL)NrM)NrN)NrO)NrP)NrQ)NrR)NrS)NrT)NrU)NrV)Nr)NrW)NrX)NrY)NrZ)Nr[)Nr\)Nr])Nr^)Nr_)Nr`)Nra)Nrb)Nrc)Nrd)Nre)Nrf)Nr)Nrg)Nrh)Nri)Nrj)Nrk)Nrl)Nrm)Nr)Nrn)Nro)Nrp)Nrq)Nrr)Nrs)Nrt)Nru)Nrv)Nrw)Nrx)Nry)Nrz)Nr{)Nr|)Nr})Nr)Nr~)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr&)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr:)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr@)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nrn)Nrr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)NrW)Nr)NrY)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nrk)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nrr)Nr)Nr )Nrz)Nr )Nr )Nr )Nr )Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr)Nr5)Nr)Nr)Nr)Nr )Nr!)Nr")Nr#)Nr$)Nr%)Nr&)Nr')Nr()Nr))Nr*)Nr+)Nr,)Nr-)Nr.)Nr/)Nr0)Nr1)Nr2)Nr3)Nr4)Nr5)Nr6)Nr7)Nr8)Nr9)Nr:)Nr)Nr;)Nr<)Nr=)Nr)Nr>)Nr?)Nr@)NrA)NrB)NrC)NrD)NrE)NrF)NrG)NrH)Nr)NrI)NrJ)NrK)NrL)NrM)NrN)NrO)NrP)NrQ)Nrv)Nr)Nr)Nr?)Nr)Nr)NrE)Nrc)Nri)Nr)NrNrNrRNrSNrNrTNr4NrNrNrNrUNr2) rrrrrrrrrrrNrVNr-Nr.Nr/Nr0NrSNrWNrTNr2NrNr6NrXNrYNr7Nr;)rrrrr r r r r rrrrrr).rZr[r\r]r^r_r`rarXrYrSrbrrcrdrrrrrrrrrerfrgrhrirjrkrlrmrnrorprqrrrsrtrurvrwrxryrrzr)'r{r|r}r~rrrrrrrrrrrrrrrrrrr,rrrrrrrrrrrrrrrr)rrrr2r9r5r6r8)rrrrrrrrrrrrrrrrrrrrrrr`)rrrrrr) Z __future__rrrrZxml.sax.saxutilsrrZ six.movesrrrr Z constantsr r __all__ frozensetrrrrrrrrrrrVERBOSErr rrrrs2                                                                                                                                                                          PK!Y+__pycache__/whitespace.cpython-36.opt-1.pycnu[3 B;Ws@snddlmZmZmZddlZddlmZddlmZm Z dj e Z ej de Z Gd d d ej Z d d ZdS) )absolute_importdivisionunicode_literalsN)base)rcdataElementsspaceCharactersz[%s]+c@s(eZdZeddgeeZddZdS)FilterZpreZtextareaccsd}xtjj|D]}|d}|dkrB|s8|d|jkrB|d7}nT|dkrX|rX|d8}n>| rx|dkrx|drxd |d<n| r|d krt|d|d<|VqWdS) NrtypeZStartTagnamerZEndTagZSpaceCharactersdata Z Characters)rr __iter__spacePreserveElementscollapse_spaces)selfZpreservetokenr r /usr/lib/python3.6/whitespace.pyrs    zFilter.__iter__N)__name__ __module__ __qualname__ frozensetlistrrrrrrrr sr cCs tjd|S)Nr) SPACES_REGEXsub)textrrrr%sr)Z __future__rrrrer rZ constantsrr joincompilerr rrrrrs  PK!Y%__pycache__/whitespace.cpython-36.pycnu[3 B;Ws@snddlmZmZmZddlZddlmZddlmZm Z dj e Z ej de Z Gd d d ej Z d d ZdS) )absolute_importdivisionunicode_literalsN)base)rcdataElementsspaceCharactersz[%s]+c@s(eZdZeddgeeZddZdS)FilterZpreZtextareaccsd}xtjj|D]}|d}|dkrB|s8|d|jkrB|d7}nT|dkrX|rX|d8}n>| rx|dkrx|drxd |d<n| r|d krt|d|d<|VqWdS) NrtypeZStartTagnamerZEndTagZSpaceCharactersdata Z Characters)rr __iter__spacePreserveElementscollapse_spaces)selfZpreservetokenr r /usr/lib/python3.6/whitespace.pyrs    zFilter.__iter__N)__name__ __module__ __qualname__ frozensetlistrrrrrrrr sr cCs tjd|S)Nr) SPACES_REGEXsub)textrrrr%sr)Z __future__rrrrer rZ constantsrr joincompilerr rrrrrs  PK! __init__.pynu[PK!n|mmalphabeticalattributes.pynu[from __future__ import absolute_import, division, unicode_literals from . import base try: from collections import OrderedDict except ImportError: from ordereddict import OrderedDict class Filter(base.Filter): def __iter__(self): for token in base.Filter.__iter__(self): if token["type"] in ("StartTag", "EmptyTag"): attrs = OrderedDict() for name, value in sorted(token["data"].items(), key=lambda x: x[0]): attrs[name] = value token["data"] = attrs yield token PK!"base.pynu[from __future__ import absolute_import, division, unicode_literals class Filter(object): def __init__(self, source): self.source = source def __iter__(self): return iter(self.source) def __getattr__(self, name): return getattr(self.source, name) PK!!< inject_meta_charset.pynu[from __future__ import absolute_import, division, unicode_literals from . import base class Filter(base.Filter): def __init__(self, source, encoding): base.Filter.__init__(self, source) self.encoding = encoding def __iter__(self): state = "pre_head" meta_found = (self.encoding is None) pending = [] for token in base.Filter.__iter__(self): type = token["type"] if type == "StartTag": if token["name"].lower() == "head": state = "in_head" elif type == "EmptyTag": if token["name"].lower() == "meta": # replace charset with actual encoding has_http_equiv_content_type = False for (namespace, name), value in token["data"].items(): if namespace is not None: continue elif name.lower() == 'charset': token["data"][(namespace, name)] = self.encoding meta_found = True break elif name == 'http-equiv' and value.lower() == 'content-type': has_http_equiv_content_type = True else: if has_http_equiv_content_type and (None, "content") in token["data"]: token["data"][(None, "content")] = 'text/html; charset=%s' % self.encoding meta_found = True elif token["name"].lower() == "head" and not meta_found: # insert meta into empty head yield {"type": "StartTag", "name": "head", "data": token["data"]} yield {"type": "EmptyTag", "name": "meta", "data": {(None, "charset"): self.encoding}} yield {"type": "EndTag", "name": "head"} meta_found = True continue elif type == "EndTag": if token["name"].lower() == "head" and pending: # insert meta into head (if necessary) and flush pending queue yield pending.pop(0) if not meta_found: yield {"type": "EmptyTag", "name": "meta", "data": {(None, "charset"): self.encoding}} while pending: yield pending.pop(0) meta_found = True state = "post_head" if state == "in_head": pending.append(token) else: yield token PK!F  lint.pynu[from __future__ import absolute_import, division, unicode_literals from six import text_type from . import base from ..constants import namespaces, voidElements from ..constants import spaceCharacters spaceCharacters = "".join(spaceCharacters) class Filter(base.Filter): def __init__(self, source, require_matching_tags=True): super(Filter, self).__init__(source) self.require_matching_tags = require_matching_tags def __iter__(self): open_elements = [] for token in base.Filter.__iter__(self): type = token["type"] if type in ("StartTag", "EmptyTag"): namespace = token["namespace"] name = token["name"] assert namespace is None or isinstance(namespace, text_type) assert namespace != "" assert isinstance(name, text_type) assert name != "" assert isinstance(token["data"], dict) if (not namespace or namespace == namespaces["html"]) and name in voidElements: assert type == "EmptyTag" else: assert type == "StartTag" if type == "StartTag" and self.require_matching_tags: open_elements.append((namespace, name)) for (namespace, name), value in token["data"].items(): assert namespace is None or isinstance(namespace, text_type) assert namespace != "" assert isinstance(name, text_type) assert name != "" assert isinstance(value, text_type) elif type == "EndTag": namespace = token["namespace"] name = token["name"] assert namespace is None or isinstance(namespace, text_type) assert namespace != "" assert isinstance(name, text_type) assert name != "" if (not namespace or namespace == namespaces["html"]) and name in voidElements: assert False, "Void element reported as EndTag token: %(tag)s" % {"tag": name} elif self.require_matching_tags: start = open_elements.pop() assert start == (namespace, name) elif type == "Comment": data = token["data"] assert isinstance(data, text_type) elif type in ("Characters", "SpaceCharacters"): data = token["data"] assert isinstance(data, text_type) assert data != "" if type == "SpaceCharacters": assert data.strip(spaceCharacters) == "" elif type == "Doctype": name = token["name"] assert name is None or isinstance(name, text_type) assert token["publicId"] is None or isinstance(name, text_type) assert token["systemId"] is None or isinstance(name, text_type) elif type == "Entity": assert isinstance(token["name"], text_type) elif type == "SerializerError": assert isinstance(token["data"], text_type) else: assert False, "Unknown token type: %(type)s" % {"type": type} yield token PK!!$&)&)optionaltags.pynu[from __future__ import absolute_import, division, unicode_literals from . import base class Filter(base.Filter): def slider(self): previous1 = previous2 = None for token in self.source: if previous1 is not None: yield previous2, previous1, token previous2 = previous1 previous1 = token if previous1 is not None: yield previous2, previous1, None def __iter__(self): for previous, token, next in self.slider(): type = token["type"] if type == "StartTag": if (token["data"] or not self.is_optional_start(token["name"], previous, next)): yield token elif type == "EndTag": if not self.is_optional_end(token["name"], next): yield token else: yield token def is_optional_start(self, tagname, previous, next): type = next and next["type"] or None if tagname in 'html': # An html element's start tag may be omitted if the first thing # inside the html element is not a space character or a comment. return type not in ("Comment", "SpaceCharacters") elif tagname == 'head': # A head element's start tag may be omitted if the first thing # inside the head element is an element. # XXX: we also omit the start tag if the head element is empty if type in ("StartTag", "EmptyTag"): return True elif type == "EndTag": return next["name"] == "head" elif tagname == 'body': # A body element's start tag may be omitted if the first thing # inside the body element is not a space character or a comment, # except if the first thing inside the body element is a script # or style element and the node immediately preceding the body # element is a head element whose end tag has been omitted. if type in ("Comment", "SpaceCharacters"): return False elif type == "StartTag": # XXX: we do not look at the preceding event, so we never omit # the body element's start tag if it's followed by a script or # a style element. return next["name"] not in ('script', 'style') else: return True elif tagname == 'colgroup': # A colgroup element's start tag may be omitted if the first thing # inside the colgroup element is a col element, and if the element # is not immediately preceded by another colgroup element whose # end tag has been omitted. if type in ("StartTag", "EmptyTag"): # XXX: we do not look at the preceding event, so instead we never # omit the colgroup element's end tag when it is immediately # followed by another colgroup element. See is_optional_end. return next["name"] == "col" else: return False elif tagname == 'tbody': # A tbody element's start tag may be omitted if the first thing # inside the tbody element is a tr element, and if the element is # not immediately preceded by a tbody, thead, or tfoot element # whose end tag has been omitted. if type == "StartTag": # omit the thead and tfoot elements' end tag when they are # immediately followed by a tbody element. See is_optional_end. if previous and previous['type'] == 'EndTag' and \ previous['name'] in ('tbody', 'thead', 'tfoot'): return False return next["name"] == 'tr' else: return False return False def is_optional_end(self, tagname, next): type = next and next["type"] or None if tagname in ('html', 'head', 'body'): # An html element's end tag may be omitted if the html element # is not immediately followed by a space character or a comment. return type not in ("Comment", "SpaceCharacters") elif tagname in ('li', 'optgroup', 'tr'): # A li element's end tag may be omitted if the li element is # immediately followed by another li element or if there is # no more content in the parent element. # An optgroup element's end tag may be omitted if the optgroup # element is immediately followed by another optgroup element, # or if there is no more content in the parent element. # A tr element's end tag may be omitted if the tr element is # immediately followed by another tr element, or if there is # no more content in the parent element. if type == "StartTag": return next["name"] == tagname else: return type == "EndTag" or type is None elif tagname in ('dt', 'dd'): # A dt element's end tag may be omitted if the dt element is # immediately followed by another dt element or a dd element. # A dd element's end tag may be omitted if the dd element is # immediately followed by another dd element or a dt element, # or if there is no more content in the parent element. if type == "StartTag": return next["name"] in ('dt', 'dd') elif tagname == 'dd': return type == "EndTag" or type is None else: return False elif tagname == 'p': # A p element's end tag may be omitted if the p element is # immediately followed by an address, article, aside, # blockquote, datagrid, dialog, dir, div, dl, fieldset, # footer, form, h1, h2, h3, h4, h5, h6, header, hr, menu, # nav, ol, p, pre, section, table, or ul, element, or if # there is no more content in the parent element. if type in ("StartTag", "EmptyTag"): return next["name"] in ('address', 'article', 'aside', 'blockquote', 'datagrid', 'dialog', 'dir', 'div', 'dl', 'fieldset', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul') else: return type == "EndTag" or type is None elif tagname == 'option': # An option element's end tag may be omitted if the option # element is immediately followed by another option element, # or if it is immediately followed by an optgroup # element, or if there is no more content in the parent # element. if type == "StartTag": return next["name"] in ('option', 'optgroup') else: return type == "EndTag" or type is None elif tagname in ('rt', 'rp'): # An rt element's end tag may be omitted if the rt element is # immediately followed by an rt or rp element, or if there is # no more content in the parent element. # An rp element's end tag may be omitted if the rp element is # immediately followed by an rt or rp element, or if there is # no more content in the parent element. if type == "StartTag": return next["name"] in ('rt', 'rp') else: return type == "EndTag" or type is None elif tagname == 'colgroup': # A colgroup element's end tag may be omitted if the colgroup # element is not immediately followed by a space character or # a comment. if type in ("Comment", "SpaceCharacters"): return False elif type == "StartTag": # XXX: we also look for an immediately following colgroup # element. See is_optional_start. return next["name"] != 'colgroup' else: return True elif tagname in ('thead', 'tbody'): # A thead element's end tag may be omitted if the thead element # is immediately followed by a tbody or tfoot element. # A tbody element's end tag may be omitted if the tbody element # is immediately followed by a tbody or tfoot element, or if # there is no more content in the parent element. # A tfoot element's end tag may be omitted if the tfoot element # is immediately followed by a tbody element, or if there is no # more content in the parent element. # XXX: we never omit the end tag when the following element is # a tbody. See is_optional_start. if type == "StartTag": return next["name"] in ['tbody', 'tfoot'] elif tagname == 'tbody': return type == "EndTag" or type is None else: return False elif tagname == 'tfoot': # A tfoot element's end tag may be omitted if the tfoot element # is immediately followed by a tbody element, or if there is no # more content in the parent element. # XXX: we never omit the end tag when the following element is # a tbody. See is_optional_start. if type == "StartTag": return next["name"] == 'tbody' else: return type == "EndTag" or type is None elif tagname in ('td', 'th'): # A td element's end tag may be omitted if the td element is # immediately followed by a td or th element, or if there is # no more content in the parent element. # A th element's end tag may be omitted if the th element is # immediately followed by a td or th element, or if there is # no more content in the parent element. if type == "StartTag": return next["name"] in ('td', 'th') else: return type == "EndTag" or type is None return False PK!# b b sanitizer.pynu[from __future__ import absolute_import, division, unicode_literals import re from xml.sax.saxutils import escape, unescape from six.moves import urllib_parse as urlparse from . import base from ..constants import namespaces, prefixes __all__ = ["Filter"] allowed_elements = frozenset(( (namespaces['html'], 'a'), (namespaces['html'], 'abbr'), (namespaces['html'], 'acronym'), (namespaces['html'], 'address'), (namespaces['html'], 'area'), (namespaces['html'], 'article'), (namespaces['html'], 'aside'), (namespaces['html'], 'audio'), (namespaces['html'], 'b'), (namespaces['html'], 'big'), (namespaces['html'], 'blockquote'), (namespaces['html'], 'br'), (namespaces['html'], 'button'), (namespaces['html'], 'canvas'), (namespaces['html'], 'caption'), (namespaces['html'], 'center'), (namespaces['html'], 'cite'), (namespaces['html'], 'code'), (namespaces['html'], 'col'), (namespaces['html'], 'colgroup'), (namespaces['html'], 'command'), (namespaces['html'], 'datagrid'), (namespaces['html'], 'datalist'), (namespaces['html'], 'dd'), (namespaces['html'], 'del'), (namespaces['html'], 'details'), (namespaces['html'], 'dfn'), (namespaces['html'], 'dialog'), (namespaces['html'], 'dir'), (namespaces['html'], 'div'), (namespaces['html'], 'dl'), (namespaces['html'], 'dt'), (namespaces['html'], 'em'), (namespaces['html'], 'event-source'), (namespaces['html'], 'fieldset'), (namespaces['html'], 'figcaption'), (namespaces['html'], 'figure'), (namespaces['html'], 'footer'), (namespaces['html'], 'font'), (namespaces['html'], 'form'), (namespaces['html'], 'header'), (namespaces['html'], 'h1'), (namespaces['html'], 'h2'), (namespaces['html'], 'h3'), (namespaces['html'], 'h4'), (namespaces['html'], 'h5'), (namespaces['html'], 'h6'), (namespaces['html'], 'hr'), (namespaces['html'], 'i'), (namespaces['html'], 'img'), (namespaces['html'], 'input'), (namespaces['html'], 'ins'), (namespaces['html'], 'keygen'), (namespaces['html'], 'kbd'), (namespaces['html'], 'label'), (namespaces['html'], 'legend'), (namespaces['html'], 'li'), (namespaces['html'], 'm'), (namespaces['html'], 'map'), (namespaces['html'], 'menu'), (namespaces['html'], 'meter'), (namespaces['html'], 'multicol'), (namespaces['html'], 'nav'), (namespaces['html'], 'nextid'), (namespaces['html'], 'ol'), (namespaces['html'], 'output'), (namespaces['html'], 'optgroup'), (namespaces['html'], 'option'), (namespaces['html'], 'p'), (namespaces['html'], 'pre'), (namespaces['html'], 'progress'), (namespaces['html'], 'q'), (namespaces['html'], 's'), (namespaces['html'], 'samp'), (namespaces['html'], 'section'), (namespaces['html'], 'select'), (namespaces['html'], 'small'), (namespaces['html'], 'sound'), (namespaces['html'], 'source'), (namespaces['html'], 'spacer'), (namespaces['html'], 'span'), (namespaces['html'], 'strike'), (namespaces['html'], 'strong'), (namespaces['html'], 'sub'), (namespaces['html'], 'sup'), (namespaces['html'], 'table'), (namespaces['html'], 'tbody'), (namespaces['html'], 'td'), (namespaces['html'], 'textarea'), (namespaces['html'], 'time'), (namespaces['html'], 'tfoot'), (namespaces['html'], 'th'), (namespaces['html'], 'thead'), (namespaces['html'], 'tr'), (namespaces['html'], 'tt'), (namespaces['html'], 'u'), (namespaces['html'], 'ul'), (namespaces['html'], 'var'), (namespaces['html'], 'video'), (namespaces['mathml'], 'maction'), (namespaces['mathml'], 'math'), (namespaces['mathml'], 'merror'), (namespaces['mathml'], 'mfrac'), (namespaces['mathml'], 'mi'), (namespaces['mathml'], 'mmultiscripts'), (namespaces['mathml'], 'mn'), (namespaces['mathml'], 'mo'), (namespaces['mathml'], 'mover'), (namespaces['mathml'], 'mpadded'), (namespaces['mathml'], 'mphantom'), (namespaces['mathml'], 'mprescripts'), (namespaces['mathml'], 'mroot'), (namespaces['mathml'], 'mrow'), (namespaces['mathml'], 'mspace'), (namespaces['mathml'], 'msqrt'), (namespaces['mathml'], 'mstyle'), (namespaces['mathml'], 'msub'), (namespaces['mathml'], 'msubsup'), (namespaces['mathml'], 'msup'), (namespaces['mathml'], 'mtable'), (namespaces['mathml'], 'mtd'), (namespaces['mathml'], 'mtext'), (namespaces['mathml'], 'mtr'), (namespaces['mathml'], 'munder'), (namespaces['mathml'], 'munderover'), (namespaces['mathml'], 'none'), (namespaces['svg'], 'a'), (namespaces['svg'], 'animate'), (namespaces['svg'], 'animateColor'), (namespaces['svg'], 'animateMotion'), (namespaces['svg'], 'animateTransform'), (namespaces['svg'], 'clipPath'), (namespaces['svg'], 'circle'), (namespaces['svg'], 'defs'), (namespaces['svg'], 'desc'), (namespaces['svg'], 'ellipse'), (namespaces['svg'], 'font-face'), (namespaces['svg'], 'font-face-name'), (namespaces['svg'], 'font-face-src'), (namespaces['svg'], 'g'), (namespaces['svg'], 'glyph'), (namespaces['svg'], 'hkern'), (namespaces['svg'], 'linearGradient'), (namespaces['svg'], 'line'), (namespaces['svg'], 'marker'), (namespaces['svg'], 'metadata'), (namespaces['svg'], 'missing-glyph'), (namespaces['svg'], 'mpath'), (namespaces['svg'], 'path'), (namespaces['svg'], 'polygon'), (namespaces['svg'], 'polyline'), (namespaces['svg'], 'radialGradient'), (namespaces['svg'], 'rect'), (namespaces['svg'], 'set'), (namespaces['svg'], 'stop'), (namespaces['svg'], 'svg'), (namespaces['svg'], 'switch'), (namespaces['svg'], 'text'), (namespaces['svg'], 'title'), (namespaces['svg'], 'tspan'), (namespaces['svg'], 'use'), )) allowed_attributes = frozenset(( # HTML attributes (None, 'abbr'), (None, 'accept'), (None, 'accept-charset'), (None, 'accesskey'), (None, 'action'), (None, 'align'), (None, 'alt'), (None, 'autocomplete'), (None, 'autofocus'), (None, 'axis'), (None, 'background'), (None, 'balance'), (None, 'bgcolor'), (None, 'bgproperties'), (None, 'border'), (None, 'bordercolor'), (None, 'bordercolordark'), (None, 'bordercolorlight'), (None, 'bottompadding'), (None, 'cellpadding'), (None, 'cellspacing'), (None, 'ch'), (None, 'challenge'), (None, 'char'), (None, 'charoff'), (None, 'choff'), (None, 'charset'), (None, 'checked'), (None, 'cite'), (None, 'class'), (None, 'clear'), (None, 'color'), (None, 'cols'), (None, 'colspan'), (None, 'compact'), (None, 'contenteditable'), (None, 'controls'), (None, 'coords'), (None, 'data'), (None, 'datafld'), (None, 'datapagesize'), (None, 'datasrc'), (None, 'datetime'), (None, 'default'), (None, 'delay'), (None, 'dir'), (None, 'disabled'), (None, 'draggable'), (None, 'dynsrc'), (None, 'enctype'), (None, 'end'), (None, 'face'), (None, 'for'), (None, 'form'), (None, 'frame'), (None, 'galleryimg'), (None, 'gutter'), (None, 'headers'), (None, 'height'), (None, 'hidefocus'), (None, 'hidden'), (None, 'high'), (None, 'href'), (None, 'hreflang'), (None, 'hspace'), (None, 'icon'), (None, 'id'), (None, 'inputmode'), (None, 'ismap'), (None, 'keytype'), (None, 'label'), (None, 'leftspacing'), (None, 'lang'), (None, 'list'), (None, 'longdesc'), (None, 'loop'), (None, 'loopcount'), (None, 'loopend'), (None, 'loopstart'), (None, 'low'), (None, 'lowsrc'), (None, 'max'), (None, 'maxlength'), (None, 'media'), (None, 'method'), (None, 'min'), (None, 'multiple'), (None, 'name'), (None, 'nohref'), (None, 'noshade'), (None, 'nowrap'), (None, 'open'), (None, 'optimum'), (None, 'pattern'), (None, 'ping'), (None, 'point-size'), (None, 'poster'), (None, 'pqg'), (None, 'preload'), (None, 'prompt'), (None, 'radiogroup'), (None, 'readonly'), (None, 'rel'), (None, 'repeat-max'), (None, 'repeat-min'), (None, 'replace'), (None, 'required'), (None, 'rev'), (None, 'rightspacing'), (None, 'rows'), (None, 'rowspan'), (None, 'rules'), (None, 'scope'), (None, 'selected'), (None, 'shape'), (None, 'size'), (None, 'span'), (None, 'src'), (None, 'start'), (None, 'step'), (None, 'style'), (None, 'summary'), (None, 'suppress'), (None, 'tabindex'), (None, 'target'), (None, 'template'), (None, 'title'), (None, 'toppadding'), (None, 'type'), (None, 'unselectable'), (None, 'usemap'), (None, 'urn'), (None, 'valign'), (None, 'value'), (None, 'variable'), (None, 'volume'), (None, 'vspace'), (None, 'vrml'), (None, 'width'), (None, 'wrap'), (namespaces['xml'], 'lang'), # MathML attributes (None, 'actiontype'), (None, 'align'), (None, 'columnalign'), (None, 'columnalign'), (None, 'columnalign'), (None, 'columnlines'), (None, 'columnspacing'), (None, 'columnspan'), (None, 'depth'), (None, 'display'), (None, 'displaystyle'), (None, 'equalcolumns'), (None, 'equalrows'), (None, 'fence'), (None, 'fontstyle'), (None, 'fontweight'), (None, 'frame'), (None, 'height'), (None, 'linethickness'), (None, 'lspace'), (None, 'mathbackground'), (None, 'mathcolor'), (None, 'mathvariant'), (None, 'mathvariant'), (None, 'maxsize'), (None, 'minsize'), (None, 'other'), (None, 'rowalign'), (None, 'rowalign'), (None, 'rowalign'), (None, 'rowlines'), (None, 'rowspacing'), (None, 'rowspan'), (None, 'rspace'), (None, 'scriptlevel'), (None, 'selection'), (None, 'separator'), (None, 'stretchy'), (None, 'width'), (None, 'width'), (namespaces['xlink'], 'href'), (namespaces['xlink'], 'show'), (namespaces['xlink'], 'type'), # SVG attributes (None, 'accent-height'), (None, 'accumulate'), (None, 'additive'), (None, 'alphabetic'), (None, 'arabic-form'), (None, 'ascent'), (None, 'attributeName'), (None, 'attributeType'), (None, 'baseProfile'), (None, 'bbox'), (None, 'begin'), (None, 'by'), (None, 'calcMode'), (None, 'cap-height'), (None, 'class'), (None, 'clip-path'), (None, 'color'), (None, 'color-rendering'), (None, 'content'), (None, 'cx'), (None, 'cy'), (None, 'd'), (None, 'dx'), (None, 'dy'), (None, 'descent'), (None, 'display'), (None, 'dur'), (None, 'end'), (None, 'fill'), (None, 'fill-opacity'), (None, 'fill-rule'), (None, 'font-family'), (None, 'font-size'), (None, 'font-stretch'), (None, 'font-style'), (None, 'font-variant'), (None, 'font-weight'), (None, 'from'), (None, 'fx'), (None, 'fy'), (None, 'g1'), (None, 'g2'), (None, 'glyph-name'), (None, 'gradientUnits'), (None, 'hanging'), (None, 'height'), (None, 'horiz-adv-x'), (None, 'horiz-origin-x'), (None, 'id'), (None, 'ideographic'), (None, 'k'), (None, 'keyPoints'), (None, 'keySplines'), (None, 'keyTimes'), (None, 'lang'), (None, 'marker-end'), (None, 'marker-mid'), (None, 'marker-start'), (None, 'markerHeight'), (None, 'markerUnits'), (None, 'markerWidth'), (None, 'mathematical'), (None, 'max'), (None, 'min'), (None, 'name'), (None, 'offset'), (None, 'opacity'), (None, 'orient'), (None, 'origin'), (None, 'overline-position'), (None, 'overline-thickness'), (None, 'panose-1'), (None, 'path'), (None, 'pathLength'), (None, 'points'), (None, 'preserveAspectRatio'), (None, 'r'), (None, 'refX'), (None, 'refY'), (None, 'repeatCount'), (None, 'repeatDur'), (None, 'requiredExtensions'), (None, 'requiredFeatures'), (None, 'restart'), (None, 'rotate'), (None, 'rx'), (None, 'ry'), (None, 'slope'), (None, 'stemh'), (None, 'stemv'), (None, 'stop-color'), (None, 'stop-opacity'), (None, 'strikethrough-position'), (None, 'strikethrough-thickness'), (None, 'stroke'), (None, 'stroke-dasharray'), (None, 'stroke-dashoffset'), (None, 'stroke-linecap'), (None, 'stroke-linejoin'), (None, 'stroke-miterlimit'), (None, 'stroke-opacity'), (None, 'stroke-width'), (None, 'systemLanguage'), (None, 'target'), (None, 'text-anchor'), (None, 'to'), (None, 'transform'), (None, 'type'), (None, 'u1'), (None, 'u2'), (None, 'underline-position'), (None, 'underline-thickness'), (None, 'unicode'), (None, 'unicode-range'), (None, 'units-per-em'), (None, 'values'), (None, 'version'), (None, 'viewBox'), (None, 'visibility'), (None, 'width'), (None, 'widths'), (None, 'x'), (None, 'x-height'), (None, 'x1'), (None, 'x2'), (namespaces['xlink'], 'actuate'), (namespaces['xlink'], 'arcrole'), (namespaces['xlink'], 'href'), (namespaces['xlink'], 'role'), (namespaces['xlink'], 'show'), (namespaces['xlink'], 'title'), (namespaces['xlink'], 'type'), (namespaces['xml'], 'base'), (namespaces['xml'], 'lang'), (namespaces['xml'], 'space'), (None, 'y'), (None, 'y1'), (None, 'y2'), (None, 'zoomAndPan'), )) attr_val_is_uri = frozenset(( (None, 'href'), (None, 'src'), (None, 'cite'), (None, 'action'), (None, 'longdesc'), (None, 'poster'), (None, 'background'), (None, 'datasrc'), (None, 'dynsrc'), (None, 'lowsrc'), (None, 'ping'), (namespaces['xlink'], 'href'), (namespaces['xml'], 'base'), )) svg_attr_val_allows_ref = frozenset(( (None, 'clip-path'), (None, 'color-profile'), (None, 'cursor'), (None, 'fill'), (None, 'filter'), (None, 'marker'), (None, 'marker-start'), (None, 'marker-mid'), (None, 'marker-end'), (None, 'mask'), (None, 'stroke'), )) svg_allow_local_href = frozenset(( (None, 'altGlyph'), (None, 'animate'), (None, 'animateColor'), (None, 'animateMotion'), (None, 'animateTransform'), (None, 'cursor'), (None, 'feImage'), (None, 'filter'), (None, 'linearGradient'), (None, 'pattern'), (None, 'radialGradient'), (None, 'textpath'), (None, 'tref'), (None, 'set'), (None, 'use') )) allowed_css_properties = frozenset(( 'azimuth', 'background-color', 'border-bottom-color', 'border-collapse', 'border-color', 'border-left-color', 'border-right-color', 'border-top-color', 'clear', 'color', 'cursor', 'direction', 'display', 'elevation', 'float', 'font', 'font-family', 'font-size', 'font-style', 'font-variant', 'font-weight', 'height', 'letter-spacing', 'line-height', 'overflow', 'pause', 'pause-after', 'pause-before', 'pitch', 'pitch-range', 'richness', 'speak', 'speak-header', 'speak-numeral', 'speak-punctuation', 'speech-rate', 'stress', 'text-align', 'text-decoration', 'text-indent', 'unicode-bidi', 'vertical-align', 'voice-family', 'volume', 'white-space', 'width', )) allowed_css_keywords = frozenset(( 'auto', 'aqua', 'black', 'block', 'blue', 'bold', 'both', 'bottom', 'brown', 'center', 'collapse', 'dashed', 'dotted', 'fuchsia', 'gray', 'green', '!important', 'italic', 'left', 'lime', 'maroon', 'medium', 'none', 'navy', 'normal', 'nowrap', 'olive', 'pointer', 'purple', 'red', 'right', 'solid', 'silver', 'teal', 'top', 'transparent', 'underline', 'white', 'yellow', )) allowed_svg_properties = frozenset(( 'fill', 'fill-opacity', 'fill-rule', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin', 'stroke-opacity', )) allowed_protocols = frozenset(( 'ed2k', 'ftp', 'http', 'https', 'irc', 'mailto', 'news', 'gopher', 'nntp', 'telnet', 'webcal', 'xmpp', 'callto', 'feed', 'urn', 'aim', 'rsync', 'tag', 'ssh', 'sftp', 'rtsp', 'afs', 'data', )) allowed_content_types = frozenset(( 'image/png', 'image/jpeg', 'image/gif', 'image/webp', 'image/bmp', 'text/plain', )) data_content_type = re.compile(r''' ^ # Match a content type / (?P[-a-zA-Z0-9.]+/[-a-zA-Z0-9.]+) # Match any character set and encoding (?:(?:;charset=(?:[-a-zA-Z0-9]+)(?:;(?:base64))?) |(?:;(?:base64))?(?:;charset=(?:[-a-zA-Z0-9]+))?) # Assume the rest is data ,.* $ ''', re.VERBOSE) class Filter(base.Filter): """ sanitization of XHTML+MathML+SVG and of inline style attributes.""" def __init__(self, source, allowed_elements=allowed_elements, allowed_attributes=allowed_attributes, allowed_css_properties=allowed_css_properties, allowed_css_keywords=allowed_css_keywords, allowed_svg_properties=allowed_svg_properties, allowed_protocols=allowed_protocols, allowed_content_types=allowed_content_types, attr_val_is_uri=attr_val_is_uri, svg_attr_val_allows_ref=svg_attr_val_allows_ref, svg_allow_local_href=svg_allow_local_href): super(Filter, self).__init__(source) self.allowed_elements = allowed_elements self.allowed_attributes = allowed_attributes self.allowed_css_properties = allowed_css_properties self.allowed_css_keywords = allowed_css_keywords self.allowed_svg_properties = allowed_svg_properties self.allowed_protocols = allowed_protocols self.allowed_content_types = allowed_content_types self.attr_val_is_uri = attr_val_is_uri self.svg_attr_val_allows_ref = svg_attr_val_allows_ref self.svg_allow_local_href = svg_allow_local_href def __iter__(self): for token in base.Filter.__iter__(self): token = self.sanitize_token(token) if token: yield token # Sanitize the +html+, escaping all elements not in ALLOWED_ELEMENTS, and # stripping out all # attributes not in ALLOWED_ATTRIBUTES. Style # attributes are parsed, and a restricted set, # specified by # ALLOWED_CSS_PROPERTIES and ALLOWED_CSS_KEYWORDS, are allowed through. # attributes in ATTR_VAL_IS_URI are scanned, and only URI schemes specified # in ALLOWED_PROTOCOLS are allowed. # # sanitize_html('') # => <script> do_nasty_stuff() </script> # sanitize_html('Click here for $100') # => Click here for $100 def sanitize_token(self, token): # accommodate filters which use token_type differently token_type = token["type"] if token_type in ("StartTag", "EndTag", "EmptyTag"): name = token["name"] namespace = token["namespace"] if ((namespace, name) in self.allowed_elements or (namespace is None and (namespaces["html"], name) in self.allowed_elements)): return self.allowed_token(token) else: return self.disallowed_token(token) elif token_type == "Comment": pass else: return token def allowed_token(self, token): if "data" in token: attrs = token["data"] attr_names = set(attrs.keys()) # Remove forbidden attributes for to_remove in (attr_names - self.allowed_attributes): del token["data"][to_remove] attr_names.remove(to_remove) # Remove attributes with disallowed URL values for attr in (attr_names & self.attr_val_is_uri): assert attr in attrs # I don't have a clue where this regexp comes from or why it matches those # characters, nor why we call unescape. I just know it's always been here. # Should you be worried by this comment in a sanitizer? Yes. On the other hand, all # this will do is remove *more* than it otherwise would. val_unescaped = re.sub("[`\x00-\x20\x7f-\xa0\s]+", '', unescape(attrs[attr])).lower() # remove replacement characters from unescaped characters val_unescaped = val_unescaped.replace("\ufffd", "") try: uri = urlparse.urlparse(val_unescaped) except ValueError: uri = None del attrs[attr] if uri and uri.scheme: if uri.scheme not in self.allowed_protocols: del attrs[attr] if uri.scheme == 'data': m = data_content_type.match(uri.path) if not m: del attrs[attr] elif m.group('content_type') not in self.allowed_content_types: del attrs[attr] for attr in self.svg_attr_val_allows_ref: if attr in attrs: attrs[attr] = re.sub(r'url\s*\(\s*[^#\s][^)]+?\)', ' ', unescape(attrs[attr])) if (token["name"] in self.svg_allow_local_href and (namespaces['xlink'], 'href') in attrs and re.search('^\s*[^#\s].*', attrs[(namespaces['xlink'], 'href')])): del attrs[(namespaces['xlink'], 'href')] if (None, 'style') in attrs: attrs[(None, 'style')] = self.sanitize_css(attrs[(None, 'style')]) token["data"] = attrs return token def disallowed_token(self, token): token_type = token["type"] if token_type == "EndTag": token["data"] = "" % token["name"] elif token["data"]: assert token_type in ("StartTag", "EmptyTag") attrs = [] for (ns, name), v in token["data"].items(): attrs.append(' %s="%s"' % (name if ns is None else "%s:%s" % (prefixes[ns], name), escape(v))) token["data"] = "<%s%s>" % (token["name"], ''.join(attrs)) else: token["data"] = "<%s>" % token["name"] if token.get("selfClosing"): token["data"] = token["data"][:-1] + "/>" token["type"] = "Characters" del token["name"] return token def sanitize_css(self, style): # disallow urls style = re.compile('url\s*\(\s*[^\s)]+?\s*\)\s*').sub(' ', style) # gauntlet if not re.match("""^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$""", style): return '' if not re.match("^\s*([-\w]+\s*:[^:;]*(;\s*|$))*$", style): return '' clean = [] for prop, value in re.findall("([-\w]+)\s*:\s*([^:;]*)", style): if not value: continue if prop.lower() in self.allowed_css_properties: clean.append(prop + ': ' + value + ';') elif prop.split('-')[0].lower() in ['background', 'border', 'margin', 'padding']: for keyword in value.split(): if keyword not in self.allowed_css_keywords and \ not re.match("^(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$", keyword): # noqa break else: clean.append(prop + ': ' + value + ';') elif prop.lower() in self.allowed_svg_properties: clean.append(prop + ': ' + value + ';') return ' '.join(clean) PK!jss whitespace.pynu[from __future__ import absolute_import, division, unicode_literals import re from . import base from ..constants import rcdataElements, spaceCharacters spaceCharacters = "".join(spaceCharacters) SPACES_REGEX = re.compile("[%s]+" % spaceCharacters) class Filter(base.Filter): spacePreserveElements = frozenset(["pre", "textarea"] + list(rcdataElements)) def __iter__(self): preserve = 0 for token in base.Filter.__iter__(self): type = token["type"] if type == "StartTag" \ and (preserve or token["name"] in self.spacePreserveElements): preserve += 1 elif type == "EndTag" and preserve: preserve -= 1 elif not preserve and type == "SpaceCharacters" and token["data"]: # Test on token["data"] above to not introduce spaces where there were not token["data"] = " " elif not preserve and type == "Characters": token["data"] = collapse_spaces(token["data"]) yield token def collapse_spaces(text): return SPACES_REGEX.sub(' ', text) PK!Tt*Gqq)__pycache__/__init__.cpython-36.opt-1.pycnu[PK!Tt*Gqq#__pycache__/__init__.cpython-36.pycnu[PK!Z7__pycache__/alphabeticalattributes.cpython-36.opt-1.pycnu[PK!Z1__pycache__/alphabeticalattributes.cpython-36.pycnu[PK!<% __pycache__/base.cpython-36.opt-1.pycnu[PK!<V __pycache__/base.cpython-36.pycnu[PK!lNN4__pycache__/inject_meta_charset.cpython-36.opt-1.pycnu[PK!lNN.R__pycache__/inject_meta_charset.cpython-36.pycnu[PK!e  %__pycache__/lint.cpython-36.opt-1.pycnu[PK!\$__pycache__/lint.cpython-36.pycnu[PK!э --__pycache__/optionaltags.cpython-36.opt-1.pycnu[PK!э 'v9__pycache__/optionaltags.cpython-36.pycnu[PK!AEE*ZE__pycache__/sanitizer.cpython-36.opt-1.pycnu[PK!0FF$__pycache__/sanitizer.cpython-36.pycnu[PK!Y+__pycache__/whitespace.cpython-36.opt-1.pycnu[PK!Y%__pycache__/whitespace.cpython-36.pycnu[PK! __init__.pynu[PK!n|mmalphabeticalattributes.pynu[PK!"base.pynu[PK!!< )inject_meta_charset.pynu[PK!F  %lint.pynu[PK!!$&)&)uoptionaltags.pynu[PK!# b b !sanitizer.pynu[PK!jss "whitespace.pynu[PK ҈