Skip to content

Commit 5331992

Browse files
authored
Merge branch 'master' into shell_global
2 parents a22fcfb + 4e52807 commit 5331992

File tree

128 files changed

+1350
-964
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

128 files changed

+1350
-964
lines changed

.github/workflows/announce-lts-rc.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
discourse-author-username: jenkins-release-bot
1717
discourse-category: 23
1818
- name: Post on mailing list
19-
uses: dawidd6/action-send-mail@v3
19+
uses: dawidd6/action-send-mail@v4
2020
with:
2121
server_address: smtp.gmail.com
2222
server_port: 465

.github/workflows/run-since-updater.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
id: run_script
3030
shell: bash
3131
- name: Create Pull Request
32-
uses: peter-evans/create-pull-request@dd2324fc52d5d43c699a5636bcf19fceaa70c284 # v7
32+
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7
3333
with:
3434
token: ${{ secrets.GITHUB_TOKEN }}
3535
commit-message: Fill in since annotations

bom/pom.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ THE SOFTWARE.
4141
<commons-fileupload2.version>2.0.0-M2</commons-fileupload2.version>
4242
<groovy.version>2.4.21</groovy.version>
4343
<jelly.version>1.1-jenkins-20250108</jelly.version>
44-
<stapler.version>1955.vdb_2736b_480e3</stapler.version>
44+
<stapler.version>1962.v928389828d33</stapler.version>
4545
</properties>
4646

4747
<dependencyManagement>
@@ -56,22 +56,22 @@ THE SOFTWARE.
5656
<dependency>
5757
<groupId>org.slf4j</groupId>
5858
<artifactId>slf4j-bom</artifactId>
59-
<version>2.0.16</version>
59+
<version>2.0.17</version>
6060
<type>pom</type>
6161
<scope>import</scope>
6262
</dependency>
6363
<dependency>
6464
<groupId>org.springframework</groupId>
6565
<artifactId>spring-framework-bom</artifactId>
66-
<version>6.2.3</version>
66+
<version>6.2.4</version>
6767
<type>pom</type>
6868
<scope>import</scope>
6969
</dependency>
7070
<dependency>
7171
<!-- https://docs.spring.io/spring-security/reference/6.3/getting-spring-security.html#getting-maven-no-boot -->
7272
<groupId>org.springframework.security</groupId>
7373
<artifactId>spring-security-bom</artifactId>
74-
<version>6.4.3</version>
74+
<version>6.4.4</version>
7575
<type>pom</type>
7676
<scope>import</scope>
7777
</dependency>
@@ -144,7 +144,7 @@ THE SOFTWARE.
144144
<dependency>
145145
<groupId>net.java.dev.jna</groupId>
146146
<artifactId>jna</artifactId>
147-
<version>5.16.0</version>
147+
<version>5.17.0</version>
148148
</dependency>
149149
<dependency>
150150
<groupId>net.java.sezpoz</groupId>

cli/src/main/java/hudson/cli/CLI.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ public static int _main(String[] _args) throws Exception {
318318
throw new AssertionError();
319319
}
320320

321-
@SuppressFBWarnings(value = {"PATH_TRAVERSAL_IN", "URLCONNECTION_SSRF_FD"}, justification = "User provided values for running the program.")
321+
@SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "User provided value for running the program.")
322322
private static String readAuthFromFile(String auth) throws IOException {
323323
Path path;
324324
try {
@@ -329,7 +329,7 @@ private static String readAuthFromFile(String auth) throws IOException {
329329
return Files.readString(path, Charset.defaultCharset());
330330
}
331331

332-
@SuppressFBWarnings(value = {"PATH_TRAVERSAL_IN", "URLCONNECTION_SSRF_FD"}, justification = "User provided values for running the program.")
332+
@SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "User provided value for running the program.")
333333
private static File getFileFromArguments(List<String> args) {
334334
return new File(args.get(1));
335335
}

core/src/main/java/hudson/DescriptorExtensionList.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import edu.umd.cs.findbugs.annotations.CheckForNull;
2828
import edu.umd.cs.findbugs.annotations.NonNull;
29+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
2930
import hudson.model.Describable;
3031
import hudson.model.Descriptor;
3132
import hudson.model.Descriptor.FormException;
@@ -274,6 +275,7 @@ protected Descriptor adapt(ExtensionComponent<Descriptor> item) {
274275
/**
275276
* Exposed just for the test harness. Clear legacy instances.
276277
*/
278+
@SuppressFBWarnings(value = "HSM_HIDING_METHOD", justification = "TODO needs triage")
277279
public static void clearLegacyInstances() {
278280
legacyDescriptors.clear();
279281
}

core/src/main/java/hudson/ExtensionList.java

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@
3636
import java.util.ArrayList;
3737
import java.util.Collection;
3838
import java.util.Collections;
39+
import java.util.IdentityHashMap;
3940
import java.util.Iterator;
4041
import java.util.List;
4142
import java.util.Map;
4243
import java.util.Objects;
44+
import java.util.Set;
4345
import java.util.Vector;
4446
import java.util.concurrent.ConcurrentHashMap;
4547
import java.util.concurrent.CopyOnWriteArrayList;
@@ -48,6 +50,8 @@
4850
import jenkins.ExtensionComponentSet;
4951
import jenkins.model.Jenkins;
5052
import jenkins.util.io.OnMaster;
53+
import org.kohsuke.accmod.Restricted;
54+
import org.kohsuke.accmod.restrictions.NoExternalUse;
5155

5256
/**
5357
* Retains the known extension instances for the given type 'T'.
@@ -335,27 +339,44 @@ protected Object getLoadLock() {
335339
/**
336340
* Used during {@link Jenkins#refreshExtensions()} to add new components into existing {@link ExtensionList}s.
337341
* Do not call from anywhere else.
342+
* @return true if {@link #fireOnChangeListeners} should be called on {@code this} after all lists have been refreshed.
338343
*/
339-
public void refresh(ExtensionComponentSet delta) {
340-
boolean fireOnChangeListeners = false;
344+
@Restricted(NoExternalUse.class)
345+
public boolean refresh(ExtensionComponentSet delta) {
341346
synchronized (getLoadLock()) {
342347
if (extensions == null)
343-
return; // not yet loaded. when we load it, we'll load everything visible by then, so no work needed
344-
345-
Collection<ExtensionComponent<T>> found = load(delta);
346-
if (!found.isEmpty()) {
347-
List<ExtensionComponent<T>> l = new ArrayList<>(extensions);
348-
l.addAll(found);
349-
extensions = sort(l);
350-
fireOnChangeListeners = true;
348+
return false; // not yet loaded. when we load it, we'll load everything visible by then, so no work needed
349+
350+
Collection<ExtensionComponent<T>> newComponents = load(delta);
351+
if (!newComponents.isEmpty()) {
352+
// We check to ensure that we do not insert duplicate instances of already-loaded extensions into the list.
353+
// This can happen when dynamically loading a plugin with an extension A that itself loads another
354+
// extension B from the same plugin in some contexts, such as in A's constructor or via a method in A called
355+
// by an ExtensionListListener. In those cases, ExtensionList.refresh may be called on a list that already
356+
// includes the new extensions. Note that ExtensionComponent objects are always unique, even when
357+
// ExtensionComponent.getInstance is identical, so we have to track the components and instances separately
358+
// to handle ordinal sorting and check for dupes.
359+
List<ExtensionComponent<T>> components = new ArrayList<>(extensions);
360+
Set<T> instances = Collections.newSetFromMap(new IdentityHashMap<>());
361+
for (ExtensionComponent<T> component : components) {
362+
instances.add(component.getInstance());
363+
}
364+
boolean fireListeners = false;
365+
for (ExtensionComponent<T> newComponent : newComponents) {
366+
if (instances.add(newComponent.getInstance())) {
367+
fireListeners = true;
368+
components.add(newComponent);
369+
}
370+
}
371+
extensions = sort(new ArrayList<>(components));
372+
return fireListeners;
351373
}
352374
}
353-
if (fireOnChangeListeners) {
354-
fireOnChangeListeners();
355-
}
375+
return false;
356376
}
357377

358-
private void fireOnChangeListeners() {
378+
@Restricted(NoExternalUse.class)
379+
public void fireOnChangeListeners() {
359380
for (ExtensionListListener listener : listeners) {
360381
try {
361382
listener.onChange();

core/src/main/java/hudson/Functions.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,6 +1810,7 @@ public static <T> T defaulted(T value, T defaultValue) {
18101810
return s.toString();
18111811
}
18121812

1813+
@SuppressFBWarnings(value = "INFORMATION_EXPOSURE_THROUGH_AN_ERROR_MESSAGE", justification = "Jenkins handles this issue differently or doesn't care about it")
18131814
private static void doPrintStackTrace(@NonNull StringBuilder s, @NonNull Throwable t, @CheckForNull Throwable higher, @NonNull String prefix, @NonNull Set<Throwable> encountered) {
18141815
if (!encountered.add(t)) {
18151816
s.append("<cycle to ").append(t).append(">\n");
@@ -1863,6 +1864,7 @@ private static void doPrintStackTrace(@NonNull StringBuilder s, @NonNull Throwab
18631864
* @param pw the log
18641865
* @since 2.43
18651866
*/
1867+
@SuppressFBWarnings(value = "XSS_SERVLET", justification = "TODO needs triage")
18661868
public static void printStackTrace(@CheckForNull Throwable t, @NonNull PrintWriter pw) {
18671869
pw.println(printThrowable(t).trim());
18681870
}

core/src/main/java/hudson/Launcher.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,7 @@ private File toFile(FilePath f) {
10001000
}
10011001

10021002
@Override
1003+
@SuppressFBWarnings(value = "COMMAND_INJECTION", justification = "TODO needs triage")
10031004
public Channel launchChannel(String[] cmd, OutputStream out, FilePath workDir, Map<String, String> envVars) throws IOException {
10041005
printCommandLine(cmd, workDir);
10051006

@@ -1437,11 +1438,15 @@ private static class RemoteChannelLaunchCallable extends MasterToSlaveCallable<O
14371438
this.envOverrides = envOverrides;
14381439
}
14391440

1441+
@SuppressFBWarnings(value = "COMMAND_INJECTION", justification = "TODO needs triage")
1442+
private Process launchProcess() throws IOException {
1443+
return Runtime.getRuntime()
1444+
.exec(cmd, Util.mapToEnv(inherit(envOverrides)), workDir == null ? null : new File(workDir));
1445+
}
1446+
14401447
@Override
14411448
public OutputStream call() throws IOException {
1442-
Process p = Runtime.getRuntime().exec(cmd,
1443-
Util.mapToEnv(inherit(envOverrides)),
1444-
workDir == null ? null : new File(workDir));
1449+
Process p = launchProcess();
14451450

14461451
List<String> cmdLines = Arrays.asList(cmd);
14471452
new StreamCopyThread("stdin copier for remote agent on " + cmdLines,

core/src/main/java/hudson/PluginManager.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
import java.util.HashMap;
101101
import java.util.HashSet;
102102
import java.util.Iterator;
103+
import java.util.LinkedHashMap;
103104
import java.util.LinkedHashSet;
104105
import java.util.List;
105106
import java.util.Locale;
@@ -114,7 +115,6 @@
114115
import java.util.concurrent.ConcurrentMap;
115116
import java.util.concurrent.CopyOnWriteArrayList;
116117
import java.util.concurrent.Future;
117-
import java.util.function.Function;
118118
import java.util.function.Supplier;
119119
import java.util.jar.JarEntry;
120120
import java.util.jar.JarFile;
@@ -363,6 +363,7 @@ PluginManager doCreate(@NonNull Class<? extends PluginManager> klass,
363363
* This is used to report a message that Jenkins needs to be restarted
364364
* for new plugins to take effect.
365365
*/
366+
@SuppressFBWarnings(value = "PA_PUBLIC_PRIMITIVE_ATTRIBUTE", justification = "Preserve API compatibility")
366367
public volatile boolean pluginUploaded = false;
367368

368369
/**
@@ -2661,7 +2662,10 @@ public boolean isActivated() {
26612662
public Map<PluginWrapper, String> getDeprecatedPlugins() {
26622663
return Jenkins.get().getPluginManager().getPlugins().stream()
26632664
.filter(PluginWrapper::isDeprecated)
2664-
.collect(Collectors.toMap(Function.identity(), it -> it.getDeprecations().get(0).url));
2665+
.sorted(Comparator.comparing(PluginWrapper::getDisplayName)) // Sort by plugin name
2666+
.collect(LinkedHashMap::new,
2667+
(map, plugin) -> map.put(plugin, plugin.getDeprecations().get(0).url),
2668+
Map::putAll);
26652669
}
26662670
}
26672671

core/src/main/java/hudson/ProxyConfiguration.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.thoughtworks.xstream.XStream;
2828
import edu.umd.cs.findbugs.annotations.CheckForNull;
2929
import edu.umd.cs.findbugs.annotations.NonNull;
30+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
3031
import hudson.model.AbstractDescribableImpl;
3132
import hudson.model.Descriptor;
3233
import hudson.model.Saveable;
@@ -113,6 +114,7 @@ public final class ProxyConfiguration extends AbstractDescribableImpl<ProxyConfi
113114
* @see #getNoProxyHostPatterns()
114115
*/
115116
@Restricted(NoExternalUse.class)
117+
@SuppressFBWarnings(value = "PA_PUBLIC_PRIMITIVE_ATTRIBUTE", justification = "Preserve API compatibility")
116118
public String noProxyHost;
117119

118120
@Deprecated

0 commit comments

Comments
 (0)