Skip to content

Commit aafc25d

Browse files
authored
Merge pull request #6 from jglick/className-JENKINS-68544
[JENKINS-68544] `\Q…\E` unsafe if input might contain `\E`
2 parents 3a7f422 + d8d6810 commit aafc25d

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryAdder.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import java.util.logging.Logger;
5050
import edu.umd.cs.findbugs.annotations.CheckForNull;
5151
import edu.umd.cs.findbugs.annotations.NonNull;
52+
import java.util.regex.Pattern;
5253
import org.apache.commons.io.IOUtils;
5354
import org.jenkinsci.plugins.workflow.cps.CpsFlowExecution;
5455
import org.jenkinsci.plugins.workflow.cps.GlobalVariable;
@@ -322,7 +323,7 @@ private static String readResource(FilePath file, @CheckForNull String encoding)
322323
continue;
323324
}
324325
for (FilePath groovy : root.list("**/*.groovy")) {
325-
String clazz = groovy.getRemote().replaceFirst("^\\Q" + root.getRemote() + "\\E[/\\\\](.+)[.]groovy", "$1").replace('/', '.').replace('\\', '.');
326+
String clazz = className(groovy.getRemote(), root.getRemote());
326327
scripts.put(clazz, groovy.readToString()); // TODO no idea what encoding the Groovy compiler uses
327328
}
328329
}
@@ -335,6 +336,10 @@ private static String readResource(FilePath file, @CheckForNull String encoding)
335336
return scripts;
336337
}
337338

339+
static String className(String groovy, String root) {
340+
return groovy.replaceFirst("^" + Pattern.quote(root) + "[/\\\\](.+)[.]groovy", "$1").replace('/', '.').replace('\\', '.');
341+
}
342+
338343
}
339344

340345
@Extension public static class Copier extends FlowCopier.ByRun {

src/test/java/org/jenkinsci/plugins/workflow/libs/LibraryAdderTest.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,10 @@
3030
import hudson.model.Result;
3131
import hudson.plugins.git.BranchSpec;
3232
import hudson.plugins.git.GitSCM;
33-
import hudson.plugins.git.SubmoduleConfig;
3433
import hudson.plugins.git.UserRemoteConfig;
35-
import hudson.plugins.git.extensions.GitSCMExtension;
36-
import hudson.slaves.WorkspaceList;
37-
import hudson.scm.SubversionSCM;
3834
import hudson.scm.ChangeLogSet;
35+
import hudson.scm.SubversionSCM;
36+
import hudson.slaves.WorkspaceList;
3937
import java.util.Collection;
4038
import java.util.Collections;
4139
import java.util.Iterator;
@@ -45,25 +43,28 @@
4543
import jenkins.plugins.git.GitSampleRepoRule;
4644
import jenkins.scm.impl.subversion.SubversionSCMSource;
4745
import jenkins.scm.impl.subversion.SubversionSampleRepoRule;
46+
import static org.hamcrest.MatcherAssert.assertThat;
47+
import static org.hamcrest.Matchers.is;
48+
import static org.hamcrest.Matchers.nullValue;
4849
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
4950
import org.jenkinsci.plugins.workflow.cps.GlobalVariable;
5051
import org.jenkinsci.plugins.workflow.cps.global.GrapeTest;
5152
import org.jenkinsci.plugins.workflow.cps.global.UserDefinedGlobalVariable;
5253
import org.jenkinsci.plugins.workflow.cps.replay.ReplayAction;
5354
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
5455
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
55-
import static org.junit.Assert.*;
56+
import static org.junit.Assert.assertEquals;
57+
import static org.junit.Assert.assertNotNull;
5658
import org.junit.ClassRule;
57-
import org.junit.Test;
5859
import org.junit.Rule;
60+
import org.junit.Test;
5961
import org.jvnet.hudson.test.BuildWatcher;
6062
import org.jvnet.hudson.test.Issue;
6163
import org.jvnet.hudson.test.JenkinsRule;
6264
import org.jvnet.hudson.test.TestExtension;
65+
import org.jvnet.hudson.test.WithoutJenkins;
6366
import org.jvnet.hudson.test.recipes.LocalData;
6467

65-
import static org.hamcrest.Matchers.nullValue;
66-
6768
public class LibraryAdderTest {
6869

6970
@ClassRule public static BuildWatcher buildWatcher = new BuildWatcher();
@@ -103,7 +104,7 @@ public class LibraryAdderTest {
103104
new SCMRetriever(
104105
new GitSCM(Collections.singletonList(new UserRemoteConfig(sampleRepo.fileUrl(), null, null, null)),
105106
Collections.singletonList(new BranchSpec("${library.stuff.version}")),
106-
false, Collections.<SubmoduleConfig>emptyList(), null, null, Collections.<GitSCMExtension>emptyList())));
107+
null, null, Collections.emptyList())));
107108
stuff.setDefaultVersion("master");
108109
stuff.setImplicit(true);
109110
GlobalLibraries.get().setLibraries(Collections.singletonList(stuff));
@@ -472,4 +473,12 @@ public void correctLibraryDirectoryUsedWhenResumingOldBuild() throws Exception {
472473
r.assertLogContains("called Foo", b);
473474
}
474475

476+
@Issue("JENKINS-68544")
477+
@WithoutJenkins
478+
@Test public void className() {
479+
assertThat(LibraryAdder.LoadedLibraries.className("/path/to/lib/src/some/pkg/Type.groovy", "/path/to/lib/src"), is("some.pkg.Type"));
480+
assertThat(LibraryAdder.LoadedLibraries.className("C:\\path\\to\\lib\\src\\some\\pkg\\Type.groovy", "C:\\path\\to\\lib\\src"), is("some.pkg.Type"));
481+
assertThat(LibraryAdder.LoadedLibraries.className("C:\\path\\to\\Extra\\lib\\src\\some\\pkg\\Type.groovy", "C:\\path\\to\\Extra\\lib\\src"), is("some.pkg.Type"));
482+
}
483+
475484
}

0 commit comments

Comments
 (0)