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

          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.
          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.
          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.
          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
          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.
          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.)
          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.
          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
          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.
          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.

            People

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

              Dates

              • Created:
                Updated:
                Resolved: