From 645beacd991379e19dc8fcb60a405045034628a9 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sat, 16 Jul 2022 23:44:10 +0200 Subject: [PATCH 01/12] [JENKINS-60866] Apply Stapler update for CSP-compliant st:bind --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 6b8d1b3c6246..6c36fd394689 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -40,7 +40,7 @@ THE SOFTWARE. 9.3 1.7.36 - 1685.v3b_5035c4ce05 + 1717.v8c67b_732b_55e 2.4.21 From fbb392e1a36b5a0b3268dbd58ff9f7df88b195bf Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sun, 17 Jul 2022 11:14:15 +0200 Subject: [PATCH 02/12] [JENKINS-60866] Make renderOnDemand CSP-compliant --- bom/pom.xml | 2 +- core/src/main/java/hudson/Functions.java | 7 +++++++ core/src/main/resources/lib/layout/renderOnDemand.jelly | 6 +++++- war/src/main/webapp/scripts/hudson-behavior.js | 8 +++++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index 6c36fd394689..5dddce20624f 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -40,7 +40,7 @@ THE SOFTWARE. 9.3 1.7.36 - 1717.v8c67b_732b_55e + 1721.v6298feb_6eb_8f 2.4.21 diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index 92b158a1efa6..1ec40c853f18 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -2167,6 +2167,13 @@ public static String createRenderOnDemandProxy(JellyContext context, String attr return Stapler.getCurrentRequest().createJavaScriptProxy(new RenderOnDemandClosure(context, attributesToCapture)); } + /** + * @since TODO + */ + public static StaplerRequest.RenderOnDemandParameters createRenderOnDemandProxyParameters(JellyContext context, String attributesToCapture) { + return Stapler.getCurrentRequest().createJavaScriptProxyParameters(new RenderOnDemandClosure(context, attributesToCapture)); + } + public static String getCurrentDescriptorByNameUrl() { return Descriptor.getCurrentDescriptorByNameUrl(); } diff --git a/core/src/main/resources/lib/layout/renderOnDemand.jelly b/core/src/main/resources/lib/layout/renderOnDemand.jelly index 029fb82d4cb8..6dba9e53b7ba 100644 --- a/core/src/main/resources/lib/layout/renderOnDemand.jelly +++ b/core/src/main/resources/lib/layout/renderOnDemand.jelly @@ -36,8 +36,12 @@ THE SOFTWARE. + render-on-demand ${attrs.clazz} - ${h.createRenderOnDemandProxy(context,attrs.capture)} + ${parameters.proxyMethod} + ${parameters.url} + ${parameters.crumb} + ${parameters.methodsString} diff --git a/war/src/main/webapp/scripts/hudson-behavior.js b/war/src/main/webapp/scripts/hudson-behavior.js index 01c7ac69028a..35abc734e106 100644 --- a/war/src/main/webapp/scripts/hudson-behavior.js +++ b/war/src/main/webapp/scripts/hudson-behavior.js @@ -790,7 +790,13 @@ function isInsideRemovable(e) { */ function renderOnDemand(e,callback,noBehaviour) { if (!e || !Element.hasClassName(e,"render-on-demand")) return; - var proxy = eval(e.getAttribute("proxy")); + + let proxyMethod = e.getAttribute('data-proxy-method'); + let proxyUrl = e.getAttribute('data-proxy-url'); + let proxyCrumb = e.getAttribute('data-proxy-crumb'); + let proxyMethods = e.getAttribute('data-proxy-args').split(","); + + var proxy = window[proxyMethod](proxyUrl, proxyCrumb, proxyMethods); proxy.render(function (t) { var contextTagName = e.parentNode.tagName; var c; From 9f675a440469884e3d750680f04b2e5327e30c0e Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sun, 17 Jul 2022 11:51:11 +0200 Subject: [PATCH 03/12] Thanks Spotless --- bom/pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 5dddce20624f..4af2f84cb41d 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -40,7 +40,8 @@ THE SOFTWARE. 9.3 1.7.36 - 1721.v6298feb_6eb_8f + + 1721.v6298feb_6eb_8f 2.4.21 From 60051b4113930e03821f76d2a660dcada835fd93 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sun, 17 Jul 2022 12:50:51 +0200 Subject: [PATCH 04/12] Make Stapler incrementals work --- war/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/war/pom.xml b/war/pom.xml index 1db05dc7b875..910133b0c2fc 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -177,10 +177,14 @@ THE SOFTWARE. 1.8 + org.jenkins-ci:commons-jelly org.jenkins-ci.main:cli org.jenkins-ci.main:jenkins-core org.jenkins-ci.main:websocket-jetty9 org.jenkins-ci.main:websocket-spi + org.kohsuke.stapler:stapler + org.kohsuke.stapler:stapler-groovy + org.kohsuke.stapler:stapler-jelly From ffd7c3694e520478ffe9c9abc4e6e3c5e7302532 Mon Sep 17 00:00:00 2001 From: Daniel Beck <1831569+daniel-beck@users.noreply.github.com> Date: Wed, 3 Aug 2022 12:35:27 +0200 Subject: [PATCH 05/12] Update Stapler to new incremental --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 4af2f84cb41d..97d1c946ec29 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -41,7 +41,7 @@ THE SOFTWARE. 9.3 1.7.36 - 1721.v6298feb_6eb_8f + 1727.vd9e6ea_2d80e0 2.4.21 From bd507661017e516a7c5c189e83c1c6de310cb334 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Fri, 11 Aug 2023 13:52:35 +0200 Subject: [PATCH 06/12] Fixup bad merge --- war/src/main/webapp/scripts/hudson-behavior.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/war/src/main/webapp/scripts/hudson-behavior.js b/war/src/main/webapp/scripts/hudson-behavior.js index 9183480ddd65..db72e96ce7e4 100644 --- a/war/src/main/webapp/scripts/hudson-behavior.js +++ b/war/src/main/webapp/scripts/hudson-behavior.js @@ -998,7 +998,7 @@ function isInsideRemovable(e) { * if specified, skip the application of behaviour rule. */ function renderOnDemand(e, callback, noBehaviour) { - if (!e || !Element.hasClassName(e, "render-on-demand")) { + if (!e || !e.classList.contains("render-on-demand")) { return; } From ced608e25c0772e97ebea74ca56359ee958d85ce Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Tue, 15 Aug 2023 21:36:39 +0200 Subject: [PATCH 07/12] Update Stapler, add test demonstrating st:bind working --- bom/pom.xml | 2 +- .../java/org/kohsuke/stapler/BindTest.java | 106 ++++++++++++++++++ .../BindTest/RootActionImpl/adjunct.js | 2 + .../BindTest/RootActionImpl/index.jelly | 10 ++ .../RootActionWithWellKnownURL/adjunct.js | 2 + .../RootActionWithWellKnownURL/index.jelly | 10 ++ 6 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 test/src/test/java/org/kohsuke/stapler/BindTest.java create mode 100644 test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/adjunct.js create mode 100644 test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/index.jelly create mode 100644 test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionWithWellKnownURL/adjunct.js create mode 100644 test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionWithWellKnownURL/index.jelly diff --git a/bom/pom.xml b/bom/pom.xml index 6a5d0edd0870..a2d47f14e42b 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -41,7 +41,7 @@ THE SOFTWARE. 9.5 2.0.7 - 1819.v7d73b_0b_a_cc5b_ + 1825.v7d53ff7c2fc5 2.4.21 diff --git a/test/src/test/java/org/kohsuke/stapler/BindTest.java b/test/src/test/java/org/kohsuke/stapler/BindTest.java new file mode 100644 index 000000000000..9eb7348781cf --- /dev/null +++ b/test/src/test/java/org/kohsuke/stapler/BindTest.java @@ -0,0 +1,106 @@ +package org.kohsuke.stapler; + +import static org.hamcrest.CoreMatchers.endsWith; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.startsWith; +import static org.hamcrest.MatcherAssert.assertThat; + +import hudson.ExtensionList; +import hudson.model.InvisibleAction; +import hudson.model.RootAction; +import java.util.Arrays; +import java.util.List; +import org.apache.commons.lang.StringUtils; +import org.htmlunit.Page; +import org.htmlunit.html.HtmlPage; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.TestExtension; +import org.kohsuke.stapler.bind.JavaScriptMethod; +import org.kohsuke.stapler.bind.WithWellKnownURL; + +@RunWith(Parameterized.class) +public class BindTest { + @Rule + public JenkinsRule j = new JenkinsRule(); + + @Parameterized.Parameters + public static List contexts() { + return Arrays.asList("/jenkins", ""); + } + + public BindTest(String contextPath) { + j.contextPath = contextPath; + } + + @Test + public void bindNormal() throws Exception { + final RootActionImpl root = ExtensionList.lookupSingleton(RootActionImpl.class); + try (JenkinsRule.WebClient wc = j.createWebClient()) { + final HtmlPage htmlPage = wc.goTo(root.getUrlName()); + final String scriptUrl = htmlPage.getElementsByTagName("script").stream().filter(it -> it.getAttribute("src").startsWith(j.contextPath + "/$stapler/bound/script" + j.contextPath + "/$stapler/bound/")).findFirst().orElseThrow().getAttribute("src"); + + final Page script = wc.goTo(StringUtils.removeStart(scriptUrl, j.contextPath + "/"), "application/javascript"); + final String content = script.getWebResponse().getContentAsString(); + assertThat(content, startsWith("varname = makeStaplerProxy('" + j.contextPath + "/$stapler/bound/")); + assertThat(content, endsWith("','test',['annotatedJsMethod1','byName1']);")); + } + assertThat(root.invocations, is(1)); + } + + @Test + public void bindWithWellKnownURL() throws Exception { + final RootActionWithWellKnownURL root = ExtensionList.lookupSingleton(RootActionWithWellKnownURL.class); + try (JenkinsRule.WebClient wc = j.createWebClient()) { + final HtmlPage htmlPage = wc.goTo(root.getUrlName()); + final String scriptUrl = htmlPage.getElementsByTagName("script").stream().filter(it -> it.getAttribute("src").startsWith(j.contextPath + "/$stapler/bound/script" + j.contextPath + "/theWellKnownRoot?")).findFirst().orElseThrow().getAttribute("src"); + + final Page script = wc.goTo(StringUtils.removeStart(scriptUrl, j.contextPath + "/"), "application/javascript"); + //?var=varname&methods='annotatedJsMethod1','byName1' + assertThat(script.getWebResponse().getContentAsString(), is("varname = makeStaplerProxy('" + j.contextPath + "/theWellKnownRoot','test',['annotatedJsMethod2','byName2']);")); + } + assertThat(root.invocations, is(1)); + } + + @TestExtension + public static class RootActionImpl extends InvisibleAction implements RootAction { + private int invocations; + + @Override + public String getUrlName() { + return "theRoot"; + } + + @JavaScriptMethod + public void annotatedJsMethod1(String foo) {} + + public void jsByName1() { + invocations++; + } + } + + @TestExtension + public static class RootActionWithWellKnownURL extends InvisibleAction implements RootAction, WithWellKnownURL { + private int invocations; + + @Override + public String getUrlName() { + return "theWellKnownRoot"; + } + + @Override + public String getWellKnownUrl() { + return "/" + getUrlName(); + } + + @JavaScriptMethod + public void annotatedJsMethod2(String foo) {} + + public void jsByName2() { + invocations++; + } + } +} diff --git a/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/adjunct.js b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/adjunct.js new file mode 100644 index 000000000000..952a9de74812 --- /dev/null +++ b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/adjunct.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line no-undef +varname.byName1(); diff --git a/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/index.jelly b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/index.jelly new file mode 100644 index 000000000000..1de10c5ac222 --- /dev/null +++ b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/index.jelly @@ -0,0 +1,10 @@ + + + + +

Root Action

+ + +
+
+
diff --git a/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionWithWellKnownURL/adjunct.js b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionWithWellKnownURL/adjunct.js new file mode 100644 index 000000000000..268b06ff66a4 --- /dev/null +++ b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionWithWellKnownURL/adjunct.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line no-undef +varname.byName2(); diff --git a/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionWithWellKnownURL/index.jelly b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionWithWellKnownURL/index.jelly new file mode 100644 index 000000000000..563805f4889c --- /dev/null +++ b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionWithWellKnownURL/index.jelly @@ -0,0 +1,10 @@ + + + + +

Root Action

+ + +
+
+
From b076c02867ec32647c958258daab8cef0ba14990 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Wed, 16 Aug 2023 12:57:45 +0200 Subject: [PATCH 08/12] Address review feedback --- bom/pom.xml | 2 +- core/src/main/java/hudson/Functions.java | 4 +++- core/src/main/resources/lib/layout/renderOnDemand.jelly | 2 +- test/src/test/java/org/kohsuke/stapler/BindTest.java | 1 - war/src/main/webapp/scripts/hudson-behavior.js | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index a2d47f14e42b..be28f756f769 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -41,7 +41,7 @@ THE SOFTWARE. 9.5 2.0.7 - 1825.v7d53ff7c2fc5 + 1827.v7b_c33e0cc853 2.4.21 diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index bad397f7b188..a9acf67fc177 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -2223,13 +2223,15 @@ public static boolean isWipeOutPermissionEnabled() { return SystemProperties.getBoolean("hudson.security.WipeOutPermission"); } + @Deprecated public static String createRenderOnDemandProxy(JellyContext context, String attributesToCapture) { return Stapler.getCurrentRequest().createJavaScriptProxy(new RenderOnDemandClosure(context, attributesToCapture)); } /** - * @since TODO + * Called from renderOnDemand.jelly to generate the parameters for the proxy object generation. */ + @Restricted(NoExternalUse.class) public static StaplerRequest.RenderOnDemandParameters createRenderOnDemandProxyParameters(JellyContext context, String attributesToCapture) { return Stapler.getCurrentRequest().createJavaScriptProxyParameters(new RenderOnDemandClosure(context, attributesToCapture)); } diff --git a/core/src/main/resources/lib/layout/renderOnDemand.jelly b/core/src/main/resources/lib/layout/renderOnDemand.jelly index 6dba9e53b7ba..dc2e2ecbde3a 100644 --- a/core/src/main/resources/lib/layout/renderOnDemand.jelly +++ b/core/src/main/resources/lib/layout/renderOnDemand.jelly @@ -42,6 +42,6 @@ THE SOFTWARE. ${parameters.proxyMethod} ${parameters.url} ${parameters.crumb} - ${parameters.methodsString} + ${parameters.urlNames} diff --git a/test/src/test/java/org/kohsuke/stapler/BindTest.java b/test/src/test/java/org/kohsuke/stapler/BindTest.java index 9eb7348781cf..613c02c5c1df 100644 --- a/test/src/test/java/org/kohsuke/stapler/BindTest.java +++ b/test/src/test/java/org/kohsuke/stapler/BindTest.java @@ -59,7 +59,6 @@ public void bindWithWellKnownURL() throws Exception { final String scriptUrl = htmlPage.getElementsByTagName("script").stream().filter(it -> it.getAttribute("src").startsWith(j.contextPath + "/$stapler/bound/script" + j.contextPath + "/theWellKnownRoot?")).findFirst().orElseThrow().getAttribute("src"); final Page script = wc.goTo(StringUtils.removeStart(scriptUrl, j.contextPath + "/"), "application/javascript"); - //?var=varname&methods='annotatedJsMethod1','byName1' assertThat(script.getWebResponse().getContentAsString(), is("varname = makeStaplerProxy('" + j.contextPath + "/theWellKnownRoot','test',['annotatedJsMethod2','byName2']);")); } assertThat(root.invocations, is(1)); diff --git a/war/src/main/webapp/scripts/hudson-behavior.js b/war/src/main/webapp/scripts/hudson-behavior.js index db72e96ce7e4..807db68af543 100644 --- a/war/src/main/webapp/scripts/hudson-behavior.js +++ b/war/src/main/webapp/scripts/hudson-behavior.js @@ -1005,9 +1005,9 @@ function renderOnDemand(e, callback, noBehaviour) { let proxyMethod = e.getAttribute("data-proxy-method"); let proxyUrl = e.getAttribute("data-proxy-url"); let proxyCrumb = e.getAttribute("data-proxy-crumb"); - let proxyMethods = e.getAttribute("data-proxy-args").split(","); + let proxyUrlNames = e.getAttribute("data-proxy-url-names").split(","); - var proxy = window[proxyMethod](proxyUrl, proxyCrumb, proxyMethods); + var proxy = window[proxyMethod](proxyUrl, proxyCrumb, proxyUrlNames); proxy.render(function (t) { var contextTagName = e.parentNode.tagName; var c; From f5c7a840b6612b56c09b5b1595f89d0b6be73c2b Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Mon, 21 Aug 2023 14:19:14 +0200 Subject: [PATCH 09/12] Add test for null bind, update Stapler --- bom/pom.xml | 2 +- .../java/org/kohsuke/stapler/BindTest.java | 22 +++++++++++++++++++ .../BindTest/RootActionImpl/null.jelly | 10 +++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/null.jelly diff --git a/bom/pom.xml b/bom/pom.xml index be28f756f769..ce84f7329a02 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -41,7 +41,7 @@ THE SOFTWARE. 9.5 2.0.7 - 1827.v7b_c33e0cc853 + 1828.v34d7e67885ea_ 2.4.21 diff --git a/test/src/test/java/org/kohsuke/stapler/BindTest.java b/test/src/test/java/org/kohsuke/stapler/BindTest.java index 613c02c5c1df..fbf589f654b9 100644 --- a/test/src/test/java/org/kohsuke/stapler/BindTest.java +++ b/test/src/test/java/org/kohsuke/stapler/BindTest.java @@ -1,9 +1,11 @@ package org.kohsuke.stapler; +import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.endsWith; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.startsWith; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertThrows; import hudson.ExtensionList; import hudson.model.InvisibleAction; @@ -12,6 +14,7 @@ import java.util.List; import org.apache.commons.lang.StringUtils; import org.htmlunit.Page; +import org.htmlunit.ScriptException; import org.htmlunit.html.HtmlPage; import org.junit.Rule; import org.junit.Test; @@ -64,6 +67,25 @@ public void bindWithWellKnownURL() throws Exception { assertThat(root.invocations, is(1)); } + @Test + public void bindNull() throws Exception { + final RootActionImpl root = ExtensionList.lookupSingleton(RootActionImpl.class); + try (JenkinsRule.WebClient wc = j.createWebClient()) { + final ScriptException exception = assertThrows(ScriptException.class, () -> wc.goTo(root.getUrlName() + "/null")); + assertThat(exception.getFailingLineNumber(), is(2)); + assertThat(exception.getFailingColumnNumber(), is(0)); + assertThat(exception.getMessage(), containsString("TypeError: Cannot call method \"byName1\" of null")); + + final HtmlPage htmlPage = exception.getPage(); + final String scriptUrl = htmlPage.getElementsByTagName("script").stream().filter(it -> it.getAttribute("src").equals(j.contextPath + "/$stapler/bound/script/null?var=varname")).findFirst().orElseThrow().getAttribute("src"); + + final Page script = wc.goTo(StringUtils.removeStart(scriptUrl, j.contextPath + "/"), "application/javascript"); + final String content = script.getWebResponse().getContentAsString(); + assertThat(content, is("varname = null;")); + } + assertThat(root.invocations, is(0)); + } + @TestExtension public static class RootActionImpl extends InvisibleAction implements RootAction { private int invocations; diff --git a/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/null.jelly b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/null.jelly new file mode 100644 index 000000000000..cb81f08c8de5 --- /dev/null +++ b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/null.jelly @@ -0,0 +1,10 @@ + + + + +

Root Action with null

+ + +
+
+
From 89271e7b1a81ca27f0fd42b1c70f46f23e61c798 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Mon, 21 Aug 2023 19:26:06 +0200 Subject: [PATCH 10/12] Checkstyle --- .../test/java/org/kohsuke/stapler/BindTest.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/test/src/test/java/org/kohsuke/stapler/BindTest.java b/test/src/test/java/org/kohsuke/stapler/BindTest.java index fbf589f654b9..749241ae60d8 100644 --- a/test/src/test/java/org/kohsuke/stapler/BindTest.java +++ b/test/src/test/java/org/kohsuke/stapler/BindTest.java @@ -44,7 +44,13 @@ public void bindNormal() throws Exception { final RootActionImpl root = ExtensionList.lookupSingleton(RootActionImpl.class); try (JenkinsRule.WebClient wc = j.createWebClient()) { final HtmlPage htmlPage = wc.goTo(root.getUrlName()); - final String scriptUrl = htmlPage.getElementsByTagName("script").stream().filter(it -> it.getAttribute("src").startsWith(j.contextPath + "/$stapler/bound/script" + j.contextPath + "/$stapler/bound/")).findFirst().orElseThrow().getAttribute("src"); + final String scriptUrl = htmlPage + .getElementsByTagName("script") + .stream() + .filter(it -> it.getAttribute("src").startsWith(j.contextPath + "/$stapler/bound/script" + j.contextPath + "/$stapler/bound/")) + .findFirst() + .orElseThrow() + .getAttribute("src"); final Page script = wc.goTo(StringUtils.removeStart(scriptUrl, j.contextPath + "/"), "application/javascript"); final String content = script.getWebResponse().getContentAsString(); @@ -59,7 +65,13 @@ public void bindWithWellKnownURL() throws Exception { final RootActionWithWellKnownURL root = ExtensionList.lookupSingleton(RootActionWithWellKnownURL.class); try (JenkinsRule.WebClient wc = j.createWebClient()) { final HtmlPage htmlPage = wc.goTo(root.getUrlName()); - final String scriptUrl = htmlPage.getElementsByTagName("script").stream().filter(it -> it.getAttribute("src").startsWith(j.contextPath + "/$stapler/bound/script" + j.contextPath + "/theWellKnownRoot?")).findFirst().orElseThrow().getAttribute("src"); + final String scriptUrl = htmlPage + .getElementsByTagName("script") + .stream() + .filter(it -> it.getAttribute("src").startsWith(j.contextPath + "/$stapler/bound/script" + j.contextPath + "/theWellKnownRoot?")) + .findFirst() + .orElseThrow() + .getAttribute("src"); final Page script = wc.goTo(StringUtils.removeStart(scriptUrl, j.contextPath + "/"), "application/javascript"); assertThat(script.getWebResponse().getContentAsString(), is("varname = makeStaplerProxy('" + j.contextPath + "/theWellKnownRoot','test',['annotatedJsMethod2','byName2']);")); From 1ff5257bd650dd66c3c1ae903f2e37403fe5d872 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Tue, 22 Aug 2023 22:58:45 +0200 Subject: [PATCH 11/12] More tests --- bom/pom.xml | 2 +- .../java/org/kohsuke/stapler/BindTest.java | 37 +++++++++++++++++++ .../BindTest/RootActionImpl/inline-null.jelly | 11 ++++++ .../BindTest/RootActionImpl/unsafe-var.jelly | 10 +++++ 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/inline-null.jelly create mode 100644 test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/unsafe-var.jelly diff --git a/bom/pom.xml b/bom/pom.xml index ce84f7329a02..271825802953 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -41,7 +41,7 @@ THE SOFTWARE. 9.5 2.0.7 - 1828.v34d7e67885ea_ + 1829.v16f23e39438b_ 2.4.21 diff --git a/test/src/test/java/org/kohsuke/stapler/BindTest.java b/test/src/test/java/org/kohsuke/stapler/BindTest.java index 749241ae60d8..5c32adf15a58 100644 --- a/test/src/test/java/org/kohsuke/stapler/BindTest.java +++ b/test/src/test/java/org/kohsuke/stapler/BindTest.java @@ -98,6 +98,43 @@ public void bindNull() throws Exception { assertThat(root.invocations, is(0)); } + @Test + public void bindUnsafe() throws Exception { + final RootActionImpl root = ExtensionList.lookupSingleton(RootActionImpl.class); + try (JenkinsRule.WebClient wc = j.createWebClient()) { + final HtmlPage htmlPage = wc.goTo(root.getUrlName() + "/unsafe-var"); + final String content = htmlPage + .getElementsByTagName("script") + .stream() + .filter(it -> it.getTextContent().contains("makeStaplerProxy")) + .findFirst() + .orElseThrow() + .getTextContent(); + + assertThat(content, startsWith("window['varname']=makeStaplerProxy('" + j.contextPath + "/$stapler/bound/")); + assertThat(content, endsWith("','test',['annotatedJsMethod1','byName1']);")); + } + assertThat(root.invocations, is(1)); + } + + @Test + public void bindInlineNull() throws Exception { + final RootActionImpl root = ExtensionList.lookupSingleton(RootActionImpl.class); + try (JenkinsRule.WebClient wc = j.createWebClient()) { + final HtmlPage htmlPage = wc.goTo(root.getUrlName() + "/inline-null"); + final String content = htmlPage + .getElementsByTagName("script") + .stream() + .filter(it -> it.getTextContent().contains("var inline")) + .findFirst() + .orElseThrow() + .getTextContent(); + + assertThat(content, containsString("var inline = null")); + } + assertThat(root.invocations, is(0)); + } + @TestExtension public static class RootActionImpl extends InvisibleAction implements RootAction { private int invocations; diff --git a/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/inline-null.jelly b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/inline-null.jelly new file mode 100644 index 000000000000..b99131131c1a --- /dev/null +++ b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/inline-null.jelly @@ -0,0 +1,11 @@ + + + + +

Root Action

+ +
+
+
diff --git a/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/unsafe-var.jelly b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/unsafe-var.jelly new file mode 100644 index 000000000000..ccb261682ba4 --- /dev/null +++ b/test/src/test/resources/org/kohsuke/stapler/BindTest/RootActionImpl/unsafe-var.jelly @@ -0,0 +1,10 @@ + + + + +

Root Action

+ + +
+
+
From dd8a0753f05949e8402fd5a6a5798f41272538eb Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Wed, 14 Feb 2024 12:10:32 +0100 Subject: [PATCH 12/12] Use released Stapler --- bom/pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index 4b8c48305ee2..ab691c2e3331 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -40,8 +40,7 @@ THE SOFTWARE. 9.6 2.0.12 - - 1867.v70a_fd882b_468 + 1839.ved17667b_a_eb_5 2.4.21