提交 01f8b82c 编写于 作者: J Jesse Glick

Merge commit '4af8a599' into security-master

......@@ -5,7 +5,7 @@
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>2.56-SNAPSHOT</version>
<version>2.57-SNAPSHOT</version>
</parent>
<artifactId>cli</artifactId>
......
......@@ -32,6 +32,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPair;
......@@ -134,6 +135,8 @@ public class PrivateKeyProvider {
byte[] bytes = new byte[(int) f.length()];
dis.readFully(bytes);
return new String(bytes);
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
......
......@@ -29,7 +29,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>2.56-SNAPSHOT</version>
<version>2.57-SNAPSHOT</version>
</parent>
<artifactId>jenkins-core</artifactId>
......
......@@ -25,6 +25,7 @@ package hudson;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import jenkins.util.SystemProperties;
import com.google.common.collect.Lists;
import hudson.Plugin.DummyImpl;
......@@ -127,6 +128,8 @@ public class ClassicPluginStrategy implements PluginStrategy {
String firstLine;
try (InputStream manifestHeaderInput = Files.newInputStream(archive.toPath())) {
firstLine = IOUtils.readFirstLine(manifestHeaderInput, "UTF-8");
} catch (InvalidPathException e) {
throw new IOException(e);
}
if (firstLine.startsWith("Manifest-Version:")) {
// this is the manifest already
......@@ -138,6 +141,8 @@ public class ClassicPluginStrategy implements PluginStrategy {
// Read the manifest
try (InputStream manifestInput = Files.newInputStream(archive.toPath())) {
return new Manifest(manifestInput);
} catch (InvalidPathException e) {
throw new IOException(e);
}
} catch (IOException e) {
throw new IOException("Failed to load " + archive, e);
......@@ -171,6 +176,8 @@ public class ClassicPluginStrategy implements PluginStrategy {
}
try (InputStream fin = Files.newInputStream(manifestFile.toPath())) {
manifest = new Manifest(fin);
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
......
......@@ -78,6 +78,7 @@ import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
......@@ -1469,8 +1470,13 @@ public final class FilePath implements Serializable {
act(new SecureFileCallable<Void>() {
private static final long serialVersionUID = -5094638816500738429L;
public Void invoke(File f, VirtualChannel channel) throws IOException {
if(!f.exists())
Files.newOutputStream(creating(f).toPath()).close();
if(!f.exists()) {
try {
Files.newOutputStream(creating(f).toPath()).close();
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
if(!stating(f).setLastModified(timestamp))
throw new IOException("Failed to set the timestamp of "+f+" to "+timestamp);
return null;
......@@ -1750,8 +1756,13 @@ public final class FilePath implements Serializable {
* Reads this file.
*/
public InputStream read() throws IOException, InterruptedException {
if(channel==null)
return Files.newInputStream(reading(new File(remote)).toPath());
if(channel==null) {
try {
return Files.newInputStream(reading(new File(remote)).toPath());
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
final Pipe p = Pipe.createRemoteToLocal();
actAsync(new SecureFileCallable<Void>() {
......@@ -1762,6 +1773,8 @@ public final class FilePath implements Serializable {
try (InputStream fis = Files.newInputStream(reading(f).toPath());
OutputStream out = p.getOut()) {
org.apache.commons.io.IOUtils.copy(fis, out);
} catch (InvalidPathException e) {
p.error(new IOException(e));
} catch (Exception x) {
p.error(x);
}
......@@ -1862,7 +1875,11 @@ public final class FilePath implements Serializable {
if(channel==null) {
File f = new File(remote).getAbsoluteFile();
mkdirs(f.getParentFile());
return Files.newOutputStream(writing(f).toPath());
try {
return Files.newOutputStream(writing(f).toPath());
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
return act(new SecureFileCallable<OutputStream>() {
......@@ -1870,8 +1887,12 @@ public final class FilePath implements Serializable {
public OutputStream invoke(File f, VirtualChannel channel) throws IOException, InterruptedException {
f = f.getAbsoluteFile();
mkdirs(f.getParentFile());
OutputStream fos = Files.newOutputStream(writing(f).toPath());
return new RemoteOutputStream(fos);
try {
OutputStream fos = Files.newOutputStream(writing(f).toPath());
return new RemoteOutputStream(fos);
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
});
}
......@@ -1891,6 +1912,8 @@ public final class FilePath implements Serializable {
try (OutputStream fos = Files.newOutputStream(writing(f).toPath());
Writer w = encoding != null ? new OutputStreamWriter(fos, encoding) : new OutputStreamWriter(fos)) {
w.write(content);
} catch (InvalidPathException e) {
throw new IOException(e);
}
return null;
}
......@@ -1994,6 +2017,8 @@ public final class FilePath implements Serializable {
try (InputStream fis = Files.newInputStream(reading(f).toPath())) {
org.apache.commons.io.IOUtils.copy(fis, out);
return null;
} catch (InvalidPathException e) {
throw new IOException(e);
} finally {
out.close();
}
......
......@@ -32,6 +32,7 @@ import hudson.model.Job;
import hudson.model.TaskListener;
import hudson.util.io.ArchiverFactory;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import jenkins.model.Jenkins;
import hudson.model.listeners.RunListener;
import hudson.scm.SCM;
......@@ -218,6 +219,8 @@ public abstract class FileSystemProvisioner implements ExtensionPoint, Describab
File wss = new File(build.getRootDir(),"workspace.tgz");
try (OutputStream os = new BufferedOutputStream(Files.newOutputStream(wss.toPath()))) {
ws.archive(ArchiverFactory.TARGZ, os, glob);
} catch (InvalidPathException e) {
throw new IOException(e);
}
return new WorkspaceSnapshotImpl();
}
......
......@@ -26,6 +26,7 @@ package hudson;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import jenkins.util.SystemProperties;
import hudson.util.DualOutputStream;
import hudson.util.EncodingStream;
......@@ -155,6 +156,8 @@ public class Main {
ret = proc.join();
w.write("</log><result>"+ret+"</result><duration>"+(System.currentTimeMillis()-start)+"</duration></run>");
} catch (InvalidPathException e) {
throw new IOException(e);
}
URL location = new URL(jobURL, "postBuildResult");
......@@ -173,6 +176,8 @@ public class Main {
// send the data
try (InputStream in = Files.newInputStream(tmpFile.toPath())) {
org.apache.commons.io.IOUtils.copy(in, con.getOutputStream());
} catch (InvalidPathException e) {
throw new IOException(e);
}
if(con.getResponseCode()!=200) {
......
......@@ -30,6 +30,7 @@ import hudson.model.AdministrativeMonitor;
import hudson.model.Api;
import hudson.model.ModelObject;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import jenkins.YesNoMaybe;
import jenkins.model.Jenkins;
import hudson.model.UpdateCenter;
......@@ -496,8 +497,11 @@ public class PluginWrapper implements Comparable<PluginWrapper>, ModelObject {
*/
public void disable() throws IOException {
// creates an empty file
OutputStream os = Files.newOutputStream(disableFile.toPath());
os.close();
try (OutputStream os = Files.newOutputStream(disableFile.toPath())) {
os.close();
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
/**
......
......@@ -23,6 +23,7 @@
*/
package hudson;
import java.nio.file.InvalidPathException;
import jenkins.util.SystemProperties;
import com.sun.jna.Native;
......@@ -202,6 +203,8 @@ public class Util {
int len;
while ((len = r.read(buf, 0, buf.length)) > 0)
str.append(buf, 0, len);
} catch (InvalidPathException e) {
throw new IOException(e);
}
return str.toString();
......@@ -283,7 +286,11 @@ public class Util {
if(!f.delete() && f.exists()) {
// trouble-shooting.
Files.deleteIfExists(f.toPath());
try {
Files.deleteIfExists(f.toPath());
} catch (InvalidPathException e) {
throw new IOException(e);
}
// see https://java.net/projects/hudson/lists/users/archive/2008-05/message/357
// I suspect other processes putting files in this directory
......@@ -811,6 +818,8 @@ public class Util {
public static String getDigestOf(@Nonnull File file) throws IOException {
try (InputStream is = Files.newInputStream(file.toPath())) {
return getDigestOf(new BufferedInputStream(is));
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
......@@ -1143,7 +1152,11 @@ public class Util {
* Creates an empty file.
*/
public static void touch(@Nonnull File file) throws IOException {
Files.newOutputStream(file.toPath()).close();
try {
Files.newOutputStream(file.toPath()).close();
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
/**
......
......@@ -26,6 +26,7 @@ package hudson;
import hudson.security.ACLContext;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.StandardOpenOption;
import jenkins.util.SystemProperties;
import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
......@@ -278,7 +279,7 @@ public class WebAppMain implements ServletContextListener {
private void recordBootAttempt(File home) {
try (OutputStream o=Files.newOutputStream(BootFailure.getBootFailureFile(home).toPath(), StandardOpenOption.CREATE, StandardOpenOption.APPEND)) {
o.write((new Date().toString() + System.getProperty("line.separator", "\n")).toString().getBytes());
} catch (IOException e) {
} catch (IOException | InvalidPathException e) {
LOGGER.log(WARNING, "Failed to record boot attempts",e);
}
}
......
......@@ -34,6 +34,7 @@ import hudson.model.Descriptor;
import hudson.util.AtomicFileWriter;
import hudson.util.XStream2;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
......@@ -140,7 +141,7 @@ public final class XmlFile {
}
try (InputStream in = new BufferedInputStream(Files.newInputStream(file.toPath()))) {
return xs.fromXML(in);
} catch (XStreamException | Error e) {
} catch (XStreamException | Error | InvalidPathException e) {
throw new IOException("Unable to read "+file,e);
}
}
......@@ -157,7 +158,7 @@ public final class XmlFile {
try (InputStream in = new BufferedInputStream(Files.newInputStream(file.toPath()))) {
// TODO: expose XStream the driver from XStream
return xs.unmarshal(DEFAULT_DRIVER.createReader(in), o);
} catch (XStreamException | Error e) {
} catch (XStreamException | Error | InvalidPathException e) {
throw new IOException("Unable to read "+file,e);
}
}
......@@ -201,14 +202,18 @@ public final class XmlFile {
* @return Reader for the file. should be close externally once read.
*/
public Reader readRaw() throws IOException {
InputStream fileInputStream = Files.newInputStream(file.toPath());
try {
return new InputStreamReader(fileInputStream, sniffEncoding());
} catch(IOException ex) {
// Exception may happen if we fail to find encoding or if this encoding is unsupported.
// In such case we close the underlying stream and rethrow.
Util.closeAndLogFailures(fileInputStream, LOGGER, "FileInputStream", file.toString());
throw ex;
InputStream fileInputStream = Files.newInputStream(file.toPath());
try {
return new InputStreamReader(fileInputStream, sniffEncoding());
} catch (IOException ex) {
// Exception may happen if we fail to find encoding or if this encoding is unsupported.
// In such case we close the underlying stream and rethrow.
Util.closeAndLogFailures(fileInputStream, LOGGER, "FileInputStream", file.toString());
throw ex;
}
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
......@@ -288,7 +293,9 @@ public final class XmlFile {
// in such a case, assume UTF-8 rather than fail, since Jenkins internally always write XML in UTF-8
return "UTF-8";
} catch (SAXException e) {
throw new IOException("Failed to detect encoding of "+file,e);
throw new IOException("Failed to detect encoding of " + file, e);
} catch (InvalidPathException e) {
throw new IOException(e);
} catch (ParserConfigurationException e) {
throw new AssertionError(e); // impossible
}
......
......@@ -30,6 +30,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
/**
* Annotates one line of console output.
......@@ -71,15 +73,16 @@ public abstract class ConsoleAnnotator<T> implements Serializable {
* Annotates one line.
*
* @param context
* The object that owns the console output. Never null.
* The object that owns the console output. Never {@code null}.
* @param text
* Contains a single line of console output, and defines convenient methods to add markup.
* The callee should put markup into this object. Never null.
* The callee should put markup into this object. Never {@code null}.
* @return
* The {@link ConsoleAnnotator} object that will annotate the next line of the console output.
* To indicate that you are not interested in the following lines, return null.
* To indicate that you are not interested in the following lines, return {@code null}.
*/
public abstract ConsoleAnnotator annotate(T context, MarkupText text );
@CheckForNull
public abstract ConsoleAnnotator annotate(@Nonnull T context, @Nonnull MarkupText text );
/**
* Cast operation that restricts T.
......
/*
* The MIT License
*
* Copyright (c) 2010-2011, CloudBees, Inc.
* Copyright (c) 2010-2017, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
......@@ -27,73 +27,31 @@ import hudson.Extension;
import hudson.MarkupText;
import org.jenkinsci.Symbol;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// TODO: the implementation has been deprecated due to JENKINS-42861
// Consider providing alternate search mechanisms (JIRA, grepcode, etc.) as proposed in
// https://github.com/jenkinsci/jenkins/pull/2808#pullrequestreview-27467560 (JENKINS-43612)
/**
* Placed on the beginning of the exception stack trace produced by Hudson, which in turn produces hyperlinked stack trace.
* Placed on the beginning of the exception stack trace produced by Jenkins,
* which in turn produces hyperlinked stack trace.
*
* <p>
* Exceptions in the user code (like junit etc) should be handled differently. This is only for exceptions
* that occur inside Hudson.
* that occur inside Jenkins.
*
* @author Kohsuke Kawaguchi
* @since 1.349
* @since 1.349 - produces search hyperlinks to the http://stacktrace.jenkins-ci.org service
* @since TODO - does nothing due to JENKINS-42861
* @deprecated This ConsoleNote used to provide hyperlinks to the
* <code>http://stacktrace.jenkins-ci.org/</code> service, which is dead now (JENKINS-42861).
* This console note does nothing right now.
*/
@Deprecated
public class HudsonExceptionNote extends ConsoleNote<Object> {
@Override
public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) {
// An exception stack trace looks like this:
// org.acme.FooBarException: message
// <TAB>at org.acme.Foo.method(Foo.java:123)
// Caused by: java.lang.ClassNotFoundException:
String line = text.getText();
int end = line.indexOf(':',charPos);
if (end<0) {
if (CLASSNAME.matcher(line.substring(charPos)).matches())
end = line.length();
else
return null; // unexpected format. abort.
}
text.addHyperlinkLowKey(charPos,end,annotateClassName(line.substring(charPos,end)));
return new ConsoleAnnotator() {
public ConsoleAnnotator annotate(Object context, MarkupText text) {
String line = text.getText();
Matcher m = STACK_TRACE_ELEMENT.matcher(line);
if (m.find()) {// allow the match to happen in the middle of a line to cope with prefix. Ant and Maven put them, among many other tools.
text.addHyperlinkLowKey(m.start()+4,m.end(),annotateMethodName(m.group(1),m.group(2),m.group(3),Integer.parseInt(m.group(4))));
return this;
}
int idx = line.indexOf(CAUSED_BY);
if (idx>=0) {
int s = idx + CAUSED_BY.length();
int e = line.indexOf(':', s);
if (e<0) e = line.length();
text.addHyperlinkLowKey(s,e,annotateClassName(line.substring(s,e)));
return this;
}
if (AND_MORE.matcher(line).matches())
return this;
// looks like we are done with the stack trace
return null;
}
};
}
// TODO; separate out the annotations and mark up
private String annotateMethodName(String className, String methodName, String sourceFileName, int lineNumber) {
return "http://stacktrace.jenkins-ci.org/search/?query="+className+'.'+methodName+"&entity=method";
}
private String annotateClassName(String className) {
return "http://stacktrace.jenkins-ci.org/search?query="+className;
return null;
}
@Extension @Symbol("stackTrace")
......@@ -103,21 +61,4 @@ public class HudsonExceptionNote extends ConsoleNote<Object> {
return "Exception Stack Trace";
}
}
/**
* Regular expression that represents a valid class name.
*/
private static final String CLASSNAME_PATTERN = "[\\p{L}0-9$_.]+";
private static final Pattern CLASSNAME = Pattern.compile(CLASSNAME_PATTERN+"\r?\n?");
/**
* Matches to the line like "\tat org.acme.Foo.method(File.java:123)"
* and captures class name, method name, source file name, and line number separately.
*/
private static final Pattern STACK_TRACE_ELEMENT = Pattern.compile("\tat ("+CLASSNAME_PATTERN+")\\.([\\p{L}0-9$_<>]+)\\((\\S+):([0-9]+)\\)");
private static final String CAUSED_BY = "Caused by: ";
private static final Pattern AND_MORE = Pattern.compile("\t... [0-9]+ more\n");
}
......@@ -20,11 +20,18 @@ import org.kohsuke.stapler.Stapler;
* @author Kohsuke Kawaguchi
*/
public class InstallUncaughtExceptionHandler {
private static final Logger LOGGER = Logger.getLogger(InstallUncaughtExceptionHandler.class.getName());
@Initializer
public static void init(final Jenkins j) throws IOException {
CompressionFilter.setUncaughtExceptionHandler(j.servletContext, new UncaughtExceptionHandler() {
@Override
public void reportException(Throwable e, ServletContext context, HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException {
if (rsp.isCommitted()) {
LOGGER.log(Level.WARNING, null, e);
return;
}
req.setAttribute("javax.servlet.error.exception",e);
try {
WebApp.get(j.servletContext).getSomeStapler()
......@@ -38,10 +45,10 @@ public class InstallUncaughtExceptionHandler {
});
try {
Thread.setDefaultUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler());
DefaultUncaughtExceptionHandler.LOGGER.log(Level.FINE, "Successfully installed a global UncaughtExceptionHandler.");
LOGGER.log(Level.FINE, "Successfully installed a global UncaughtExceptionHandler.");
}
catch (SecurityException ex) {
DefaultUncaughtExceptionHandler.LOGGER.log(Level.SEVERE,
LOGGER.log(Level.SEVERE,
"Failed to set the default UncaughtExceptionHandler. " +
"If any threads die due to unhandled coding errors then there will be no logging of this information. " +
"The lack of this diagnostic information will make it harder to track down issues which will reduce the supportability of Jenkins. " +
......@@ -53,8 +60,6 @@ public class InstallUncaughtExceptionHandler {
/** An UncaughtExceptionHandler that just logs the exception */
private static class DefaultUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
private static final Logger LOGGER = Logger.getLogger(InstallUncaughtExceptionHandler.class.getName());
@Override
public void uncaughtException(Thread t, Throwable ex) {
// if this was an OutOfMemoryError then all bets about logging are off - but in the absence of anything else...
......@@ -65,4 +70,7 @@ public class InstallUncaughtExceptionHandler {
}
}
private InstallUncaughtExceptionHandler() {}
}
......@@ -33,6 +33,7 @@ import hudson.util.jna.SHELLEXECUTEINFO;
import hudson.util.jna.Shell32;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import jenkins.model.Jenkins;
import hudson.AbortException;
import hudson.Extension;
......@@ -313,6 +314,8 @@ public class WindowsInstallerLink extends ManagementLink {
} finally {
try (InputStream fin = Files.newInputStream(new File(pwd,"redirect.log").toPath())) {
IOUtils.copy(fin, out.getLogger());
} catch (InvalidPathException e) {
// ignore;
}
}
}
......
......@@ -31,6 +31,7 @@ import hudson.Util;
import hudson.Functions;
import hudson.BulkChange;
import hudson.cli.declarative.CLIResolver;
import hudson.model.Queue.Executable;
import hudson.model.listeners.ItemListener;
import hudson.model.listeners.SaveableListener;
import hudson.model.queue.Tasks;
......@@ -87,6 +88,8 @@ import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import static hudson.model.queue.Executables.getParentOf;
import hudson.model.queue.SubTask;
import java.lang.reflect.InvocationTargetException;
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import org.apache.commons.io.FileUtils;
import org.kohsuke.accmod.Restricted;
......@@ -621,9 +624,12 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet
Map<Executor, Queue.Executable> buildsInProgress = new LinkedHashMap<>();
for (Computer c : Jenkins.getInstance().getComputers()) {
for (Executor e : c.getAllExecutors()) {
WorkUnit workUnit = e.getCurrentWorkUnit();
if (workUnit != null) {
Item item = Tasks.getItemOf(getParentOf(workUnit.getExecutable()));
final WorkUnit workUnit = e.getCurrentWorkUnit();
final Executable executable = workUnit != null ? workUnit.getExecutable() : null;
final SubTask subtask = executable != null ? getParentOf(executable) : null;
if (subtask != null) {
Item item = Tasks.getItemOf(subtask);
if (item != null) {
while (item != null) {
if (item == this) {
......
......@@ -511,6 +511,7 @@ public class Executor extends Thread implements ModelObject {
* null if the executor is idle.
*/
@Exported
@CheckForNull
public WorkUnit getCurrentWorkUnit() {
lock.readLock().lock();
try {
......
......@@ -35,6 +35,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import javax.servlet.ServletException;
import org.apache.commons.fileupload.FileItem;
......@@ -212,6 +213,8 @@ public class FileParameterValue extends ParameterValue {
} else {
response.serveFile(request, data, lastModified, contentLength, originalFileName);
}
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
}
......@@ -241,7 +244,11 @@ public class FileParameterValue extends ParameterValue {
}
public InputStream getInputStream() throws IOException {
return Files.newInputStream(file.toPath());
try {
return Files.newInputStream(file.toPath());
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
public String getContentType() {
......@@ -265,7 +272,7 @@ public class FileParameterValue extends ParameterValue {
try (InputStream inputStream = Files.newInputStream(file.toPath())) {
return IOUtils.toByteArray(inputStream);
}
} catch (IOException e) {
} catch (IOException | InvalidPathException e) {
throw new Error(e);
}
}
......@@ -302,7 +309,11 @@ public class FileParameterValue extends ParameterValue {
@Deprecated
public OutputStream getOutputStream() throws IOException {
return Files.newOutputStream(file.toPath());
try {
return Files.newOutputStream(file.toPath());
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
@Override
......
......@@ -64,6 +64,7 @@ import hudson.model.queue.WorkUnitContext;
import hudson.security.ACL;
import hudson.security.AccessControlled;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import jenkins.security.QueueItemAuthenticatorProvider;
import jenkins.util.Timer;
import hudson.triggers.SafeTimerTask;
......@@ -384,6 +385,8 @@ public class Queue extends ResourceController implements Saveable {
if (j != null)
j.scheduleBuild();
}
} catch (InvalidPathException e) {
throw new IOException(e);
}
// discard the queue file now that we are done
queueFile.delete();
......
......@@ -42,6 +42,7 @@ import hudson.console.ConsoleNote;
import hudson.console.ModelHyperlinkNote;
import hudson.console.PlainTextConsoleOutputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.StandardOpenOption;
import jenkins.util.SystemProperties;
import hudson.Util;
......@@ -1367,12 +1368,16 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
if (logFile.exists() ) {
// Checking if a ".gz" file was return
InputStream fis = Files.newInputStream(logFile.toPath());
if (logFile.getName().endsWith(".gz")) {
return new GZIPInputStream(fis);
} else {
return fis;
}
try {
InputStream fis = Files.newInputStream(logFile.toPath());
if (logFile.getName().endsWith(".gz")) {
return new GZIPInputStream(fis);
} else {
return fis;
}
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
String message = "No such file: " + logFile;
......@@ -1804,7 +1809,12 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
// don't do buffering so that what's written to the listener
// gets reflected to the file immediately, which can then be
// served to the browser immediately
OutputStream logger = Files.newOutputStream(getLogFile().toPath(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
OutputStream logger;
try {
logger = Files.newOutputStream(getLogFile().toPath(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
} catch (InvalidPathException e) {
throw new IOException(e);
}
RunT build = job.getBuild();
// Global log filters
......
......@@ -32,6 +32,7 @@ import hudson.PluginWrapper;
import hudson.ProxyConfiguration;
import hudson.security.ACLContext;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import jenkins.util.SystemProperties;
import hudson.Util;
import hudson.XmlFile;
......@@ -1141,7 +1142,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
out.write(buf,0,len);
job.status = job.new Installing(total == -1 ? -1 : cin.getCount() * 100 / total);
}
} catch (IOException e) {
} catch (IOException | InvalidPathException e) {
throw new IOException("Failed to load "+src+" to "+tmp,e);
} finally {
t.setName(oldName);
......
......@@ -35,6 +35,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.annotation.CheckForNull;
/**
* Implements {@link ViewGroup} to be used as a "mix-in".
......@@ -92,7 +93,14 @@ public abstract class ViewGroupMixIn {
owner.save();
}
public View getView(String name) {
/**
* Gets a view by the specified name.
* The method iterates through {@link ViewGroup}s if required.
* @param name Name of the view
* @return View instance or {@code null} if it is missing
*/
@CheckForNull
public View getView(@CheckForNull String name) {
for (View v : views()) {
if(v.getViewName().equals(name))
return v;
......
......@@ -36,10 +36,14 @@ import javax.annotation.Nonnull;
* @author Kohsuke Kawaguchi
*/
public class Executables {
/**
* Due to the return type change in {@link Executable}, the caller needs a special precaution now.
* Due to the return type change in {@link Executable} in 1.377, the caller needs a special precaution now.
* @param e Executable
* @return Discovered subtask
*/
public static @Nonnull SubTask getParentOf(Executable e) {
public static @Nonnull SubTask getParentOf(@Nonnull Executable e)
throws Error, RuntimeException {
try {
return e.getParent();
} catch (AbstractMethodError _) {
......@@ -77,6 +81,7 @@ public class Executables {
try {
return e.getEstimatedDuration();
} catch (AbstractMethodError error) {
// TODO: according to the code above, e.getparent() may fail. The method also needs to be reworked
return e.getParent().getEstimatedDuration();
}
}
......
......@@ -79,6 +79,7 @@ public final class WorkUnit {
/**
* If the execution has already started, return the executable that was created.
*/
@CheckForNull
public Executable getExecutable() {
return executable;
}
......
......@@ -40,6 +40,7 @@ import hudson.util.HttpResponses;
import hudson.util.Secret;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import jenkins.model.Jenkins;
import jenkins.security.MasterToSlaveCallable;
import net.sf.json.JSONObject;
......@@ -519,6 +520,8 @@ public class JDKInstaller extends ToolInstaller {
tmp.getParentFile().mkdirs();
try (OutputStream out = Files.newOutputStream(tmp.toPath())) {
IOUtils.copy(m.getResponseBodyAsStream(), out);
} catch (InvalidPathException e) {
throw new IOException(e);
}
tmp.renameTo(cache);
......
......@@ -33,6 +33,7 @@ import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
/**
* Buffered {@link FileWriter} that supports atomic operations.
......@@ -71,7 +72,11 @@ public class AtomicFileWriter extends Writer {
destFile = f;
if (encoding==null)
encoding = Charset.defaultCharset().name();
core = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(tmpFile.toPath()),encoding));
try {
core = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(tmpFile.toPath()), encoding));
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
@Override
......
......@@ -33,6 +33,7 @@ import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
......@@ -78,7 +79,11 @@ public class CompressedFile {
public OutputStream write() throws IOException {
if(gz.exists())
gz.delete();
return Files.newOutputStream(file.toPath());
try {
return Files.newOutputStream(file.toPath());
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
/**
......@@ -86,11 +91,19 @@ public class CompressedFile {
*/
public InputStream read() throws IOException {
if(file.exists())
return Files.newInputStream(file.toPath());
try {
return Files.newInputStream(file.toPath());
} catch (InvalidPathException e) {
throw new IOException(e);
}
// check if the compressed file exists
if(gz.exists())
return new GZIPInputStream(Files.newInputStream(gz.toPath()));
try {
return new GZIPInputStream(Files.newInputStream(gz.toPath()));
} catch (InvalidPathException e) {
throw new IOException(e);
}
// no such file
throw new FileNotFoundException(file.getName());
......
......@@ -4,6 +4,7 @@ import hudson.Functions;
import hudson.os.PosixAPI;
import hudson.os.PosixException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import org.apache.commons.io.LineIterator;
import java.io.*;
......@@ -29,12 +30,16 @@ public class IOUtils {
public static void copy(File src, OutputStream out) throws IOException {
try (InputStream in = Files.newInputStream(src.toPath())) {
org.apache.commons.io.IOUtils.copy(in, out);
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
public static void copy(InputStream in, File out) throws IOException {
try (OutputStream fos = Files.newOutputStream(out.toPath())) {
org.apache.commons.io.IOUtils.copy(in, fos);
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
......
......@@ -6,6 +6,7 @@ import hudson.model.TaskListener;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import java.io.BufferedReader;
......@@ -112,6 +113,8 @@ public class SecretRewriter {
buf.append(line.substring(copied));
out.println(buf.toString());
}
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
......@@ -141,7 +144,7 @@ public class SecretRewriter {
String canonical;
try {
canonical = dir.toPath().toRealPath(new LinkOption[0]).toString();
} catch (IOException e) {
} catch (IOException | InvalidPathException e) {
canonical = dir.getAbsolutePath(); //
}
if (!callstack.add(canonical)) {
......
......@@ -42,7 +42,9 @@ import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.logging.Level;
import java.util.logging.Logger;
......@@ -96,7 +98,15 @@ public class StreamTaskListener extends AbstractTaskListener implements Serializ
// don't do buffering so that what's written to the listener
// gets reflected to the file immediately, which can then be
// served to the browser immediately
this(Files.newOutputStream(out.toPath()),charset);
this(Files.newOutputStream(asPath(out)), charset);
}
private static Path asPath(File out) throws IOException {
try {
return out.toPath();
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
/**
......@@ -113,7 +123,7 @@ public class StreamTaskListener extends AbstractTaskListener implements Serializ
// gets reflected to the file immediately, which can then be
// served to the browser immediately
this(Files.newOutputStream(
out.toPath(),
asPath(out),
StandardOpenOption.CREATE, append ? StandardOpenOption.APPEND: StandardOpenOption.TRUNCATE_EXISTING
),
charset
......@@ -149,7 +159,7 @@ public class StreamTaskListener extends AbstractTaskListener implements Serializ
out.print(prefix);
out.println(msg);
// the idiom in Hudson is to use the returned writer for writing stack trace,
// the idiom in Jenkins is to use the returned writer for writing stack trace,
// so put the marker here to indicate an exception. if the stack trace isn't actually written,
// HudsonExceptionNote.annotate recovers gracefully.
try {
......
......@@ -26,6 +26,7 @@ package hudson.util;
import com.google.common.collect.*;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import javax.annotation.Nonnull;
import java.io.BufferedReader;
import java.io.File;
......@@ -71,6 +72,8 @@ public class TextFile {
String line;
while ((line = in.readLine()) != null)
w.println(line);
} catch (InvalidPathException e) {
throw new IOException(e);
}
return out.toString();
}
......@@ -101,7 +104,7 @@ public class TextFile {
}
}
};
} catch (IOException e) {
} catch (IOException | InvalidPathException e) {
throw new RuntimeException(e);
}
}
......
......@@ -29,6 +29,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.NoSuchFileException;
import java.nio.file.StandardOpenOption;
......@@ -57,7 +58,7 @@ import java.nio.file.StandardOpenOption;
try {
current = Files.newOutputStream(out.toPath(), StandardOpenOption.CREATE,
appendOnNextOpen ? StandardOpenOption.APPEND : StandardOpenOption.TRUNCATE_EXISTING);
} catch (FileNotFoundException | NoSuchFileException e) {
} catch (FileNotFoundException | NoSuchFileException | InvalidPathException e) {
throw new IOException("Failed to open "+out,e);
}
return current;
......
......@@ -29,6 +29,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.NoSuchFileException;
import java.nio.file.StandardOpenOption;
import org.apache.commons.io.FileUtils;
......@@ -55,7 +56,7 @@ public class RewindableFileOutputStream extends OutputStream {
FileUtils.forceMkdir(out.getParentFile());
try {
current = Files.newOutputStream(out.toPath(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
} catch (FileNotFoundException | NoSuchFileException e) {
} catch (FileNotFoundException | NoSuchFileException | InvalidPathException e) {
throw new IOException("Failed to open "+out,e);
}
}
......
......@@ -36,6 +36,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.archivers.tar.TarConstants;
......@@ -108,7 +109,7 @@ final class TarArchiver extends Archiver {
while ((len = in.read(buf)) >= 0) {
tar.write(buf, 0, len);
}
} catch (IOException e) {// log the exception in any case
} catch (IOException | InvalidPathException e) {// log the exception in any case
IOException ioE = new IOException("Error writing to tar file from: " + file, e);
throw ioE;
}
......
......@@ -28,6 +28,7 @@ import hudson.util.FileVisitor;
import hudson.util.IOUtils;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
......@@ -75,6 +76,8 @@ final class ZipArchiver extends Archiver {
int len;
while((len=in.read(buf))>=0)
zip.write(buf,0,len);
} catch (InvalidPathException e) {
throw new IOException(e);
}
zip.closeEntry();
}
......
......@@ -24,6 +24,7 @@
package hudson.views;
import hudson.Extension;
import hudson.model.View;
import jenkins.model.GlobalConfiguration;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
......@@ -41,7 +42,18 @@ public class GlobalDefaultViewConfiguration extends GlobalConfiguration {
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
// for compatibility reasons, the actual value is stored in Jenkins
Jenkins j = Jenkins.getInstance();
j.setPrimaryView(json.has("primaryView") ? j.getView(json.getString("primaryView")) : j.getViews().iterator().next());
if (json.has("primaryView")) {
final String viewName = json.getString("primaryView");
final View newPrimaryView = j.getView(viewName);
if (newPrimaryView == null) {
throw new FormException(Messages.GlobalDefaultViewConfiguration_ViewDoesNotExist(viewName), "primaryView");
}
j.setPrimaryView(newPrimaryView);
} else {
// Fallback if the view is not specified
j.setPrimaryView(j.getViews().iterator().next());
}
return true;
}
}
......
......@@ -7,6 +7,7 @@ import hudson.Util;
import hudson.model.AdministrativeMonitor;
import hudson.util.jna.Kernel32Utils;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.OpenOption;
import java.nio.file.StandardOpenOption;
import jenkins.model.Jenkins;
......@@ -55,6 +56,8 @@ public class HsErrPidList extends AdministrativeMonitor {
try {
try (FileChannel ch = FileChannel.open(getSecretKeyFile().toPath(), StandardOpenOption.READ)) {
map = ch.map(MapMode.READ_ONLY,0,1);
} catch (InvalidPathException e) {
throw new IOException(e);
}
scan("./hs_err_pid%p.log");
......
......@@ -1824,7 +1824,14 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
return names;
}
public View getView(String name) {
/**
* Gets a view by the specified name.
* The method iterates through {@link hudson.model.ViewGroup}s if required.
* @param name Name of the view
* @return View instance or {@code null} if it is missing
*/
@CheckForNull
public View getView(@CheckForNull String name) {
return viewGroupMixIn.getView(name);
}
......@@ -1883,7 +1890,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
return viewGroupMixIn.getPrimaryView();
}
public void setPrimaryView(View v) {
public void setPrimaryView(@Nonnull View v) {
this.primaryView = v.getViewName();
}
......
......@@ -7,6 +7,7 @@ import hudson.util.TextFile;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import jenkins.model.Jenkins;
import javax.crypto.Cipher;
......@@ -82,6 +83,8 @@ public class DefaultConfidentialStore extends ConfidentialStore {
}
} catch (GeneralSecurityException e) {
throw new IOException("Failed to persist the key: "+key.getId(),e);
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
......@@ -106,6 +109,8 @@ public class DefaultConfidentialStore extends ConfidentialStore {
}
} catch (GeneralSecurityException e) {
throw new IOException("Failed to load the key: "+key.getId(),e);
} catch (InvalidPathException e) {
throw new IOException(e);
} catch (IOException x) {
if (x.getCause() instanceof BadPaddingException) {
return null; // broken somehow
......
......@@ -3,6 +3,7 @@ package jenkins.util;
import com.trilead.ssh2.crypto.Base64;
import hudson.util.FormValidation;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
import org.apache.commons.io.output.NullOutputStream;
......@@ -177,6 +178,8 @@ public class JSONSignatureValidator {
Certificate certificate;
try (InputStream in = Files.newInputStream(cert.toPath())) {
certificate = cf.generateCertificate(in);
} catch (InvalidPathException e) {
throw new IOException(e);
} catch (CertificateException e) {
LOGGER.log(Level.WARNING, String.format("Files in %s are expected to be either "
+ "certificates or .txt files documenting the certificates, "
......
......@@ -295,7 +295,11 @@ public abstract class VirtualFile implements Comparable<VirtualFile>, Serializab
if (isIllegalSymlink()) {
throw new FileNotFoundException(f.getPath());
}
return Files.newInputStream(f.toPath());
try {
return Files.newInputStream(f.toPath());
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
private boolean isIllegalSymlink() { // TODO JENKINS-26838
try {
......
package jenkins.util.io;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import jenkins.model.Jenkins;
import java.io.File;
......@@ -59,7 +60,7 @@ public class FileBoolean {
file.getParentFile().mkdirs();
Files.newOutputStream(file.toPath()).close();
get(); // update state
} catch (IOException e) {
} catch (IOException | InvalidPathException e) {
LOGGER.log(Level.WARNING, "Failed to touch "+file);
}
}
......
......@@ -2,6 +2,7 @@ package jenkins.util.xml;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import jenkins.util.SystemProperties;
import org.apache.commons.io.IOUtils;
import org.kohsuke.accmod.Restricted;
......@@ -142,6 +143,8 @@ public final class XMLUtils {
try (InputStream fileInputStream = Files.newInputStream(file.toPath());
InputStreamReader fileReader = new InputStreamReader(fileInputStream, encoding)) {
return parse(fileReader);
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
......
......@@ -30,3 +30,5 @@ StatusColumn.DisplayName=Status
WeatherColumn.DisplayName=Weather
DefaultViewsTabsBar.DisplayName=Default Views TabBar
DefaultMyViewsTabsBar.DisplayName=Default My Views TabBar
GlobalDefaultViewConfiguration.ViewDoesNotExist=The specified view does not exist: {0}
......@@ -33,7 +33,7 @@ THE SOFTWARE.
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>2.56-SNAPSHOT</version>
<version>2.57-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Jenkins main module</name>
......
#!/usr/bin/ruby
# The MIT License
#
# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# Moves the changelog from the trunk section to the release section
# Usage: rc.changelog.rb < changelog.html > output.html
changelog = []
inside = false;
ARGF.each do |line|
if /=TRUNK-BEGIN=/ =~ line
inside = true;
puts line
# new template
puts "<ul class=image>"
puts " <li class=>"
puts "</ul>"
next
end
if /=TRUNK-END=/ =~ line
inside = false;
puts line
next
end
if inside
changelog << line
next
end
if /=RC-CHANGES=/ =~ line
changelog.each { |line| puts line }
next
end
puts line
end
......@@ -28,7 +28,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>2.56-SNAPSHOT</version>
<version>2.57-SNAPSHOT</version>
</parent>
<artifactId>test</artifactId>
......
/*
* The MIT License
*
* Copyright (c) 2017 Oleg Nenashev.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.views;
import hudson.model.Descriptor;
import net.sf.json.JSONObject;
import static org.hamcrest.Matchers.*;
import org.junit.Assert;
import static org.junit.Assert.assertThat;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.kohsuke.stapler.MockStaplerRequestBuilder;
import org.kohsuke.stapler.StaplerRequest;
/**
* Tests of {@link GlobalDefaultViewConfiguration}.
* @author Oleg Nenashev
*/
public class GlobalDefaultViewConfigurationTest {
@Rule
public JenkinsRule j = new JenkinsRule();
@Test
@Issue("JENKINS-42717")
public void shouldNotFailIfTheDefaultViewIsMissing() {
String viewName = "NonExistentView";
GlobalDefaultViewConfiguration c = new GlobalDefaultViewConfiguration();
StaplerRequest create = new MockStaplerRequestBuilder(j, "/configure").build();
JSONObject params = new JSONObject();
params.accumulate("primaryView", viewName);
try {
c.configure(create, params);
} catch(Descriptor.FormException ex) {
assertThat("Wrong exception message for the form failure",
ex.getMessage(), containsString(Messages.GlobalDefaultViewConfiguration_ViewDoesNotExist(viewName)));
return;
}
Assert.fail("Expected FormException");
}
}
/*
* The MIT License
*
* Copyright (c) 2017 Oleg Nenashev.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.kohsuke.stapler;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import jenkins.model.Jenkins;
import org.eclipse.jetty.server.Request;
import org.jvnet.hudson.test.JenkinsRule;
import org.mockito.Mockito;
import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest;
/**
* Mocked version of {@link StaplerRequest}.
* @author Oleg Nenashev
*/
public class MockStaplerRequestBuilder{
private final JenkinsRule r;
private final List<AncestorImpl> ancestors = new ArrayList<>();
private final TokenList tokens;
final Map<String,Object> getters = new HashMap<>();
private Stapler stapler;
public MockStaplerRequestBuilder(@Nonnull JenkinsRule r, String url) {
this.r = r;
this.tokens = new TokenList(url);
}
public MockStaplerRequestBuilder withStapler(Stapler stapler) {
this.stapler = stapler;
return this;
}
public MockStaplerRequestBuilder withGetter(String objectName, Object object) {
this.getters.put(objectName, object);
return this;
}
public MockStaplerRequestBuilder withAncestor(AncestorImpl ancestor) {
this.ancestors.add(ancestor);
return this;
}
public StaplerRequest build() throws AssertionError {
HttpServletRequest rawRequest = Mockito.mock(HttpServletRequest.class);
return new RequestImpl(stapler != null ? stapler : new Stapler(), rawRequest, ancestors, tokens);
}
}
......@@ -28,7 +28,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>2.56-SNAPSHOT</version>
<version>2.57-SNAPSHOT</version>
</parent>
<artifactId>jenkins-war</artifactId>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册