From d098314181ed3eb75a624ebff2756fd5ec2b9cd8 Mon Sep 17 00:00:00 2001 From: Allan Burdajewicz Date: Mon, 18 Dec 2023 11:12:54 +0100 Subject: [PATCH 1/7] [JENKINS-63355] Prevent NPEs when library name is not provided --- .../org/jenkinsci/plugins/workflow/libs/LibraryAdder.java | 4 ++++ .../plugins/workflow/libs/LibraryConfiguration.java | 6 +++++- .../org/jenkinsci/plugins/workflow/libs/LibraryStep.java | 5 ++++- .../plugins/workflow/libs/LibraryStep/config.jelly | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java b/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java index a57ba1e6..d4c9f45d 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java @@ -120,6 +120,10 @@ boolean kindTrusted = kind.isTrusted(); for (LibraryConfiguration cfg : kind.forJob(build.getParent(), libraryVersions)) { String name = cfg.getName(); + if (name == null) { + continue; + } + if (!cfg.isImplicit() && !libraryVersions.containsKey(name)) { continue; // not using this one at all } diff --git a/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryConfiguration.java b/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryConfiguration.java index bc7a67d6..9e264e90 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryConfiguration.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryConfiguration.java @@ -70,6 +70,7 @@ public class LibraryConfiguration extends AbstractDescribableImpl - + From 086558c1d4225b4cfe99523ae17cc3fccd1a450b Mon Sep 17 00:00:00 2001 From: Allan Burdajewicz Date: Mon, 18 Dec 2023 11:13:40 +0100 Subject: [PATCH 2/7] [JENKINS-63355] Add tests --- .../plugins/workflow/libs/LibraryStepTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryStepTest.java b/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryStepTest.java index 8e76a469..6dccb2ac 100644 --- a/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryStepTest.java +++ b/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryStepTest.java @@ -338,4 +338,19 @@ public class LibraryStepTest { r.assertLogContains("/lib/java", b); r.assertLogContains("/pipeline/java", b); } + + @Issue("JENKINS-63355") + @Test public void emptyNameLibrariesAreSkipped() throws Exception { + sampleRepo.init(); + sampleRepo.write("vars/x.groovy", "def call() {echo 'ran library'}"); + sampleRepo.git("add", "vars"); + sampleRepo.git("commit", "--message=init"); + GlobalLibraries.get().setLibraries(List.of( + new LibraryConfiguration("stuff", new SCMSourceRetriever(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", true))), + new LibraryConfiguration("", new SCMSourceRetriever(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", true))) + )); + WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); + p.setDefinition(new CpsFlowDefinition("library 'stuff@master'; x()", true)); + WorkflowRun b = r.buildAndAssertSuccess(p); + } } From 54cbd98548de9cd1758217042c3d71ad6925d321 Mon Sep 17 00:00:00 2001 From: Allan Burdajewicz Date: Wed, 20 Dec 2023 11:47:49 +0100 Subject: [PATCH 3/7] Revert "[JENKINS-63355] Add tests" This reverts commit 086558c1d4225b4cfe99523ae17cc3fccd1a450b. --- .../plugins/workflow/libs/LibraryStepTest.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryStepTest.java b/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryStepTest.java index 6dccb2ac..8e76a469 100644 --- a/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryStepTest.java +++ b/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryStepTest.java @@ -338,19 +338,4 @@ public class LibraryStepTest { r.assertLogContains("/lib/java", b); r.assertLogContains("/pipeline/java", b); } - - @Issue("JENKINS-63355") - @Test public void emptyNameLibrariesAreSkipped() throws Exception { - sampleRepo.init(); - sampleRepo.write("vars/x.groovy", "def call() {echo 'ran library'}"); - sampleRepo.git("add", "vars"); - sampleRepo.git("commit", "--message=init"); - GlobalLibraries.get().setLibraries(List.of( - new LibraryConfiguration("stuff", new SCMSourceRetriever(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", true))), - new LibraryConfiguration("", new SCMSourceRetriever(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", true))) - )); - WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); - p.setDefinition(new CpsFlowDefinition("library 'stuff@master'; x()", true)); - WorkflowRun b = r.buildAndAssertSuccess(p); - } } From 4c07978b40b5e70c221868c56bae649908b84775 Mon Sep 17 00:00:00 2001 From: Allan Burdajewicz Date: Wed, 20 Dec 2023 11:51:38 +0100 Subject: [PATCH 4/7] [JENKINS-63355] Prevent creating a library without name --- .../org/jenkinsci/plugins/workflow/libs/LibraryAdder.java | 3 --- .../plugins/workflow/libs/LibraryConfiguration.java | 5 ++++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java b/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java index d4c9f45d..ff997d82 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java @@ -120,9 +120,6 @@ boolean kindTrusted = kind.isTrusted(); for (LibraryConfiguration cfg : kind.forJob(build.getParent(), libraryVersions)) { String name = cfg.getName(); - if (name == null) { - continue; - } if (!cfg.isImplicit() && !libraryVersions.containsKey(name)) { continue; // not using this one at all diff --git a/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryConfiguration.java b/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryConfiguration.java index 9e264e90..f3d1cd1a 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryConfiguration.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryConfiguration.java @@ -63,6 +63,9 @@ public class LibraryConfiguration extends AbstractDescribableImpl Date: Wed, 20 Dec 2023 12:57:39 +0100 Subject: [PATCH 5/7] [JENKINS-63355] Add tests --- .../libs/LibraryConfigurationTest.java | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryConfigurationTest.java b/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryConfigurationTest.java index c91a4627..393485e5 100644 --- a/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryConfigurationTest.java +++ b/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryConfigurationTest.java @@ -24,7 +24,7 @@ package org.jenkinsci.plugins.workflow.libs; -import java.util.Collections; +import java.util.List; import hudson.plugins.git.GitSCM; import org.hamcrest.Matchers; @@ -69,29 +69,24 @@ public class LibraryConfigurationTest { } @Issue("JENKINS-59527") - @Test public void emptyStringDefaultVersionAndName() { - String libraryName = ""; - String defaultVersion = ""; - - LibraryConfiguration cfg = new LibraryConfiguration(libraryName, new SCMRetriever(new GitSCM("https://phony.jenkins.io/bar.git"))); - cfg.setDefaultVersion(defaultVersion); - - assertNull(cfg.getName()); + @Test public void emptyDefaultVersion() { + LibraryConfiguration cfg = new LibraryConfiguration("test", new SCMRetriever(new GitSCM("https://phony.jenkins.io/bar.git"))); + cfg.setDefaultVersion(""); assertNull(cfg.getDefaultVersion()); - } - - @Issue("JENKINS-59527") - @Test public void nullDefaultVersionAndName() { - String libraryName = null; - String defaultVersion = null; - - LibraryConfiguration cfg = new LibraryConfiguration(libraryName, new SCMRetriever(new GitSCM("https://phony.jenkins.io/bar.git"))); - cfg.setDefaultVersion(defaultVersion); - assertNull(cfg.getName()); + cfg = new LibraryConfiguration("test", new SCMRetriever(new GitSCM("https://phony.jenkins.io/bar.git"))); + cfg.setDefaultVersion(null); assertNull(cfg.getDefaultVersion()); } - + @Issue("JENKINS-63355") + @Test public void emptyNameCannotBeSaved() throws Exception { + assertThrows(IllegalArgumentException.class, () -> GlobalLibraries.get().setLibraries(List.of( + new LibraryConfiguration(null, new SCMRetriever(new GitSCM("https://phony.jenkins.io/bar.git"))) + ))); + assertThrows(IllegalArgumentException.class, () -> GlobalLibraries.get().setLibraries(List.of( + new LibraryConfiguration("", new SCMRetriever(new GitSCM("https://phony.jenkins.io/bar.git"))) + ))); + } } From 8900d5f8a52047b469a233e768ddba7ae48e49a7 Mon Sep 17 00:00:00 2001 From: Allan Burdajewicz Date: Wed, 20 Dec 2023 13:00:23 +0100 Subject: [PATCH 6/7] [JENKINS-63355] remove empty line --- .../java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java b/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java index ff997d82..a57ba1e6 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java @@ -120,7 +120,6 @@ boolean kindTrusted = kind.isTrusted(); for (LibraryConfiguration cfg : kind.forJob(build.getParent(), libraryVersions)) { String name = cfg.getName(); - if (!cfg.isImplicit() && !libraryVersions.containsKey(name)) { continue; // not using this one at all } From 082b29b8d0e12cb512e11f229c9080cc03b81286 Mon Sep 17 00:00:00 2001 From: Allan Burdajewicz Date: Wed, 21 May 2025 10:22:31 +1000 Subject: [PATCH 7/7] [JENKINS-63555] Add test for pre-existing null named libraries --- .../workflow/libs/LibraryStepTest.java | 29 ++++++++++++++++++ .../libs/LibraryStepTest/nullNamedLibrary.zip | Bin 0 -> 1143 bytes 2 files changed, 29 insertions(+) create mode 100644 src/test/resources/org/jenkinsci/plugins/workflow/libs/LibraryStepTest/nullNamedLibrary.zip diff --git a/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryStepTest.java b/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryStepTest.java index 8e76a469..58bf3120 100644 --- a/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryStepTest.java +++ b/src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryStepTest.java @@ -56,6 +56,7 @@ import org.jvnet.hudson.test.BuildWatcher; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.recipes.LocalData; @Issue("JENKINS-39450") public class LibraryStepTest { @@ -338,4 +339,32 @@ public class LibraryStepTest { r.assertLogContains("/lib/java", b); r.assertLogContains("/pipeline/java", b); } + + @LocalData + @Test public void nullNamedLibrary() throws Exception { + sampleRepo.init(); + sampleRepo.write("vars/x.groovy", "def call() {echo 'ran library'}"); + sampleRepo.git("add", "vars"); + sampleRepo.git("commit", "--message=init"); + GlobalLibraries.get().setLibraries(Collections.singletonList(new LibraryConfiguration("stuff", new SCMSourceRetriever(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", true))))); + + /* + LibraryConfiguration cfg = new LibraryConfiguration(null, new SCMSourceRetriever(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", true))); + cfg.setDefaultVersion("master"); + cfg.setImplicit(true); + + Folder f = r.jenkins.createProject(Folder.class, "f"); + f.addProperty(new FolderLibraries(Collections.singletonList(cfg))); + f.save(); + */ + + // local data have a folder 'f' with a library with no name (a null name) + Folder f = r.jenkins.getItemByFullName("f", Folder.class); + assertNotNull(f); + WorkflowJob p = f.createProject(WorkflowJob.class, "p"); + p.setDefinition(new CpsFlowDefinition("library 'stuff@master'; x()", true)); + WorkflowRun b = r.buildAndAssertSuccess(p); + r.assertLogContains("Found a library without name", r.buildAndAssertSuccess(p)); + r.assertLogContains("ran library", b); + } } diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/libs/LibraryStepTest/nullNamedLibrary.zip b/src/test/resources/org/jenkinsci/plugins/workflow/libs/LibraryStepTest/nullNamedLibrary.zip new file mode 100644 index 0000000000000000000000000000000000000000..fbb0c7bb28d6773e3573fa5dfccb159e0d65bfdc GIT binary patch literal 1143 zcmWIWW@h1H0D%K8Tcf}XD8b4g!;qDqRIDEw!pXqw&Z3*~5{OGHxEUB(zA`c}u!sN^ z2Eeu3xS?uihiOlP7$D59n*qXD3;-F#!SKp;Yt&}8_Up@;7#MQc85jf+1|;X_rDdk; zRpjP?-BQ7(n*qXTMlB7E&A(+JQu}_rLxzz5krY`2mC0GT*LhdQ-u(43Z_ex^Ym=34 zYd*dI{@H97pGC7;6n5Hum$_g4mU(Z5|I-J&J)%*%?)#qivn|-c*V;9G@$%!dKVHA+ zTHvts2d#A_S^wEsYgM!oZPI@nE`TV!Ieq)5s^UW`>%-8v|^1c76sh@uynXj+*`DRMn z>i9qBjlEXQ{bGKCw`IYc1HZx(8)RSX`F`=7!NVN;9`55-!A*O;4~zJ(Ykewpdw>0z z#ZQt&R!3wqf6tnG^U3rwC80eQ^2c{-SZ?$6Dwr^r*>#riRnB&SjXt}cfBM9#xtWhg zb?=A7HjnK=1rM3hjci=bzE)&&Utb>j$<|9s(5cma*OiCiF=>ixu7n;6;St-g&Fj?( zuj;oa{@=6qO8I_kzFXxHLyebJ{JLjfMjlxAu|N3C8(seo>rO}BF_E$FUjFLWMW!oP z0tA;@vAnFEY;;_{>ayR~X+^u{^Rcrj8DyN=AX6o`(*AJsV-HbpMF&r>uH|KlLPGpk zzn4FldHLA2Z16dKHcbOj68RQX2b1V_Ba-ygiEUBKSiHxJHoN