ICEfaces
  1. ICEfaces
  2. ICE-3182

DOMResponseWriter.writeText() escaping

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.7
    • Fix Version/s: 2.0-Alpha3, 2.0.0
    • Component/s: Framework
    • Labels:
      None
    • Environment:
      ICEfaces

      Description

      As the API says, text has to be written "after performing any escaping
      appropriate for the markup language being rendered".
      The SUN RI HtmlResponseWriter implements the escaping.
      In ICEFaces text render, escaping is implemented by converting
      text with DOMUtils.escapeAnsi().

      The implementation currently does not escape text inserted in the DOM. Note that it can be argued that the DOM should not contain escaped text and that any escaping should be performed during DOM serialization.

        Issue Links

          Activity

          Ted Goddard created issue -
          Hide
          Ted Goddard added a comment -

          The key factor is that component output is escaped as expected; whether the escaping occurs upon input to the DOM or output from the serializer is an implementation decision.

          Show
          Ted Goddard added a comment - The key factor is that component output is escaped as expected; whether the escaping occurs upon input to the DOM or output from the serializer is an implementation decision.
          Ted Goddard made changes -
          Field Original Value New Value
          Fix Version/s 1.7.2 [ 10130 ]
          Ken Fyten made changes -
          Assignee Mark Collette [ mark.collette ]
          Hide
          Ken Fyten added a comment -

          Need to assess any impacts on backwards compatibility also.

          Show
          Ken Fyten added a comment - Need to assess any impacts on backwards compatibility also.
          Ken Fyten made changes -
          Assignee Priority P3
          Hide
          Mark Collette added a comment -

          Certain components might need to output unescaped data, like outputText with its escaped attribute set to false. Otherwise, most everything else should be escaped. This is typically accomplished by the component using the appropriate write, writeText, writeAttribute, etc. calls on the ResponseWriter. But since most of our components use direct-to-DOM rendering, and not the ResponseWriter, we've never implemented this. I recommend we at least fix our ResponseWriter to follow the standard of escaping. Escaping should not be done at DOM serialisation though, since then we'll have already lost the context of whether something should be escaped or not. Care should be taken, when we convert our Renderers to ResponseWriter, to ensure they're using the correct escaping methods, and not double-escaping.

          Show
          Mark Collette added a comment - Certain components might need to output unescaped data, like outputText with its escaped attribute set to false. Otherwise, most everything else should be escaped. This is typically accomplished by the component using the appropriate write , writeText , writeAttribute , etc. calls on the ResponseWriter. But since most of our components use direct-to-DOM rendering, and not the ResponseWriter, we've never implemented this. I recommend we at least fix our ResponseWriter to follow the standard of escaping. Escaping should not be done at DOM serialisation though, since then we'll have already lost the context of whether something should be escaped or not. Care should be taken, when we convert our Renderers to ResponseWriter, to ensure they're using the correct escaping methods, and not double-escaping.
          Ken Fyten made changes -
          Fix Version/s 1.8DR#2 [ 10142 ]
          Fix Version/s 1.7.2 [ 10130 ]
          Ken Fyten made changes -
          Fix Version/s 2.0 [ 10032 ]
          Fix Version/s 1.8DR#2 [ 10142 ]
          Assignee Priority P3
          Assignee Mark Collette [ mark.collette ]
          Hide
          Mark Collette added a comment -

          ResponseWriter.writeText is the one that does escaping, while ResponseWriter.write does not do escaping.

          Show
          Mark Collette added a comment - ResponseWriter.writeText is the one that does escaping, while ResponseWriter.write does not do escaping.
          Hide
          Mark Collette added a comment -

          Two reasons for doing this at the ResponseWriter level, and not manually by our components, is so that our components won't accidentally omit to do escaping, and so that third party components, which most likely would have been developed to rely on the stock JSF behaviour of ResponseWriter escaping, will continue to operate safely in an ICEfaces environment.

          Show
          Mark Collette added a comment - Two reasons for doing this at the ResponseWriter level, and not manually by our components, is so that our components won't accidentally omit to do escaping, and so that third party components, which most likely would have been developed to rely on the stock JSF behaviour of ResponseWriter escaping, will continue to operate safely in an ICEfaces environment.
          Hide
          Ted Goddard added a comment -

          Further, if this is a standard feature of the JSF ResponseWriter, we should also implement that standard behavior. How does the ResponseWriter know whether the component wants escaping or not, though?

          Show
          Ted Goddard added a comment - Further, if this is a standard feature of the JSF ResponseWriter, we should also implement that standard behavior. How does the ResponseWriter know whether the component wants escaping or not, though?
          Hide
          Ted Goddard added a comment -

          Missed Mark's comment above; writeText is specified to perform escaping, so this same escaping should be performed by the DOMResponseWriter prior to insertion into the DOM:

          Write text from a character array, after any performing any escaping appropriate for the markup language being rendered

          Show
          Ted Goddard added a comment - Missed Mark's comment above; writeText is specified to perform escaping, so this same escaping should be performed by the DOMResponseWriter prior to insertion into the DOM: Write text from a character array, after any performing any escaping appropriate for the markup language being rendered
          Ken Fyten made changes -
          Assignee Ted Goddard [ ted.goddard ]
          Hide
          Ken Fyten added a comment -

          We should try to delegate to the JSF escaping to support this correctly for 2.0.

          Show
          Ken Fyten added a comment - We should try to delegate to the JSF escaping to support this correctly for 2.0.
          Ken Fyten made changes -
          Salesforce Case []
          Assignee Priority P2
          Ken Fyten made changes -
          Salesforce Case []
          Assignee Ted Goddard [ ted.goddard ] Greg Dick [ greg.dick ]
          Mark Collette made changes -
          Link This issue blocks ICE-5582 [ ICE-5582 ]
          Hide
          Judy Guglielmin added a comment -

          jsf htmlunit tests fail with the following tests
          /*

          • Regression test for bug #939
            */
            public void testCdataEscape1() throws Exception { getPage("/faces/ajax/ajaxEcho.xhtml"); // First we'll check the first page was output correctly checkTrue("form1:out1",""); checkTrue("form1:in1",""); HtmlTextInput in1 = (HtmlTextInput) lastpage.getHtmlElementById("form1:in1"); in1.type("]]>"); // Submit the ajax request HtmlSubmitInput button1 = (HtmlSubmitInput) lastpage.getHtmlElementById("form1:button1"); lastpage = (HtmlPage) button1.click(); // Check that the ajax request succeeds checkTrue("form1:out1","]]>"); //fails here as it only finds ' ' (empty string). }

          here is the markup for this test:-
          <h:body>
          <h:form id="form1"> <!-- Note that unlike previous examples, prependid='true' -->
          <h:outputScript name="jsf.js" library="javax.faces" target="head"/>
          <h:outputScript name="ajax/echo1.js" target="head"/>
          <h:outputStylesheet name="stylesheet.css"/>

          Output: <h:outputText id="out1" value="#

          {ajaxecho.str}"/>
          <br/>
          Input: <h:inputText id="in1" value="#{ajaxecho.str}

          "/>
          <!-- Increment the counter on the server, and the client -->
          <br/>
          <h:commandButton id="button1" value="Echo"
          onclick="return buttonpush('form1:out1 form1:in1', 'form1:button1 form1:in1', this, event);"/>
          <br/>
          <!-- Test using a valid string as an identifier, instead of an element -->
          <h:commandButton id="button2" value="Echo"
          onclick="return buttonpush('form1:out1 form1:in1', 'form1:button2 form1:in1', 'form1:button2', event);"/>
          <br/>
          <!-- Resets the string, refreshes the form, but not the page -->
          <h:commandButton id="reset" value="reset"
          onclick="return resetpush(this, event);"
          actionListener="#

          {ajaxecho.reset}

          "/>
          <!-- Reloads the page, doesn't reset the string -->
          <h:commandButton id="reload" value="reload"/>
          <h:messages/>
          </h:form>

          </h:body>
          </html>

          Note that other tests for escape data "]" works as does "var a=["

          Show
          Judy Guglielmin added a comment - jsf htmlunit tests fail with the following tests /* Regression test for bug #939 */ public void testCdataEscape1() throws Exception { getPage("/faces/ajax/ajaxEcho.xhtml"); // First we'll check the first page was output correctly checkTrue("form1:out1",""); checkTrue("form1:in1",""); HtmlTextInput in1 = (HtmlTextInput) lastpage.getHtmlElementById("form1:in1"); in1.type("]]>"); // Submit the ajax request HtmlSubmitInput button1 = (HtmlSubmitInput) lastpage.getHtmlElementById("form1:button1"); lastpage = (HtmlPage) button1.click(); // Check that the ajax request succeeds checkTrue("form1:out1","]]>"); //fails here as it only finds ' ' (empty string). } here is the markup for this test:- <h:body> <h:form id="form1"> <!-- Note that unlike previous examples, prependid='true' --> <h:outputScript name="jsf.js" library="javax.faces" target="head"/> <h:outputScript name="ajax/echo1.js" target="head"/> <h:outputStylesheet name="stylesheet.css"/> Output: <h:outputText id="out1" value="# {ajaxecho.str}"/> <br/> Input: <h:inputText id="in1" value="#{ajaxecho.str} "/> <!-- Increment the counter on the server, and the client --> <br/> <h:commandButton id="button1" value="Echo" onclick="return buttonpush('form1:out1 form1:in1', 'form1:button1 form1:in1', this, event);"/> <br/> <!-- Test using a valid string as an identifier, instead of an element --> <h:commandButton id="button2" value="Echo" onclick="return buttonpush('form1:out1 form1:in1', 'form1:button2 form1:in1', 'form1:button2', event);"/> <br/> <!-- Resets the string, refreshes the form, but not the page --> <h:commandButton id="reset" value="reset" onclick="return resetpush(this, event);" actionListener="# {ajaxecho.reset} "/> <!-- Reloads the page, doesn't reset the string --> <h:commandButton id="reload" value="reload"/> <h:messages/> </h:form> </h:body> </html> Note that other tests for escape data "]" works as does "var a=["
          Hide
          Ted Goddard added a comment -

          Is it possible to capture the ICEfaces and non-ICEfaces HTTP responses and paste them in here to show the difference?

          (Please assign back to Greg after this.)

          Show
          Ted Goddard added a comment - Is it possible to capture the ICEfaces and non-ICEfaces HTTP responses and paste them in here to show the difference? (Please assign back to Greg after this.)
          Ted Goddard made changes -
          Assignee Greg Dick [ greg.dick ] Judy Guglielmin [ judy.guglielmin ]
          Hide
          Judy Guglielmin added a comment -

          with ICEfaces, input into an input field for the character "a" returns the following response
          <partial-response><changes><update id="form1:out1"><Unable to render embedded object: File (out1">a</span>]]></update><update id="javax.faces.ViewState"><) not found.[CDATA[j_id3:j_id4]]></update></changes></partial-response>

          "1" is input, the response is:-
          <partial-response><changes><update id="form1:out1"><Unable to render embedded object: File (out1">1</span>]]></update><update id="javax.faces.ViewState"><) not found.[CDATA[j_id3:j_id4]]></update></changes></partial-response>

          ']" is input, the response is;_
          <partial-response><changes><update id="form1:out1"><Unable to render embedded object: File (out1"><) not found.[CDATA[ ]]></span>]]></update><update id="javax.faces.ViewState"><![CDATA[j_id23:j_id24]]></update></changes></partial-response>

          "<![CDATA[ ]]>" is input, the response is empty:-
          <partial-response><changes><update id="javax.faces.ViewState"><![CDATA[j_id23:j_id24]]></update></changes></partial-response>

          Show
          Judy Guglielmin added a comment - with ICEfaces, input into an input field for the character "a" returns the following response <partial-response><changes><update id="form1:out1">< Unable to render embedded object: File (out1">a</span>]]></update><update id="javax.faces.ViewState"><) not found. [CDATA [j_id3:j_id4] ]></update></changes></partial-response> "1" is input, the response is:- <partial-response><changes><update id="form1:out1">< Unable to render embedded object: File (out1">1</span>]]></update><update id="javax.faces.ViewState"><) not found. [CDATA [j_id3:j_id4] ]></update></changes></partial-response> ']" is input, the response is;_ <partial-response><changes><update id="form1:out1">< Unable to render embedded object: File (out1"><) not found. [CDATA[ ]]></span>]]></update><update id="javax.faces.ViewState"><![CDATA [j_id23:j_id24] ]></update></changes></partial-response> "<![CDATA[ ]]>" is input, the response is empty:- <partial-response><changes><update id="javax.faces.ViewState"><![CDATA [j_id23:j_id24] ]></update></changes></partial-response>
          Hide
          Judy Guglielmin added a comment -

          responses to the same values input without ICEfaces:-

          "a"
          <partial-response><changes><update id="form1:out1"><Unable to render embedded object: File (out1">a</span>]]></update><update id="form1:in1"><) not found.[CDATA[<input id="form1:in1" type="text" name="form1:in1" value="a" />]]></update><update id="javax.faces.ViewState"><![CDATA[j_id29:j_id30]]></update></changes></partial-response>

          "]"
          <partial-response><changes><update id="form1:out1"><Unable to render embedded object: File (out1">]</span>]]></update><update id="form1:in1"><) not found.[CDATA[<input id="form1:in1" type="text" name="form1:in1" value="]" />]]></update><update id="javax.faces.ViewState"><![CDATA[j_id29:j_id30]]></update></changes></partial-response>

          "<![CDATA[ ]]>"
          <partial-response><changes><update id="form1:out1"><Unable to render embedded object: File (out1"><) not found.[CDATA[ ]]></span>]]></update><update id="form1:in1"><Unable to render embedded object: File (in1" type="text" name="form1:in1" value="<) not found.[CDATA[ ]]>" />]]></update><update id="javax.faces.ViewState"><![CDATA[j_id29:j_id30]]></update></changes></partial-response

          Show
          Judy Guglielmin added a comment - responses to the same values input without ICEfaces:- "a" <partial-response><changes><update id="form1:out1">< Unable to render embedded object: File (out1">a</span>]]></update><update id="form1:in1"><) not found. [CDATA [<input id="form1:in1" type="text" name="form1:in1" value="a" />] ]></update><update id="javax.faces.ViewState"><![CDATA [j_id29:j_id30] ]></update></changes></partial-response> "]" <partial-response><changes><update id="form1:out1">< Unable to render embedded object: File (out1">]</span>]]></update><update id="form1:in1"><) not found. [CDATA [<input id="form1:in1" type="text" name="form1:in1" value="] " />]]></update><update id="javax.faces.ViewState"><![CDATA [j_id29:j_id30] ]></update></changes></partial-response> "<![CDATA[ ]]>" <partial-response><changes><update id="form1:out1">< Unable to render embedded object: File (out1"><) not found. [CDATA[ ]]></span>]]></update><update id="form1:in1">< Unable to render embedded object: File (in1" type="text" name="form1:in1" value="<) not found. [CDATA[ ]]>" />]]></update><update id="javax.faces.ViewState"><![CDATA [j_id29:j_id30] ]></update></changes></partial-response
          Hide
          Judy Guglielmin added a comment -

          As requested by Ted, I have updated based upon the jsf systests pertaining to this jira. Let me know if there is anything else I can provide for you. (these were tested using the test application and the browser. Curiously enough, some of the tests that pass in the browser don't pass with htmlunit. For example I get the following for the 'a' input:-
          Testcase: testCdataEscape1 took 0.237 sec
          [junit] FAILED
          [junit] form1:out1:- Expected ']]>', but received ''
          [junit] junit.framework.AssertionFailedError: form1:out1:- Expected ']]>', but received ''
          [junit] at com.sun.faces.htmlunit.AbstractTestCase.checkTrue(AbstractTestCase.java:419)
          [junit] at com.sun.faces.ajax.AjaxEchoTestCase.testCdataEscape1(AjaxEchoTestCase.java:154)

          yet it's fine when I do this in the browser. The last one that fails in the browser (CDATA...) also fails in htmlunit though.

          Show
          Judy Guglielmin added a comment - As requested by Ted, I have updated based upon the jsf systests pertaining to this jira. Let me know if there is anything else I can provide for you. (these were tested using the test application and the browser. Curiously enough, some of the tests that pass in the browser don't pass with htmlunit. For example I get the following for the 'a' input:- Testcase: testCdataEscape1 took 0.237 sec [junit] FAILED [junit] form1:out1:- Expected ']]>', but received '' [junit] junit.framework.AssertionFailedError: form1:out1:- Expected ']]>', but received '' [junit] at com.sun.faces.htmlunit.AbstractTestCase.checkTrue(AbstractTestCase.java:419) [junit] at com.sun.faces.ajax.AjaxEchoTestCase.testCdataEscape1(AjaxEchoTestCase.java:154) yet it's fine when I do this in the browser. The last one that fails in the browser (CDATA...) also fails in htmlunit though.
          Judy Guglielmin made changes -
          Assignee Judy Guglielmin [ judy.guglielmin ] Greg Dick [ greg.dick ]
          Hide
          Judy Guglielmin added a comment -

          note the results of ajaxEcho tests in the comments

          Show
          Judy Guglielmin added a comment - note the results of ajaxEcho tests in the comments
          Judy Guglielmin made changes -
          Link This issue blocks ICE-4950 [ ICE-4950 ]
          Hide
          Judy Guglielmin added a comment -

          Other tests of characters that do not pass:-
          "]]>" and "<!"

          Show
          Judy Guglielmin added a comment - Other tests of characters that do not pass:- "]]>" and "<!"
          Hide
          Greg Dick added a comment -

          This is a problem with escaping the CData termination sequence, but there are several facets to the problem.

          Keep in mind for the following problems that there are two modes of operation. The initial rendering mode when the output is HTML and the CData termination block has no special meaning and update mode when the updates are sent in XML where it obviously will terminate the update CData section.

          • For the purposes of the <h:outputText> component, the solution is to escape the '>' in all cases, thus the string ]]> becomes ]]> in all rendered text. This is appropriate for initial rendering in HTML as well as updates of outputText components written in updates (as well as mirrors what the native JSF components do)
          • There is a problem with the <h:inputText> component in ICEFaces, but only on the very first POSTBack. An input Text component displays its 'value' verbatim, so escaping the '>' char doesn't work and will show up as the literal string ]]> because it's rendered in HTML.

          Normally we don't render inputText components as part of an <update> block. This is accomplished by setting the POSTBack values into the OLD DOM so that they match the rendered values in the new DOM and thusly don't show up in the nodeDiff array. However, when we render the response from the first POSTback we see the following. What it shows is that some script has been added to the form offsetting each child by 1 basically. The upshot of this process is that the Form is added to the diff block, and this will render out all its children.

          Diff in node String value, oldNode: [#text: ], new Node: [#text: <script type='text/javascript'>ice.captureSubmit('form1');</script>], adding newNode
          [#text: <script type='text/javascript'>ice.captureSubmit('form1');</script>]
          Diff in Node Name, oldNode: #comment, new Node: #text, adding parent: [form: null]
          Diff in Node Name, oldNode: #text, new Node: #comment, adding parent: [form: null]
          Diff in Node Name, oldNode: span, new Node: #text, adding parent: [form: null]
          Diff in Node Name, oldNode: #text, new Node: span, adding parent: [form: null]
          Diff in Node Name, oldNode: br, new Node: #text, adding parent: [form: null]
          Diff in Node Name, oldNode: #text, new Node: br, adding parent: [form: null]
          Diff in Node Name, oldNode: input, new Node: #text, adding parent: [form: null]
          Diff in Node Name, oldNode: #text, new Node: input, adding parent: [form: null]
          Diff in Node Name, oldNode: #comment, new Node: #text, adding parent: [form: null]
          Diff in Node Name, oldNode: #text, new Node: #comment, adding parent: [form: null]
          Diff in Node Name, oldNode: br, new Node: #text, adding parent: [form: null]
          Diff in Node Name, oldNode: input, new Node: br, adding parent: [form: null]
          Diff in Node Name, oldNode: #text, new Node: input, adding parent: [form: null]
          Diff in Node Name, oldNode: br, new Node: #text, adding parent: [form: null]
          Diff in Node Name, oldNode: #text, new Node: br, adding parent: [form: null]
          Diff in Node Name, oldNode: #comment, new Node: #text, adding parent: [form: null]
          Diff in Node Name, oldNode: input, new Node: #comment, adding parent: [form: null]
          Diff in Node Name, oldNode: #text, new Node: input, adding parent: [form: null]
          Diff in Node Name, oldNode: br, new Node: #text, adding parent: [form: null]
          Diff in Node Name, oldNode: #text, new Node: br, adding parent: [form: null]
          Diff in Node Name, oldNode: #comment, new Node: #text, adding parent: [form: null]
          Diff in Node Name, oldNode: input, new Node: #comment, adding parent: [form: null]
          Diff in Node Name, oldNode: #text, new Node: input, adding parent: [form: null]
          Diff in Node Name, oldNode: #comment, new Node: #text, adding parent: [form: null]
          Diff in Node Name, oldNode: input, new Node: #comment, adding parent: [form: null]
          Diff in Node Id, oldNodeId: form1:reload, new NodeId: form1:_t18, adding parent: [form: null]
          Diff in Node Name, oldNode: #text, new Node: input, adding parent: [form: null]

          As a result of having the Form in the update, the following update is constructed:

          <partial-response><changes><update id="form1"><![CDATA[<form action="/escape/icefaces.jsf" enctype="application/x-www-form-urlencoded" id="form1" method="post" name="form1">
          <input name="form1" type="hidden" value="form1" />
          <script type='text/javascript'>ice.captureSubmit('form1');</script>
          Output: <span id="form1:out1">aaa]]>bbb</span> <br />
          Input: <input id="form1:in1" name="form1:in1" type="text" value="aaa]]>bbb" /> <br />
          <br />
          <input id="form1:reset" name="form1:reset" onclick="return resetpush(this, event);" type="submit" value="reset" />
          <input id="form1:_t18" name="form1:_t18" type="submit" value="send it in" /><input id="form1:reload" name="form1:reload" type="submit" value="reload" />
          </form>]]></update><update id="javax.faces.ViewState"><![CDATA[3863213446070469989:3513529411051212321]]></update></changes></partial-response>

          Here the output Text has been escaped properly, but the inputText causes a problem since this is now XML content. If we escape the '>', the escaped characters show up verbatim, if we don't escape the characters, it terminates the update CData block.

          Inputting ']]>' in an inputText in the first POSTback causes the bridge to dispose of the view and a reload to be performed, which leaves us in the position of being vulnerable to the problem repeatedly. However, if the first POSTback doesn't contain ]]>, for all subsequent requests the script block of the form never changes and the update block only contains the outputText string and the application works and supports ]]> properly.

          Show
          Greg Dick added a comment - This is a problem with escaping the CData termination sequence, but there are several facets to the problem. Keep in mind for the following problems that there are two modes of operation. The initial rendering mode when the output is HTML and the CData termination block has no special meaning and update mode when the updates are sent in XML where it obviously will terminate the update CData section. For the purposes of the <h:outputText> component, the solution is to escape the '>' in all cases, thus the string ]]> becomes ]]> in all rendered text. This is appropriate for initial rendering in HTML as well as updates of outputText components written in updates (as well as mirrors what the native JSF components do) There is a problem with the <h:inputText> component in ICEFaces, but only on the very first POSTBack. An input Text component displays its 'value' verbatim, so escaping the '>' char doesn't work and will show up as the literal string ]]> because it's rendered in HTML. Normally we don't render inputText components as part of an <update> block. This is accomplished by setting the POSTBack values into the OLD DOM so that they match the rendered values in the new DOM and thusly don't show up in the nodeDiff array. However, when we render the response from the first POSTback we see the following. What it shows is that some script has been added to the form offsetting each child by 1 basically. The upshot of this process is that the Form is added to the diff block, and this will render out all its children. Diff in node String value, oldNode: [#text: ] , new Node: [#text: <script type='text/javascript'>ice.captureSubmit('form1');</script>] , adding newNode [#text: <script type='text/javascript'>ice.captureSubmit('form1');</script>] Diff in Node Name, oldNode: #comment, new Node: #text, adding parent: [form: null] Diff in Node Name, oldNode: #text, new Node: #comment, adding parent: [form: null] Diff in Node Name, oldNode: span, new Node: #text, adding parent: [form: null] Diff in Node Name, oldNode: #text, new Node: span, adding parent: [form: null] Diff in Node Name, oldNode: br, new Node: #text, adding parent: [form: null] Diff in Node Name, oldNode: #text, new Node: br, adding parent: [form: null] Diff in Node Name, oldNode: input, new Node: #text, adding parent: [form: null] Diff in Node Name, oldNode: #text, new Node: input, adding parent: [form: null] Diff in Node Name, oldNode: #comment, new Node: #text, adding parent: [form: null] Diff in Node Name, oldNode: #text, new Node: #comment, adding parent: [form: null] Diff in Node Name, oldNode: br, new Node: #text, adding parent: [form: null] Diff in Node Name, oldNode: input, new Node: br, adding parent: [form: null] Diff in Node Name, oldNode: #text, new Node: input, adding parent: [form: null] Diff in Node Name, oldNode: br, new Node: #text, adding parent: [form: null] Diff in Node Name, oldNode: #text, new Node: br, adding parent: [form: null] Diff in Node Name, oldNode: #comment, new Node: #text, adding parent: [form: null] Diff in Node Name, oldNode: input, new Node: #comment, adding parent: [form: null] Diff in Node Name, oldNode: #text, new Node: input, adding parent: [form: null] Diff in Node Name, oldNode: br, new Node: #text, adding parent: [form: null] Diff in Node Name, oldNode: #text, new Node: br, adding parent: [form: null] Diff in Node Name, oldNode: #comment, new Node: #text, adding parent: [form: null] Diff in Node Name, oldNode: input, new Node: #comment, adding parent: [form: null] Diff in Node Name, oldNode: #text, new Node: input, adding parent: [form: null] Diff in Node Name, oldNode: #comment, new Node: #text, adding parent: [form: null] Diff in Node Name, oldNode: input, new Node: #comment, adding parent: [form: null] Diff in Node Id, oldNodeId: form1:reload, new NodeId: form1:_t18, adding parent: [form: null] Diff in Node Name, oldNode: #text, new Node: input, adding parent: [form: null] As a result of having the Form in the update, the following update is constructed: <partial-response><changes><update id="form1"><![CDATA[<form action="/escape/icefaces.jsf" enctype="application/x-www-form-urlencoded" id="form1" method="post" name="form1"> <input name="form1" type="hidden" value="form1" /> <script type='text/javascript'>ice.captureSubmit('form1');</script> Output: <span id="form1:out1">aaa]]>bbb</span> <br /> Input: <input id="form1:in1" name="form1:in1" type="text" value="aaa]]>bbb" /> <br /> <br /> <input id="form1:reset" name="form1:reset" onclick="return resetpush(this, event);" type="submit" value="reset" /> <input id="form1:_t18" name="form1:_t18" type="submit" value="send it in" /><input id="form1:reload" name="form1:reload" type="submit" value="reload" /> </form>]]></update><update id="javax.faces.ViewState"><![CDATA [3863213446070469989:3513529411051212321] ]></update></changes></partial-response> Here the output Text has been escaped properly, but the inputText causes a problem since this is now XML content. If we escape the '>', the escaped characters show up verbatim, if we don't escape the characters, it terminates the update CData block. Inputting ']]>' in an inputText in the first POSTback causes the bridge to dispose of the view and a reload to be performed, which leaves us in the position of being vulnerable to the problem repeatedly. However, if the first POSTback doesn't contain ]]>, for all subsequent requests the script block of the form never changes and the update block only contains the outputText string and the application works and supports ]]> properly.
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #21291 Thu Apr 22 09:33:20 MDT 2010 greg.dick ICE-3182 escape XML chars in rendered text, and more cases checked in attribute rendering
          Files Changed
          Commit graph MODIFY /icefaces/scratchpads/glimmer/core/src/main/java/org/icefaces/util/DOMUtils.java
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #21299 Fri Apr 23 09:42:13 MDT 2010 greg.dick ICE-3182 removed some stylesheet includes to simplify
          Files Changed
          Commit graph MODIFY /icefaces/scratchpads/glimmer/samples/test/ICE-3182/src/main/webapp/icefaces.xhtml
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #21334 Wed Apr 28 07:39:04 MDT 2010 greg.dick ICE-3182 changed the location of escaping code to be done at responseWriting time rather than during serialization
          Files Changed
          Commit graph MODIFY /icefaces/scratchpads/glimmer/core/src/main/java/org/icefaces/util/DOMUtils.java
          Commit graph MODIFY /icefaces/scratchpads/glimmer/core/src/main/java/org/icefaces/context/DOMResponseWriter.java
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #21345 Thu Apr 29 10:18:34 MDT 2010 greg.dick ICE-3182 check for presence of script or style
          Files Changed
          Commit graph MODIFY /icefaces/scratchpads/glimmer/core/src/main/java/org/icefaces/context/DOMResponseWriter.java
          Ken Fyten made changes -
          Link This issue blocks ICE-5551 [ ICE-5551 ]
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #21375 Fri May 07 11:17:53 MDT 2010 greg.dick ICE-3182 updated use of ScriptWriter
          Files Changed
          Commit graph MODIFY /icefaces/scratchpads/glimmer/core/src/main/java/org/icefaces/event/EnterKeySubmit.java
          Commit graph MODIFY /icefaces/scratchpads/glimmer/core/src/main/java/org/icefaces/event/ScriptWriter.java
          Commit graph MODIFY /icefaces/scratchpads/glimmer/core/src/main/java/org/icefaces/event/RedirectSubmit.java
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #21378 Fri May 07 14:32:38 MDT 2010 greg.dick ICE-3182 Added encodeEnd method to avoid adding span artifacts
          Files Changed
          Commit graph MODIFY /icefaces/scratchpads/glimmer/core/src/main/java/org/icefaces/event/ScriptWriter.java
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #21379 Fri May 07 14:38:49 MDT 2010 deryk.sinotte ICE-3182: fixed copy/paste type and optimize imports
          Files Changed
          Commit graph MODIFY /icefaces/scratchpads/glimmer/core/src/main/java/org/icefaces/event/EnterKeySubmit.java
          Commit graph MODIFY /icefaces/scratchpads/glimmer/core/src/main/java/org/icefaces/event/RedirectSubmit.java
          Hide
          Greg Dick added a comment -

          There was an issue with the event listeners simply adding the script to the document (which appended it to the end) on subsequent passes. This has been fixed so the first time full update is eliminated.

          We put the escaping behaviour into the writeText method as specified. The code now passes the Mojarra escaping tests.

          Show
          Greg Dick added a comment - There was an issue with the event listeners simply adding the script to the document (which appended it to the end) on subsequent passes. This has been fixed so the first time full update is eliminated. We put the escaping behaviour into the writeText method as specified. The code now passes the Mojarra escaping tests.
          Greg Dick made changes -
          Status Open [ 1 ] Resolved [ 5 ]
          Resolution Fixed [ 1 ]
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #21463 Mon May 24 16:09:53 MDT 2010 mircea.toma ICE-3182 Change dynamically added component to use ResponseWriter for generating HTML content instead of writing HTML content as escaped text.
          Files Changed
          Commit graph MODIFY /icefaces/scratchpads/glimmer/core/src/main/java/org/icefaces/event/BridgeSetup.java
          Commit graph MODIFY /icefaces/scratchpads/glimmer/compat/core/src/main/java/com/icesoft/faces/application/ExtrasSetup.java
          Commit graph MODIFY /icefaces/scratchpads/glimmer/compat/core/src/main/java/com/icesoft/faces/component/JavaScriptContextSetup.java
          Ken Fyten made changes -
          Fix Version/s 2.0.0 [ 10230 ]
          Ken Fyten made changes -
          Status Resolved [ 5 ] Closed [ 6 ]
          Assignee Priority P2

            People

            • Assignee:
              Greg Dick
              Reporter:
              Ted Goddard
            • Votes:
              1 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: