def write_safe(self, *safe_strs): ctx = self.ctx_ underlying = self.underlying_ for safe_str in safe_strs: end_ctx, safe_text, before_error, unprocessed = ( context_update.process_raw_text(safe_str, ctx)) if context.is_error_context(end_ctx): raise AutoescapeError(safe_text[:-len(unprocessed)], unprocessed) ctx = end_ctx underlying.write(safe_str) self.ctx_ = ctx
def write_safe(self, *safe_strs): ctx = self.ctx_ underlying = self.underlying_ for safe_str in safe_strs: end_ctx, safe_text, before_error, unprocessed = ( context_update.process_raw_text(safe_str, ctx)) if context.is_error_context(end_ctx): raise AutoescapeError( safe_text[:-len(unprocessed)], unprocessed) ctx = end_ctx underlying.write(safe_str) self.ctx_ = ctx
def step(self, start_state, step_value, debug_hint=None): if context.is_error_context(start_state): # Simplifies error checking below. return start_state if hasattr(step_value, 'to_raw_content'): # Handle text nodes specified by the template author. raw_content = step_value.to_raw_content() if raw_content is not None: try: end_state, new_content, error_ctx, error_text = ( context_update.process_raw_text( raw_content, start_state)) if context.is_error_context(end_state): self.error(debug_hint, 'bad content in %s: `%s`' % ( debug.context_to_string(error_ctx), error_text)) elif new_content != raw_content: self.text_values[step_value] = new_content except context_update.ContextUpdateFailure, err: self.error(debug_hint, str(err)) end_state = context.STATE_ERROR return end_state
def step(self, start_state, step_value, debug_hint=None): if context.is_error_context(start_state): # Simplifies error checking below. return start_state if hasattr(step_value, 'to_raw_content'): # Handle text nodes specified by the template author. raw_content = step_value.to_raw_content() if raw_content is not None: try: end_state, new_content, error_ctx, error_text = ( context_update.process_raw_text( raw_content, start_state)) if context.is_error_context(end_state): self.error( debug_hint, 'bad content in %s: `%s`' % (debug.context_to_string(error_ctx), error_text)) elif new_content != raw_content: self.text_values[step_value] = new_content except context_update.ContextUpdateFailure, err: self.error(debug_hint, str(err)) end_state = context.STATE_ERROR return end_state
def test_escape_text(self): """ Tests the content propagation algorithm. """ tests = ( ( "", 0, ), ( 'Hello, World!', 0, ), ( # An orphaned "<" is OK. 'I <3 Ponies!', 0, 'I <3 Ponies!', ), ( '<a', context.STATE_TAG_NAME, ), ( '<a ', context.STATE_TAG, ), ( '<a>', context.STATE_TEXT, ), ( '<a href', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a on', context.STATE_ATTR_NAME | context.ATTR_SCRIPT, ), ( '<a href ', context.STATE_AFTER_NAME | context.ATTR_URL, ), ( '<a style = ', context.STATE_BEFORE_VALUE | context.ATTR_STYLE, ), ( '<a href=', context.STATE_BEFORE_VALUE | context.ATTR_URL, ), ( '<a href=x', context.STATE_URL | context.DELIM_SPACE_OR_TAG_END | context.URL_PART_PRE_QUERY, '<a href="x', ), ( '<a href=x ', context.STATE_TAG, '<a href="x" ', ), ( '<a href=>', context.STATE_TEXT, '<a href="">', ), ( '<a href=x>', context.STATE_TEXT, '<a href="x">', ), ( "<a href ='", context.STATE_URL | context.DELIM_SINGLE_QUOTE, ), ( "<a href=''", context.STATE_TAG, ), ( '<a href= "', context.STATE_URL | context.DELIM_DOUBLE_QUOTE, ), ( '<a href=""', context.STATE_TAG, ), ( '<a title="', context.STATE_ATTR | context.DELIM_DOUBLE_QUOTE, ), ( "<a HREF='http:", context.STATE_URL | context.DELIM_SINGLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( "<a Href='/", context.STATE_URL | context.DELIM_SINGLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( "<a href='\"", context.STATE_URL | context.DELIM_SINGLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a href="\'', context.STATE_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( "<a href=''", context.STATE_URL | context.DELIM_SINGLE_QUOTE | context.URL_PART_PRE_QUERY, "<a href=''", ), ( '<a href=""', context.STATE_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, '<a href=""', ), ( '<a href=""', context.STATE_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a href="', context.STATE_URL | context.DELIM_SPACE_OR_TAG_END | context.URL_PART_PRE_QUERY, '<a href=""', ), ( '<a href="/search?q=', context.STATE_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_QUERY_OR_FRAG, ), ( '<img alt="1">', context.STATE_TEXT, ), ( '<img alt="1>"', context.STATE_TAG, '<img alt="1>"', ), ( '<img alt="1>">', context.STATE_TEXT, '<img alt="1>">', ), ( '<input checked type="checkbox"', context.STATE_TAG, ), ( '<a onclick="', context.STATE_JS | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="//foo', context.STATE_JSLINE_CMT | context.DELIM_DOUBLE_QUOTE, '<a onclick="', ), ( "<a onclick='//\n", context.STATE_JS | context.DELIM_SINGLE_QUOTE, "<a onclick='\n", ), ( "<a onclick='//\r\n", context.STATE_JS | context.DELIM_SINGLE_QUOTE, "<a onclick='\n\n", # \n\n is ok, \n is ok, \r\n is ok ), ( u"<a onclick='//\u2028", context.STATE_JS | context.DELIM_SINGLE_QUOTE, "<a onclick='\n", ), ( '<a onclick="/*', context.STATE_JSBLOCK_CMT | context.DELIM_DOUBLE_QUOTE, '<a onclick=" ', ), ( '<a onclick="/*/', context.STATE_JSBLOCK_CMT | context.DELIM_DOUBLE_QUOTE, '<a onclick=" ', ), ( '<a onclick="/**/', context.STATE_JS | context.DELIM_DOUBLE_QUOTE, '<a onclick=" ', ), ( '<a onkeypress=""', context.STATE_JSDQ_STR | context.DELIM_DOUBLE_QUOTE, '<a onkeypress=""', ), ( "<a onclick='"foo"", context.STATE_JS | context.DELIM_SINGLE_QUOTE | context.JS_CTX_DIV_OP, "<a onclick='\"foo\"", ), ( '<a onclick='foo'', context.STATE_JS | context.DELIM_SPACE_OR_TAG_END | context.JS_CTX_DIV_OP, '<a onclick="\'foo\'', ), ( '<a onclick='foo', context.STATE_JSSQ_STR | context.DELIM_SPACE_OR_TAG_END, '<a onclick="\'foo', ), ( '<a onclick=""foo\'', context.STATE_JSDQ_STR | context.DELIM_DOUBLE_QUOTE, '<a onclick=""foo\'', ), ( '<a onclick="\'foo"', context.STATE_JSSQ_STR | context.DELIM_DOUBLE_QUOTE, '<a onclick="\'foo"', ), ( '<A ONCLICK="\'', context.STATE_JSSQ_STR | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="/', context.STATE_JSREGEXP | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="\'foo\'', context.STATE_JS | context.DELIM_DOUBLE_QUOTE | context.JS_CTX_DIV_OP, ), ( '<a onclick="\'foo\\\'', context.STATE_JSSQ_STR | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="\'foo\\\'', context.STATE_JSSQ_STR | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="/foo/', context.STATE_JS | context.DELIM_DOUBLE_QUOTE | context.JS_CTX_DIV_OP, ), ( '<script>/foo/ /=', context.STATE_JS | context.ELEMENT_SCRIPT, ), ( '<a onclick="1 /foo', context.STATE_JS | context.DELIM_DOUBLE_QUOTE | context.JS_CTX_DIV_OP, ), ( '<a onclick="1 /*c*/ /foo', context.STATE_JS | context.DELIM_DOUBLE_QUOTE | context.JS_CTX_DIV_OP, '<a onclick="1 /foo', ), ( '<a onclick="/foo[/]', context.STATE_JSREGEXP | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="/foo\\/', context.STATE_JSREGEXP | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="/foo/', context.STATE_JS | context.DELIM_DOUBLE_QUOTE | context.JS_CTX_DIV_OP, ), ( '<input checked style="', context.STATE_CSS | context.DELIM_DOUBLE_QUOTE, ), ( '<a style="//', context.STATE_CSSLINE_CMT | context.DELIM_DOUBLE_QUOTE, '<a style="', ), ( '<a style="//</script>', context.STATE_CSSLINE_CMT | context.DELIM_DOUBLE_QUOTE, '<a style="', ), ( "<a style='//\n", context.STATE_CSS | context.DELIM_SINGLE_QUOTE, "<a style='\n", ), ( "<a style='//\r", context.STATE_CSS | context.DELIM_SINGLE_QUOTE, "<a style='\n", ), ( '<a style="/*', context.STATE_CSSBLOCK_CMT | context.DELIM_DOUBLE_QUOTE, '<a style=" ', ), ( '<a style="/*/', context.STATE_CSSBLOCK_CMT | context.DELIM_DOUBLE_QUOTE, '<a style=" ', ), ( '<a style="/**/', context.STATE_CSS | context.DELIM_DOUBLE_QUOTE, '<a style=" ', ), ( '<a style="background: \'', context.STATE_CSSSQ_STR | context.DELIM_DOUBLE_QUOTE, ), ( '<a style="background: "', context.STATE_CSSDQ_STR | context.DELIM_DOUBLE_QUOTE, '<a style="background: "', ), ( '<a style="background: \'/foo?img=', context.STATE_CSSSQ_STR | context.DELIM_DOUBLE_QUOTE | context.URL_PART_QUERY_OR_FRAG, ), ( '<a style="background: \'/', context.STATE_CSSSQ_STR | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a style="background: url("/', context.STATE_CSSDQ_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, '<a style="background: url("/', ), ( '<a style="background: url(\'/', context.STATE_CSSSQ_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a style="background: url(\'/)', context.STATE_CSSSQ_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a style="background: url(\'/ ', context.STATE_CSSSQ_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a style="background: url(/', context.STATE_CSS_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a style="background: url( ', context.STATE_CSS_URL | context.DELIM_DOUBLE_QUOTE, ), ( '<a style="background: url( /image?name=', context.STATE_CSS_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_QUERY_OR_FRAG, ), ( '<a style="background: url(x)', context.STATE_CSS | context.DELIM_DOUBLE_QUOTE, ), ( '<a style="background: url(\'x\'', context.STATE_CSS | context.DELIM_DOUBLE_QUOTE, ), ( '<a style="background: url( x ', context.STATE_CSS | context.DELIM_DOUBLE_QUOTE, ), ( '<!-- foo', context.STATE_HTMLCMT, '', ), ( '<!-->', context.STATE_HTMLCMT, '', ), ( '<!--->', context.STATE_HTMLCMT, '', ), ( '<!-- foo -->', context.STATE_TEXT, '', ), ( '<script', context.STATE_TAG | context.ELEMENT_SCRIPT, ), ( '<script ', context.STATE_TAG | context.ELEMENT_SCRIPT, ), ( '<script src="foo.js" ', context.STATE_TAG | context.ELEMENT_SCRIPT, ), ( "<script src='foo.js' ", context.STATE_TAG | context.ELEMENT_SCRIPT, ), ( '<script type=text/javascript ', context.STATE_TAG | context.ELEMENT_SCRIPT, '<script type="text/javascript" ', ), ( '<script>foo', context.STATE_JS | context.JS_CTX_DIV_OP | context.ELEMENT_SCRIPT, ), ( '<script>foo</script>', context.STATE_TEXT, ), ( '<script>foo</script><!--', context.STATE_HTMLCMT, '<script>foo</script>', ), ( '<script>document.write("<p>foo</p>");', context.STATE_JS | context.ELEMENT_SCRIPT, ), ( r'<script>document.write("<p>foo<\/script>");', context.STATE_JS | context.ELEMENT_SCRIPT, ), ( '<script>document.write("<script>alert(1)</script>");', context.STATE_TEXT, ), ( '<Script>', context.STATE_JS | context.ELEMENT_SCRIPT, ), ( '<SCRIPT>foo', context.STATE_JS | context.JS_CTX_DIV_OP | context.ELEMENT_SCRIPT, ), ( '<textarea>value', context.STATE_RCDATA | context.ELEMENT_TEXTAREA, ), ( '<textarea>value</textarea>', context.STATE_TEXT, ), ( '<textarea>value</TEXTAREA>', context.STATE_TEXT, ), ( '<textarea name=html><b', context.STATE_RCDATA | context.ELEMENT_TEXTAREA, '<textarea name="html"><b', ), ( '<title>value', context.STATE_RCDATA | context.ELEMENT_TITLE, ), ( '<style>value', context.STATE_CSS | context.ELEMENT_STYLE, ), ( '<a xlink:href', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a xmlns', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a xmlns:foo', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a xmlnsxyz', context.STATE_ATTR_NAME, ), ( '<a data-url', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a data-iconUri', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a data-urlItem', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a g:', context.STATE_ATTR_NAME, ), ( '<a g:url', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a g:iconUri', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a g:urlItem', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a g:value', context.STATE_ATTR_NAME, ), ( "<a svg:style='", context.STATE_CSS | context.DELIM_SINGLE_QUOTE, ), ( '<svg:font-face', context.STATE_TAG_NAME, ), ( '<svg:a svg:onclick="', context.STATE_JS | context.DELIM_DOUBLE_QUOTE, )) for test_case in tests: if len(test_case) == 2: test_input, want_ctx = test_case want_text = test_input else: test_input, want_ctx, want_text = test_case got_ctx, got_text, _, _ = context_update.process_raw_text( test_input, 0) if got_ctx != want_ctx: self.fail("input %r: want context\n\t%s\ngot\n\t%s" % (test_input, debug.context_to_string(want_ctx), debug.context_to_string(got_ctx))) self.assertEquals(got_text, want_text, msg=("input %r: want text\n\t%r\ngot\n\t%r" % (test_input, want_text, got_text)))
def test_escape_text(self): """ Tests the content propagation algorithm. """ tests = ( ( "", 0, ), ( 'Hello, World!', 0, ), ( # An orphaned "<" is OK. 'I <3 Ponies!', 0, 'I <3 Ponies!', ), ( '<a', context.STATE_TAG_NAME, ), ( '<a ', context.STATE_TAG, ), ( '<a>', context.STATE_TEXT, ), ( '<a href', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a on', context.STATE_ATTR_NAME | context.ATTR_SCRIPT, ), ( '<a href ', context.STATE_AFTER_NAME | context.ATTR_URL, ), ( '<a style = ', context.STATE_BEFORE_VALUE | context.ATTR_STYLE, ), ( '<a href=', context.STATE_BEFORE_VALUE | context.ATTR_URL, ), ( '<a href=x', context.STATE_URL | context.DELIM_SPACE_OR_TAG_END | context.URL_PART_PRE_QUERY, '<a href="x', ), ( '<a href=x ', context.STATE_TAG, '<a href="x" ', ), ( '<a href=>', context.STATE_TEXT, '<a href="">', ), ( '<a href=x>', context.STATE_TEXT, '<a href="x">', ), ( "<a href ='", context.STATE_URL | context.DELIM_SINGLE_QUOTE, ), ( "<a href=''", context.STATE_TAG, ), ( '<a href= "', context.STATE_URL | context.DELIM_DOUBLE_QUOTE, ), ( '<a href=""', context.STATE_TAG, ), ( '<a title="', context.STATE_ATTR | context.DELIM_DOUBLE_QUOTE, ), ( "<a HREF='http:", context.STATE_URL | context.DELIM_SINGLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( "<a Href='/", context.STATE_URL | context.DELIM_SINGLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( "<a href='\"", context.STATE_URL | context.DELIM_SINGLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a href="\'', context.STATE_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( "<a href=''", context.STATE_URL | context.DELIM_SINGLE_QUOTE | context.URL_PART_PRE_QUERY, "<a href=''", ), ( '<a href=""', context.STATE_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, '<a href=""', ), ( '<a href=""', context.STATE_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a href="', context.STATE_URL | context.DELIM_SPACE_OR_TAG_END | context.URL_PART_PRE_QUERY, '<a href=""', ), ( '<a href="/search?q=', context.STATE_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_QUERY_OR_FRAG, ), ( '<img alt="1">', context.STATE_TEXT, ), ( '<img alt="1>"', context.STATE_TAG, '<img alt="1>"', ), ( '<img alt="1>">', context.STATE_TEXT, '<img alt="1>">', ), ( '<input checked type="checkbox"', context.STATE_TAG, ), ( '<a onclick="', context.STATE_JS | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="//foo', context.STATE_JSLINE_CMT | context.DELIM_DOUBLE_QUOTE, '<a onclick="', ), ( "<a onclick='//\n", context.STATE_JS | context.DELIM_SINGLE_QUOTE, "<a onclick='\n", ), ( "<a onclick='//\r\n", context.STATE_JS | context.DELIM_SINGLE_QUOTE, "<a onclick='\n\n", # \n\n is ok, \n is ok, \r\n is ok ), ( u"<a onclick='//\u2028", context.STATE_JS | context.DELIM_SINGLE_QUOTE, "<a onclick='\n", ), ( '<a onclick="/*', context.STATE_JSBLOCK_CMT | context.DELIM_DOUBLE_QUOTE, '<a onclick=" ', ), ( '<a onclick="/*/', context.STATE_JSBLOCK_CMT | context.DELIM_DOUBLE_QUOTE, '<a onclick=" ', ), ( '<a onclick="/**/', context.STATE_JS | context.DELIM_DOUBLE_QUOTE, '<a onclick=" ', ), ( '<a onkeypress=""', context.STATE_JSDQ_STR | context.DELIM_DOUBLE_QUOTE, '<a onkeypress=""', ), ( "<a onclick='"foo"", context.STATE_JS | context.DELIM_SINGLE_QUOTE | context.JS_CTX_DIV_OP, "<a onclick='\"foo\"", ), ( '<a onclick='foo'', context.STATE_JS | context.DELIM_SPACE_OR_TAG_END | context.JS_CTX_DIV_OP, '<a onclick="\'foo\'', ), ( '<a onclick='foo', context.STATE_JSSQ_STR | context.DELIM_SPACE_OR_TAG_END, '<a onclick="\'foo', ), ( '<a onclick=""foo\'', context.STATE_JSDQ_STR | context.DELIM_DOUBLE_QUOTE, '<a onclick=""foo\'', ), ( '<a onclick="\'foo"', context.STATE_JSSQ_STR | context.DELIM_DOUBLE_QUOTE, '<a onclick="\'foo"', ), ( '<A ONCLICK="\'', context.STATE_JSSQ_STR | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="/', context.STATE_JSREGEXP | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="\'foo\'', context.STATE_JS | context.DELIM_DOUBLE_QUOTE | context.JS_CTX_DIV_OP, ), ( '<a onclick="\'foo\\\'', context.STATE_JSSQ_STR | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="\'foo\\\'', context.STATE_JSSQ_STR | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="/foo/', context.STATE_JS | context.DELIM_DOUBLE_QUOTE | context.JS_CTX_DIV_OP, ), ( '<script>/foo/ /=', context.STATE_JS | context.ELEMENT_SCRIPT, ), ( '<a onclick="1 /foo', context.STATE_JS | context.DELIM_DOUBLE_QUOTE | context.JS_CTX_DIV_OP, ), ( '<a onclick="1 /*c*/ /foo', context.STATE_JS | context.DELIM_DOUBLE_QUOTE | context.JS_CTX_DIV_OP, '<a onclick="1 /foo', ), ( '<a onclick="/foo[/]', context.STATE_JSREGEXP | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="/foo\\/', context.STATE_JSREGEXP | context.DELIM_DOUBLE_QUOTE, ), ( '<a onclick="/foo/', context.STATE_JS | context.DELIM_DOUBLE_QUOTE | context.JS_CTX_DIV_OP, ), ( '<input checked style="', context.STATE_CSS | context.DELIM_DOUBLE_QUOTE, ), ( '<a style="//', context.STATE_CSSLINE_CMT | context.DELIM_DOUBLE_QUOTE, '<a style="', ), ( '<a style="//</script>', context.STATE_CSSLINE_CMT | context.DELIM_DOUBLE_QUOTE, '<a style="', ), ( "<a style='//\n", context.STATE_CSS | context.DELIM_SINGLE_QUOTE, "<a style='\n", ), ( "<a style='//\r", context.STATE_CSS | context.DELIM_SINGLE_QUOTE, "<a style='\n", ), ( '<a style="/*', context.STATE_CSSBLOCK_CMT | context.DELIM_DOUBLE_QUOTE, '<a style=" ', ), ( '<a style="/*/', context.STATE_CSSBLOCK_CMT | context.DELIM_DOUBLE_QUOTE, '<a style=" ', ), ( '<a style="/**/', context.STATE_CSS | context.DELIM_DOUBLE_QUOTE, '<a style=" ', ), ( '<a style="background: \'', context.STATE_CSSSQ_STR | context.DELIM_DOUBLE_QUOTE, ), ( '<a style="background: "', context.STATE_CSSDQ_STR | context.DELIM_DOUBLE_QUOTE, '<a style="background: "', ), ( '<a style="background: \'/foo?img=', context.STATE_CSSSQ_STR | context.DELIM_DOUBLE_QUOTE | context.URL_PART_QUERY_OR_FRAG, ), ( '<a style="background: \'/', context.STATE_CSSSQ_STR | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a style="background: url("/', context.STATE_CSSDQ_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, '<a style="background: url("/', ), ( '<a style="background: url(\'/', context.STATE_CSSSQ_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a style="background: url(\'/)', context.STATE_CSSSQ_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a style="background: url(\'/ ', context.STATE_CSSSQ_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a style="background: url(/', context.STATE_CSS_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_PRE_QUERY, ), ( '<a style="background: url( ', context.STATE_CSS_URL | context.DELIM_DOUBLE_QUOTE, ), ( '<a style="background: url( /image?name=', context.STATE_CSS_URL | context.DELIM_DOUBLE_QUOTE | context.URL_PART_QUERY_OR_FRAG, ), ( '<a style="background: url(x)', context.STATE_CSS | context.DELIM_DOUBLE_QUOTE, ), ( '<a style="background: url(\'x\'', context.STATE_CSS | context.DELIM_DOUBLE_QUOTE, ), ( '<a style="background: url( x ', context.STATE_CSS | context.DELIM_DOUBLE_QUOTE, ), ( '<!-- foo', context.STATE_HTMLCMT, '', ), ( '<!-->', context.STATE_HTMLCMT, '', ), ( '<!--->', context.STATE_HTMLCMT, '', ), ( '<!-- foo -->', context.STATE_TEXT, '', ), ( '<script', context.STATE_TAG | context.ELEMENT_SCRIPT, ), ( '<script ', context.STATE_TAG | context.ELEMENT_SCRIPT, ), ( '<script src="foo.js" ', context.STATE_TAG | context.ELEMENT_SCRIPT, ), ( "<script src='foo.js' ", context.STATE_TAG | context.ELEMENT_SCRIPT, ), ( '<script type=text/javascript ', context.STATE_TAG | context.ELEMENT_SCRIPT, '<script type="text/javascript" ', ), ( '<script>foo', context.STATE_JS | context.JS_CTX_DIV_OP | context.ELEMENT_SCRIPT, ), ( '<script>foo</script>', context.STATE_TEXT, ), ( '<script>foo</script><!--', context.STATE_HTMLCMT, '<script>foo</script>', ), ( '<script>document.write("<p>foo</p>");', context.STATE_JS | context.ELEMENT_SCRIPT, ), ( r'<script>document.write("<p>foo<\/script>");', context.STATE_JS | context.ELEMENT_SCRIPT, ), ( '<script>document.write("<script>alert(1)</script>");', context.STATE_TEXT, ), ( '<Script>', context.STATE_JS | context.ELEMENT_SCRIPT, ), ( '<SCRIPT>foo', context.STATE_JS | context.JS_CTX_DIV_OP | context.ELEMENT_SCRIPT, ), ( '<textarea>value', context.STATE_RCDATA | context.ELEMENT_TEXTAREA, ), ( '<textarea>value</textarea>', context.STATE_TEXT, ), ( '<textarea>value</TEXTAREA>', context.STATE_TEXT, ), ( '<textarea name=html><b', context.STATE_RCDATA | context.ELEMENT_TEXTAREA, '<textarea name="html"><b', ), ( '<title>value', context.STATE_RCDATA | context.ELEMENT_TITLE, ), ( '<style>value', context.STATE_CSS | context.ELEMENT_STYLE, ), ( '<a xlink:href', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a xmlns', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a xmlns:foo', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a xmlnsxyz', context.STATE_ATTR_NAME, ), ( '<a data-url', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a data-iconUri', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a data-urlItem', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a g:', context.STATE_ATTR_NAME, ), ( '<a g:url', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a g:iconUri', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a g:urlItem', context.STATE_ATTR_NAME | context.ATTR_URL, ), ( '<a g:value', context.STATE_ATTR_NAME, ), ( "<a svg:style='", context.STATE_CSS | context.DELIM_SINGLE_QUOTE, ), ( '<svg:font-face', context.STATE_TAG_NAME, ), ( '<svg:a svg:onclick="', context.STATE_JS | context.DELIM_DOUBLE_QUOTE, ) ) for test_case in tests: if len(test_case) == 2: test_input, want_ctx = test_case want_text = test_input else: test_input, want_ctx, want_text = test_case got_ctx, got_text, _, _ = context_update.process_raw_text( test_input, 0) if got_ctx != want_ctx: self.fail("input %r: want context\n\t%s\ngot\n\t%s" % (test_input, debug.context_to_string(want_ctx), debug.context_to_string(got_ctx))) self.assertEquals( got_text, want_text, msg = ("input %r: want text\n\t%r\ngot\n\t%r" % (test_input, want_text, got_text)))