Before I file the issue, can you inspect the self-contained test case I created (see the attachment)? And please tell me what's the issue to be filed? The results are the following:
Escaping double quotes in the IFRAME HTML text execute [1022/211419.412220:INFO:CONSOLE(1)] "Uncaught SyntaxError: Invalid or unexpected token", source: var%20iframe%3Ddocument.createelement%28%22iframe%22%29%3Biframe.setattribute%28%22srcdoc%22%2C%22%3C%21doctype%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3Cp%20style%3D%5C%22vertical-align:middle;font-size:2em;\" ><img style=\"vertical-align:middle;height:50px;\" src=\"https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/ios10-weather-app-icon.png\" />Meteo</p></body></html>"); (1) executeAndWait [1022/211610.194334:INFO:CONSOLE(1)] "Uncaught SyntaxError: Invalid or unexpected token", source: %28function%28%29%7Bvar%20base%5Furl%3D%27https://www.codenameone.com/!cn1return/';function doCallback(val) { var url = BASE_URL + encodeURIComponent(JSON.stringify(val)); if (window.cefQuery) { window.cefQuery({request:'shouldNavigate:'+url, onSuccess: function(response){}, onFailure:function(error_code, error_message) { console.log(error_message)}});} else if (window.cn1application && window.cn1application.shouldNavigate) { window.cn1application.shouldNavigate(url) } else if (true) {window._cn1ready = window._cn1ready || []; window._cn1ready.push(function(){window.cn1application.shouldNavigate(url)});} else {window.location.href=url}} var result = {value:null, type:null, errorMessage:null, errorCode:0, callbackId:0};var callback = { onSucess: function(val) { this.onSuccess(val);}, onSuccess: function(val) { result.value = val; result.type = typeof(val); if (val !== null && typeof val === 'object') {result.value = val.toString();} doCallback(result);}, onError: function(message, code) { if (message instanceof Error) {result.errorMessage = message.message; result.errorCode = 0;} else {result.errorMessage = message; result.errorCode = code;} doCallback(result);}};try { var iframe=document.createElement("IFRAME");iframe.setAttribute("srcdoc","<!DOCTYPE html><html><head></head><body><p style=\"vertical-align:middle;font-size:2em;\" ><img style=\"vertical-align:middle;height:50px;\" src=\"https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/ios10-weather-app-icon.png\" />Meteo</p></body></html>");} catch (e) {try {callback.onError(e.message, 0);} catch (e2) {callback.onError('Unknown error', 0);}}})(); (1) Without escaping double quotes in the IFRAME HTML text execute [1022/212307.710510:INFO:CONSOLE(1)] "Uncaught SyntaxError: Invalid or unexpected token", source: var%20iframe%3Ddocument.createelement%28%22iframe%22%29%3Biframe.setattribute%28%22srcdoc%22%2C%22%3C%21doctype%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3Cp%20style%3D%22vertical-align:middle;font-size:2em;" ><img style="vertical-align:middle;height:50px;" src="https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/ios10-weather-app-icon.png" />Meteo</p></body></html>"); (1) executeAndWait [1022/212214.198521:INFO:CONSOLE(1)] "Uncaught SyntaxError: Invalid or unexpected token", source: %28function%28%29%7Bvar%20base%5Furl%3D%27https://www.codenameone.com/!cn1return/';function doCallback(val) { var url = BASE_URL + encodeURIComponent(JSON.stringify(val)); if (window.cefQuery) { window.cefQuery({request:'shouldNavigate:'+url, onSuccess: function(response){}, onFailure:function(error_code, error_message) { console.log(error_message)}});} else if (window.cn1application && window.cn1application.shouldNavigate) { window.cn1application.shouldNavigate(url) } else if (true) {window._cn1ready = window._cn1ready || []; window._cn1ready.push(function(){window.cn1application.shouldNavigate(url)});} else {window.location.href=url}} var result = {value:null, type:null, errorMessage:null, errorCode:0, callbackId:1};var callback = { onSucess: function(val) { this.onSuccess(val);}, onSuccess: function(val) { result.value = val; result.type = typeof(val); if (val !== null && typeof val === 'object') {result.value = val.toString();} doCallback(result);}, onError: function(message, code) { if (message instanceof Error) {result.errorMessage = message.message; result.errorCode = 0;} else {result.errorMessage = message; result.errorCode = code;} doCallback(result);}};try { var iframe=document.createElement("IFRAME");iframe.setAttribute("srcdoc","<!DOCTYPE html><html><head></head><body><p style="vertical-align:middle;font-size:2em;" ><img style="vertical-align:middle;height:50px;" src="https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/ios10-weather-app-icon.png" />Meteo</p></body></html>");} catch (e) {try {callback.onError(e.message, 0);} catch (e2) {callback.onError('Unknown error', 0);}}})(); (1) Il giorno giovedì 22 ottobre 2020 alle 17:52:47 UTC+2 Steve Hannah ha scritto: > Create a self-contained test cast and file an issue in the issue tracker. > > On Thu, Oct 22, 2020 at 8:34 AM 'P5music' via CodenameOne Discussions < > [email protected]> wrote: > >> I tried your suggestion but it does not work, as expected if you consider >> that what is going to be executed is something that has quotes inside >> quotes, like >> setAttribute("srcdoc","<HTML><div style="some styling here" >> ></DIV></HTML>"); >> >> that line is injected so it has to be >> "setAttribute(\"srcdoc\",\"<HTML><div style="some styling here" >> ></DIV></HTML>\");" >> This is what goes inside the function, >> >> but in the log you can see for example: >> >> iframe.setAttribute("srcdoc","<!DOCTYPE html><html><head></head><body><p >> style="vertical-align:middle;font-size:2em;" >............. >> when deep quotes are not escaped how you suggested. >> >> While just applying the escaping of double quotes I get in the log >> >> var%20div%3Ddocument.createelement%28%27div%27%29%3Bdiv.addeventlistener%28%27mouse >> >> the error seems to be anticipated because that string continues and >> reaches to (the same code position even it belongs to a different IFRAME): >> >> iframe.setattribute%28%22srcdoc%22%2C%22%3C%21doctype%20html%3E%3Chtml%3E%3Chead%3E%3Clink%20href%3D%5C%22https:// >> that is clearly different >> and this change happens just if I escape instead of not escaping as you >> suggested. >> >> >> Il giorno giovedì 22 ottobre 2020 alle 16:31:11 UTC+2 Steve Hannah ha >> scritto: >> >>> Don't escape the quotes. >>> >>> On Thu, Oct 22, 2020 at 7:29 AM 'P5music' via CodenameOne Discussions < >>> [email protected]> wrote: >>> >>>> I am testing the two variants. >>>> >>>> If I use the original variant executeAndWait I get what is the original >>>> error of this thread. >>>> >>>> If I use the execute variant I get the new error and apparent double >>>> encoding. >>>> >>>> I am not applying any encoding. I just escape the quotes (in both >>>> cases): >>>> String htmlText=originalHtml.replace("\"","\\\""); >>>> It has be done because I have to inject the HTML into the srcdoc >>>> attribute of the IFRAMEs. >>>> >>>> >>>> Il giorno giovedì 22 ottobre 2020 alle 16:20:50 UTC+2 Steve Hannah ha >>>> scritto: >>>> >>>>> Did you already pass that string through your own encoding/escaping? >>>>> If so, you may have some double-encoding going on. >>>>> >>>>> On Thu, Oct 22, 2020 at 7:08 AM 'P5music' via CodenameOne Discussions < >>>>> [email protected]> wrote: >>>>> >>>>>> This variant seems to be encoding all text. >>>>>> [1022/154808.805601:INFO:CONSOLE(1)] "Uncaught SyntaxError: Invalid >>>>>> or unexpected token", source: >>>>>> var%20div%3Ddocument.createelement%28%27div%27%29%3Bdiv.addeventlistener%28%27mouse..... >>>>>> >>>>>> This just a snippet of what is being done. I think that the HTML was >>>>>> encoded, including the surrounding Javascript (I see it in Chrome debug >>>>>> console). >>>>>> What's wrong? >>>>>> Il giorno giovedì 22 ottobre 2020 alle 15:18:52 UTC+2 Steve Hannah ha >>>>>> scritto: >>>>>> >>>>>>> There is an executeAndWait() variant that takes parameters. >>>>>>> >>>>>>> https://www.codenameone.com/javadoc/com/codename1/ui/BrowserComponent.html#executeAndWait-java.lang.String-java.lang.Object...- >>>>>>> >>>>>>> There are many variants listed in the javadocs. One for every >>>>>>> occasion. >>>>>>> >>>>>>> On Thu, Oct 22, 2020 at 6:10 AM 'P5music' via CodenameOne >>>>>>> Discussions <[email protected]> wrote: >>>>>>> >>>>>>>> I need the "wait" part too, is it possible to properly encode the >>>>>>>> raw text with a method? >>>>>>>> So I can keep using the executeAndWait variant? >>>>>>>> >>>>>>>> Il giorno giovedì 22 ottobre 2020 alle 14:50:54 UTC+2 Steve Hannah >>>>>>>> ha scritto: >>>>>>>> >>>>>>>>> I see. It isn't the DOCTYPE it has complaining about. It is that >>>>>>>>> you are placing raw text. You can't have new lines. >>>>>>>>> >>>>>>>>> If you want to inject arbitrary strings you should use the >>>>>>>>> execute(String js, Object[] params) variant: >>>>>>>>> >>>>>>>>> https://www.codenameone.com/javadoc/com/codename1/ui/BrowserComponent.html#execute-java.lang.String-java.lang.Object:A- >>>>>>>>> >>>>>>>>> E.g. myBrowserComponent.execute("...iframe.setAttribute('srcdoc', >>>>>>>>> ${0});...", new Object[]{htmlText}); >>>>>>>>> >>>>>>>>> That will properly encode the htmlText (e.g. escaping new lines >>>>>>>>> and other problematic characters). >>>>>>>>> >>>>>>>>> On Thu, Oct 22, 2020 at 5:36 AM 'P5music' via CodenameOne >>>>>>>>> Discussions <[email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hello, >>>>>>>>>> The injected HTML is not under my control, it is a string. If it >>>>>>>>>> doesn't like '<!DOCTYPE as a single string, it also could be not >>>>>>>>>> liking >>>>>>>>>> other things. >>>>>>>>>> In the provided code above it seems that it is written that way >>>>>>>>>> but it is a string >>>>>>>>>> created this way: >>>>>>>>>> " ... iframe.setAttribute(\"srcdoc\",\""+htmlText+"\");" >>>>>>>>>> Also, as you can see double-quotes " have been replaced by single >>>>>>>>>> quotes ' by the executeAndWait method. >>>>>>>>>> >>>>>>>>>> Il giorno giovedì 22 ottobre 2020 alle 13:46:25 UTC+2 Steve >>>>>>>>>> Hannah ha scritto: >>>>>>>>>> >>>>>>>>>>> Perhaps it doesn't like the doctype tag. Try splitting it up. >>>>>>>>>>> E.g. >>>>>>>>>>> >>>>>>>>>>> iframe.setAttribute('srcdoc', '<'+'!DOCTYPE html>...'); >>>>>>>>>>> >>>>>>>>>>> On Thu, Oct 22, 2020 at 4:26 AM 'P5music' via CodenameOne >>>>>>>>>>> Discussions <[email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> In my CodenameOne app some Javascript code is injected to >>>>>>>>>>>> create a DOM, made of IFRAMES with HTML code inside. >>>>>>>>>>>> The HTML code is correct but I am debugging in Chrome and I see >>>>>>>>>>>> that when the HTML code starts an error is detected (the error is >>>>>>>>>>>> also in >>>>>>>>>>>> the IntelliJ IDEA console): >>>>>>>>>>>> >>>>>>>>>>>> The following text is the function that is made from the >>>>>>>>>>>> executeAndWait method: >>>>>>>>>>>> >>>>>>>>>>>> (function(){var BASE_URL=' >>>>>>>>>>>> https://www.codenameone.com/!cn1return/';function >>>>>>>>>>>> doCallback(val) { var url = BASE_URL + >>>>>>>>>>>> encodeURIComponent(JSON.stringify(val)); if (window.cefQuery) { >>>>>>>>>>>> window.cefQuery({request:'shouldNavigate:'+url, onSuccess: >>>>>>>>>>>> function(response){}, onFailure:function(error_code, >>>>>>>>>>>> error_message) { >>>>>>>>>>>> console.log(error_message)}});} else if (window.cn1application && >>>>>>>>>>>> window.cn1application.shouldNavigate) { >>>>>>>>>>>> window.cn1application.shouldNavigate(url) } else if (true) >>>>>>>>>>>> {window._cn1ready = window._cn1ready || []; >>>>>>>>>>>> window._cn1ready.push(function(){window.cn1application.shouldNavigate(url)});} >>>>>>>>>>>> >>>>>>>>>>>> else {window.location.href=url}} var result = {value:null, >>>>>>>>>>>> type:null, >>>>>>>>>>>> errorMessage:null, errorCode:0, callbackId:3};var callback = { >>>>>>>>>>>> onSucess: >>>>>>>>>>>> function(val) { this.onSuccess(val);}, onSuccess: function(val) >>>>>>>>>>>> { >>>>>>>>>>>> result.value = val; result.type = typeof(val); if (val !== null && >>>>>>>>>>>> typeof >>>>>>>>>>>> val === 'object') {result.value = val.toString();} >>>>>>>>>>>> doCallback(result);}, >>>>>>>>>>>> onError: function(message, code) { if (message instanceof Error) >>>>>>>>>>>> {result.errorMessage = message.message; result.errorCode = 0;} >>>>>>>>>>>> else >>>>>>>>>>>> {result.errorMessage = message; result.errorCode = code;} >>>>>>>>>>>> doCallback(result);}};try { var >>>>>>>>>>>> div=document.createElement('DIV');div.addEventListener('mousedown', >>>>>>>>>>>> >>>>>>>>>>>> function (event) >>>>>>>>>>>> {callMouseDown(div.getAttribute("id"));});div.addEventListener('mouseup', >>>>>>>>>>>> >>>>>>>>>>>> function (event) {callMouseUp(div.getAttribute("id"));});var >>>>>>>>>>>> iframe=document.createElement("IFRAME");iframe.style.zIndex="0";iframe.style.pointerEvents="none";div.style.position="relative"; >>>>>>>>>>>> div.id="0";iframe.setAttribute("scrolling","no");iframe.setAttribute("frameborder","no");iframe.setAttribute("noresize","noresize");iframe.setAttribute("height","100"); >>>>>>>>>>>> >>>>>>>>>>>> iframe.innerText="FALLBACK";iframe.setAttribute("srcdoc","<!DOCTYPE >>>>>>>>>>>> html> >>>>>>>>>>>> >>>>>>>>>>>> I did not paste all the function body. I stopped when the first >>>>>>>>>>>> HTML code begins for the first IFRAME and the error is there. >>>>>>>>>>>> As you can see in the attached image the red error starts at >>>>>>>>>>>> the comma (Uncaught SyntaxError: Invalid or unexpected token). >>>>>>>>>>>> >>>>>>>>>>>> (The HTML code is a text with other quotes inside as it is in >>>>>>>>>>>> normal HTML but it is correctly escaped) >>>>>>>>>>>> >>>>>>>>>>>> Can you help me? Do you see something? Could this be caused by >>>>>>>>>>>> the calling function? >>>>>>>>>>>> Thanks in advance >>>>>>>>>>>> Regards >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> You received this message because you are subscribed to the >>>>>>>>>>>> Google Groups "CodenameOne Discussions" group. >>>>>>>>>>>> To unsubscribe from this group and stop receiving emails from >>>>>>>>>>>> it, send an email to [email protected]. >>>>>>>>>>>> To view this discussion on the web visit >>>>>>>>>>>> https://groups.google.com/d/msgid/codenameone-discussions/42678b68-78f9-40fa-adb1-7f4740b9796fn%40googlegroups.com >>>>>>>>>>>> >>>>>>>>>>>> <https://groups.google.com/d/msgid/codenameone-discussions/42678b68-78f9-40fa-adb1-7f4740b9796fn%40googlegroups.com?utm_medium=email&utm_source=footer> >>>>>>>>>>>> . >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Steve Hannah >>>>>>>>>>> Software Developer >>>>>>>>>>> Codename One >>>>>>>>>>> http://www.codenameone.com >>>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> You received this message because you are subscribed to the >>>>>>>>>> Google Groups "CodenameOne Discussions" group. >>>>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>>>> send an email to [email protected]. >>>>>>>>>> >>>>>>>>> To view this discussion on the web visit >>>>>>>>>> https://groups.google.com/d/msgid/codenameone-discussions/7bf62f74-3642-46d9-b446-9c2bc6aabe6en%40googlegroups.com >>>>>>>>>> >>>>>>>>>> <https://groups.google.com/d/msgid/codenameone-discussions/7bf62f74-3642-46d9-b446-9c2bc6aabe6en%40googlegroups.com?utm_medium=email&utm_source=footer> >>>>>>>>>> . >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Steve Hannah >>>>>>>>> Software Developer >>>>>>>>> Codename One >>>>>>>>> http://www.codenameone.com >>>>>>>>> >>>>>>>> -- >>>>>>>> You received this message because you are subscribed to the Google >>>>>>>> Groups "CodenameOne Discussions" group. >>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>> send an email to [email protected]. >>>>>>>> >>>>>>> To view this discussion on the web visit >>>>>>>> https://groups.google.com/d/msgid/codenameone-discussions/da7d4cbf-62fd-4503-9680-2f2a16112ed3n%40googlegroups.com >>>>>>>> >>>>>>>> <https://groups.google.com/d/msgid/codenameone-discussions/da7d4cbf-62fd-4503-9680-2f2a16112ed3n%40googlegroups.com?utm_medium=email&utm_source=footer> >>>>>>>> . >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Steve Hannah >>>>>>> Software Developer >>>>>>> Codename One >>>>>>> http://www.codenameone.com >>>>>>> >>>>>> -- >>>>>> You received this message because you are subscribed to the Google >>>>>> Groups "CodenameOne Discussions" group. >>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>> send an email to [email protected]. >>>>>> >>>>> To view this discussion on the web visit >>>>>> https://groups.google.com/d/msgid/codenameone-discussions/a400a0f3-ba0d-482b-b690-3c12e1d76ff4n%40googlegroups.com >>>>>> >>>>>> <https://groups.google.com/d/msgid/codenameone-discussions/a400a0f3-ba0d-482b-b690-3c12e1d76ff4n%40googlegroups.com?utm_medium=email&utm_source=footer> >>>>>> . >>>>>> >>>>> >>>>> >>>>> -- >>>>> Steve Hannah >>>>> Software Developer >>>>> Codename One >>>>> http://www.codenameone.com >>>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "CodenameOne Discussions" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to [email protected]. >>>> >>> To view this discussion on the web visit >>>> https://groups.google.com/d/msgid/codenameone-discussions/c22c8ec5-721a-485a-8dc3-54e55238017fn%40googlegroups.com >>>> >>>> <https://groups.google.com/d/msgid/codenameone-discussions/c22c8ec5-721a-485a-8dc3-54e55238017fn%40googlegroups.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>> >>> >>> -- >>> Steve Hannah >>> Software Developer >>> Codename One >>> http://www.codenameone.com >>> >> -- >> You received this message because you are subscribed to the Google Groups >> "CodenameOne Discussions" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> > To view this discussion on the web visit >> https://groups.google.com/d/msgid/codenameone-discussions/8b4fe010-4c96-4974-aab6-786719e1dd98n%40googlegroups.com >> >> <https://groups.google.com/d/msgid/codenameone-discussions/8b4fe010-4c96-4974-aab6-786719e1dd98n%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> > > > -- > Steve Hannah > Software Developer > Codename One > http://www.codenameone.com > -- You received this message because you are subscribed to the Google Groups "CodenameOne Discussions" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/codenameone-discussions/a380dabc-3681-4c15-8bcc-d21e9bab6bb3n%40googlegroups.com.
package com.codename1.JSInjectionUserCase; import static com.codename1.ui.CN.*; import com.codename1.ui.*; import com.codename1.ui.events.ActionEvent; import com.codename1.ui.events.ActionListener; import com.codename1.ui.plaf.UIManager; import com.codename1.ui.util.Resources; import com.codename1.io.Log; import java.io.IOException; import com.codename1.ui.layouts.BoxLayout; import com.codename1.io.NetworkEvent; /** * This file was generated by <a href="https://www.codenameone.com/">Codename One</a> for the purpose * of building native mobile applications using Java. */ public class MyApplication { private Form current; private Resources theme; public void init(Object context) { // use two network threads instead of one updateNetworkThreadCount(2); theme = UIManager.initFirstTheme("/theme"); // Enable Toolbar on all Forms by default Toolbar.setGlobalToolbar(true); // Pro only feature Log.bindCrashProtection(true); addNetworkErrorListener(err -> { // prevent the event from propagating err.consume(); if(err.getError() != null) { Log.e(err.getError()); } Log.sendLogAsync(); Dialog.show("Connection Error", "There was a networking error in the connection to " + err.getConnectionRequest().getUrl(), "OK", null); }); } public void start() { if(current != null){ current.show(); return; } Form hi = new Form("Hi World", BoxLayout.y()); hi.add(new Label("Hi World")); BrowserComponent bc=new BrowserComponent(); bc.addWebEventListener("onLoad", new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { String JSCommand=createIFrameHtmlJString(generatedSampleHTML()); bc.execute(JSCommand); //bc.executeAndWait(JSCommand); } }); bc.setPage("<HTML><BODY style=\"display:flex;flex-direction:column;\" >"+ "</BODY></HTML>",""); hi.add(bc); hi.show(); } public void stop() { current = getCurrentForm(); if(current instanceof Dialog) { ((Dialog)current).dispose(); current = getCurrentForm(); } } public void destroy() { } private String createIFrameHtmlJString(String originalHTML) { String htmlText=originalHTML.replace("\"","\\\""); //String htmlText=originalHTML; String result= "var iframe=document.createElement(\"IFRAME\");iframe.setAttribute(\"srcdoc\",\"" + htmlText+ "\");"; return result; } private String generatedSampleHTML() { return "<!DOCTYPE html>\n" + "<html><head></head>\n" + "<body>\n"+ "<p style=\"vertical-align:middle;font-size:2em;\" >\n"+ "<img style=\"vertical-align:middle;height:50px;\" src=\"https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/ios10-weather-app-icon.png\" />\n"+ "Meteo\n"+ "</p></body></html>"; } }
