Skip to content

Commit

Permalink
Merge branch 'master' into new-new-view-page
Browse files Browse the repository at this point in the history
  • Loading branch information
janfaracik committed Oct 21, 2021
2 parents 281b2bd + 6adc9c0 commit 7cddfd3
Show file tree
Hide file tree
Showing 229 changed files with 1,341 additions and 583 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
private_key: ${{ secrets.JENKINS_CHANGELOG_UPDATER_PRIVATE_KEY }}
repository: jenkins-infra/jenkins.io
- name: Check out
uses: actions/[email protected].4
uses: actions/[email protected].5
with:
fetch-depth: 0
- name: Publish jenkins.io changelog draft
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-release-artifact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
project-version: ${{ steps.set-version.outputs.project-version }}
is-lts: ${{ steps.set-version.outputs.is-lts }}
steps:
- uses: actions/[email protected].4
- uses: actions/[email protected].5
- name: Set up JDK 8
uses: actions/setup-java@v2
with:
Expand Down
7 changes: 5 additions & 2 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ def buildNumber = BUILD_NUMBER as int; if (buildNumber > 1) milestone(buildNumbe
def runTests = true
def failFast = false

properties([buildDiscarder(logRotator(numToKeepStr: '50', artifactNumToKeepStr: '3')), durabilityHint('PERFORMANCE_OPTIMIZED')])
properties([
buildDiscarder(logRotator(numToKeepStr: '50', artifactNumToKeepStr: '3')),
disableConcurrentBuilds(abortPrevious: true)
])

// TODO: Restore 'Windows' once https://groups.google.com/forum/#!topic/jenkinsci-dev/v9d-XosOp2s is resolved
def buildTypes = ['Linux']
Expand Down Expand Up @@ -114,7 +117,7 @@ for(j = 0; j < jdks.size(); j++) {
// TODO: Restore ATH once https://groups.google.com/forum/#!topic/jenkinsci-dev/v9d-XosOp2s is resolved
// TODO: ATH flow now supports Java 8 only, it needs to be reworked (INFRA-1690)
builds.ath = {
node("docker&&highmem") {
node("docker-highmem") {
// Just to be safe
deleteDir()
def fileUri
Expand Down
2 changes: 1 addition & 1 deletion bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ THE SOFTWARE.
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1-jenkins-2</version>
<version>3.1-jenkins-3</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
Expand Down
2 changes: 1 addition & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ THE SOFTWARE.
<properties>
<staplerFork>true</staplerFork>
<hamcrest.version>2.2</hamcrest.version>
<xmlunit.version>2.8.2</xmlunit.version>
<xmlunit.version>2.8.3</xmlunit.version>
<!-- TODO: JENKINS-36716 - Switch to Medium once SpotBugs is cleaned up, 929 issues on September 26, 2021 -->
<spotbugs.threshold>High</spotbugs.threshold>
</properties>
Expand Down
24 changes: 20 additions & 4 deletions core/src/main/java/hudson/PluginManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.PluginWrapper.Dependency;
import hudson.init.InitMilestone;
Expand Down Expand Up @@ -481,7 +482,7 @@ protected void reactOnCycle(PluginWrapper q, List<PluginWrapper> cycle) {
LOGGER.log(Level.SEVERE, "found cycle in plugin dependencies: (root=" + q + ", deactivating all involved) " + cycle.stream().map(Object::toString).collect(Collectors.joining(" -> ")));
for (PluginWrapper pluginWrapper : cycle) {
pluginWrapper.setHasCycleDependency(true);
failedPlugins.add(new FailedPlugin(pluginWrapper.getShortName(), new CycleDetectedException(cycle)));
failedPlugins.add(new FailedPlugin(pluginWrapper, new CycleDetectedException(cycle)));
}
}

Expand Down Expand Up @@ -534,12 +535,12 @@ public void run(Reactor session) throws Exception {
p.resolvePluginDependencies();
strategy.load(p);
} catch (MissingDependencyException e) {
failedPlugins.add(new FailedPlugin(p.getShortName(), e));
failedPlugins.add(new FailedPlugin(p, e));
activePlugins.remove(p);
plugins.remove(p);
LOGGER.log(Level.SEVERE, "Failed to install {0}: {1}", new Object[] { p.getShortName(), e.getMessage() });
} catch (IOException e) {
failedPlugins.add(new FailedPlugin(p.getShortName(), e));
failedPlugins.add(new FailedPlugin(p, e));
activePlugins.remove(p);
plugins.remove(p);
throw e;
Expand All @@ -559,7 +560,7 @@ public void run(Reactor session) throws Exception {
try {
p.getPluginOrFail().postInitialize();
} catch (Exception e) {
failedPlugins.add(new FailedPlugin(p.getShortName(), e));
failedPlugins.add(new FailedPlugin(p, e));
activePlugins.remove(p);
plugins.remove(p);
throw e;
Expand Down Expand Up @@ -2210,10 +2211,25 @@ public String toString() {
public static final class FailedPlugin {
public final String name;
public final Exception cause;
@Nullable
public final PluginWrapper pluginWrapper;

/**
* Constructor for FailedPlugin when we do not have an associated PluginWrapper
*/
public FailedPlugin(String name, Exception cause) {
this.name = name;
this.cause = cause;
this.pluginWrapper = null;
}

/**
* Constructor for FailedPlugin when we know which PluginWrapper failed
*/
public FailedPlugin(PluginWrapper pluginWrapper, Exception cause) {
this.name = pluginWrapper.getShortName();
this.cause = cause;
this.pluginWrapper = pluginWrapper;
}

public String getExceptionString() {
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/java/hudson/model/AbstractCIBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@


import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.security.AccessControlled;
import hudson.slaves.ComputerListener;
Expand Down Expand Up @@ -57,6 +58,7 @@ public abstract class AbstractCIBase extends Node implements ItemGroup<TopLevelI
* @deprecated
* Maybe you were trying to call {@link #getDisplayName()}.
*/
@NonNull
@Deprecated @Override
public String getNodeName() {
return "";
Expand Down
11 changes: 3 additions & 8 deletions core/src/main/java/hudson/model/AsyncAperiodicWork.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,21 +113,16 @@ public final void doAperiodicRun() {
long startTime = System.currentTimeMillis();
long stopTime;

StreamTaskListener l = createListener();
AsyncPeriodicWork.LazyTaskListener l = new AsyncPeriodicWork.LazyTaskListener(() -> createListener(), String.format("Started at %tc", new Date(startTime)));
try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) {
l.getLogger().printf("Started at %tc%n", new Date(startTime));
execute(l);
execute(l);
} catch (IOException e) {
Functions.printStackTrace(e, l.fatalError(e.getMessage()));
} catch (InterruptedException e) {
Functions.printStackTrace(e, l.fatalError("aborted"));
} finally {
stopTime = System.currentTimeMillis();
try {
l.getLogger().printf("Finished at %tc. %dms%n", new Date(stopTime), stopTime - startTime);
} finally {
l.closeQuietly();
}
l.close(String.format("Finished at %tc. %dms", new Date(stopTime), stopTime - startTime));
}

logger.log(getNormalLoggingLevel(), "Finished {0}. {1,number} ms",
Expand Down
43 changes: 36 additions & 7 deletions core/src/main/java/hudson/model/AsyncPeriodicWork.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import hudson.util.StreamTaskListener;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import jenkins.model.Jenkins;
Expand Down Expand Up @@ -94,9 +96,8 @@ public final void doRun() {
long startTime = System.currentTimeMillis();
long stopTime;

StreamTaskListener l = createListener();
LazyTaskListener l = new LazyTaskListener(() -> createListener(), String.format("Started at %tc", new Date(startTime)));
try {
l.getLogger().printf("Started at %tc%n", new Date(startTime));
try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) {
execute(l);
}
Expand All @@ -106,11 +107,7 @@ public final void doRun() {
Functions.printStackTrace(e, l.fatalError("aborted"));
} finally {
stopTime = System.currentTimeMillis();
try {
l.getLogger().printf("Finished at %tc. %dms%n", new Date(stopTime), stopTime - startTime);
} finally {
l.closeQuietly();
}
l.close(String.format("Finished at %tc. %dms", new Date(stopTime), stopTime - startTime));
}

logger.log(getNormalLoggingLevel(), "Finished {0}. {1,number} ms",
Expand All @@ -125,6 +122,38 @@ public final void doRun() {
}
}

static final class LazyTaskListener implements TaskListener {

private final Supplier<StreamTaskListener> supplier;
private final String openingMessage;
private StreamTaskListener delegate;

LazyTaskListener(Supplier<StreamTaskListener> supplier, String openingMessage) {
this.supplier = supplier;
this.openingMessage = openingMessage;
}

@Override
public synchronized PrintStream getLogger() {
if (delegate == null) {
delegate = supplier.get();
delegate.getLogger().println(openingMessage);
}
return delegate.getLogger();
}

synchronized void close(String closingMessage) {
if (delegate != null) {
try {
delegate.getLogger().println(closingMessage);
} finally {
delegate.closeQuietly();
}
}
}

}

protected StreamTaskListener createListener() {
File f = getLogFile();
if (!f.getParentFile().isDirectory()) {
Expand Down
15 changes: 6 additions & 9 deletions core/src/main/java/hudson/model/Cause.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import hudson.console.ModelHyperlinkNote;
import hudson.diagnosis.OldDataMonitor;
import hudson.util.XStream2;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
Expand Down Expand Up @@ -65,8 +64,10 @@ public abstract class Cause {
/**
* One-line human-readable text of the cause.
*
* <p>
* By default, this method is used to render HTML as well.
* Historically, this method's return value was used to render HTML on the UI as well.
* Since Jenkins 2.315 and 2.303.2, the return value is interpreted as text.
* To have rich HTML output on the UI, provide a custom {@code description.jelly} view for your subclass.
* See <a href="https://www.jenkins.io/doc/developer/security/xss-prevention/Cause-getShortDescription/">the documentation</a>.
*/
@Exported(visibility=3)
public abstract String getShortDescription();
Expand Down Expand Up @@ -483,13 +484,9 @@ public RemoteCause(String host, String note) {
@Override
public String getShortDescription() {
if(note != null) {
try {
return Messages.Cause_RemoteCause_ShortDescriptionWithNote(Util.xmlEscape(addr), Jenkins.get().getMarkupFormatter().translate(note));
} catch (IOException x) {
// ignore
}
return Messages.Cause_RemoteCause_ShortDescriptionWithNote(addr, note);
}
return Messages.Cause_RemoteCause_ShortDescription(Util.xmlEscape(addr));
return Messages.Cause_RemoteCause_ShortDescription(addr);
}

@Exported(visibility = 3)
Expand Down
36 changes: 35 additions & 1 deletion core/src/main/java/hudson/model/DirectoryBrowserSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.FilePath;
import hudson.Util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
Expand All @@ -52,6 +54,7 @@
import java.util.stream.Stream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;

import jenkins.model.Jenkins;
import jenkins.security.MasterToSlaveCallable;
import jenkins.security.ResourceDomainConfiguration;
Expand Down Expand Up @@ -82,6 +85,11 @@ public final class DirectoryBrowserSupport implements HttpResponse {
@SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "Accessible via System Groovy Scripts")
public static boolean ALLOW_SYMLINK_ESCAPE = SystemProperties.getBoolean(DirectoryBrowserSupport.class.getName() + ".allowSymlinkEscape");

/**
* Escape hatch for the protection against SECURITY-2481. If enabled, the absolute paths on Windows will be allowed.
*/
static final String ALLOW_ABSOLUTE_PATH_PROPERTY_NAME = DirectoryBrowserSupport.class.getName() + ".allowAbsolutePath";

public final ModelObject owner;

public final String title;
Expand Down Expand Up @@ -243,7 +251,20 @@ private void serveFile(StaplerRequest req, StaplerResponse rsp, VirtualFile root
String rest = _rest.toString();

// this is the base file/directory
VirtualFile baseFile = base.isEmpty() ? root : root.child(base);
VirtualFile baseFile;
if (base.isEmpty()) {
baseFile = root;
} else {
if (!SystemProperties.getBoolean(ALLOW_ABSOLUTE_PATH_PROPERTY_NAME, false)) {
boolean isAbsolute = root.run(new IsAbsolute(base));
if (isAbsolute) {
LOGGER.info(() -> "SECURITY-2481 The path provided in the URL (" + base + ") is absolute and thus is refused.");
rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
}
baseFile = root.child(base);
}

if (baseFile.hasSymlink(getNoFollowLinks())) {
rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
Expand Down Expand Up @@ -397,6 +418,19 @@ private void serveFile(StaplerRequest req, StaplerResponse rsp, VirtualFile root
}
}

private static final class IsAbsolute extends MasterToSlaveCallable<Boolean, IOException> {
private final String fragment;

IsAbsolute(String fragment) {
this.fragment = fragment;
}

@Override
public Boolean call() throws IOException {
return new File(fragment).isAbsolute();
}
}

private List<List<Path>> keepReadabilityOnlyOnDescendants(VirtualFile root, boolean patternUsed, List<List<Path>> pathFragmentsList){
Stream<List<Path>> pathFragmentsStream = pathFragmentsList.stream().map((List<Path> pathFragments) -> {
List<Path> mappedFragments = new ArrayList<>(pathFragments.size());
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/hudson/model/JDK.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public static class DescriptorImpl extends ToolDescriptor<JDK> {

@Override
public String getDisplayName() {
return "JDK"; // TODO I18N
return Messages.JDK_DisplayName();
}

@Override
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/java/hudson/model/ParametersAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.EnvVars;
import hudson.Util;
import hudson.diagnosis.OldDataMonitor;
Expand Down Expand Up @@ -284,6 +285,7 @@ public ParametersAction merge(@CheckForNull ParametersAction overrides) {
return parametersAction;
}

@SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", justification = "parameters in readResolve is needed for data migration.")
private Object readResolve() {
if (parameters == null) { // JENKINS-39495
parameters = Collections.emptyList();
Expand Down
1 change: 1 addition & 0 deletions core/src/main/java/hudson/model/Slave.java
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ public String getRemoteFS() {
return remoteFS;
}

@NonNull
@Override
public String getNodeName() {
return name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -506,9 +506,9 @@ public void add(Class definedInCls, String fieldName) {

private Class determineType(HierarchicalStreamReader reader, boolean validField, Object result, String fieldName, Class definedInCls) {
String classAttribute = reader.getAttribute(mapper.aliasForAttribute("class"));
Class fieldType = reflectionProvider.getFieldType(result, fieldName, definedInCls);
if (classAttribute != null) {
Class specifiedType = mapper.realClass(classAttribute);
Class fieldType = reflectionProvider.getFieldType(result, fieldName, definedInCls);
if(fieldType.isAssignableFrom(specifiedType))
// make sure that the specified type in XML is compatible with the field type.
// this allows the code to evolve in more flexible way.
Expand All @@ -522,6 +522,7 @@ private Class determineType(HierarchicalStreamReader reader, boolean validField,
return mapper.realClass(reader.getNodeName());
}
} else {
Class fieldType = reflectionProvider.getFieldType(result, fieldName, definedInCls);
return mapper.defaultImplementationOf(fieldType);
}
}
Expand Down
Loading

0 comments on commit 7cddfd3

Please sign in to comment.