diff --git a/core/pom.xml b/core/pom.xml
index 4c49c99bf807..a0e54f858013 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -250,6 +250,12 @@ THE SOFTWARE.
org.connectbot
jbcrypt
+
+ org.eclipse.jetty
+ jetty-server
+ 9.4.51.v20230217
+ compile
+
org.fusesource.jansi
diff --git a/core/src/main/java/hudson/console/AnnotatedLargeText.java b/core/src/main/java/hudson/console/AnnotatedLargeText.java
index 963435afe1ae..35d5641c10d6 100644
--- a/core/src/main/java/hudson/console/AnnotatedLargeText.java
+++ b/core/src/main/java/hudson/console/AnnotatedLargeText.java
@@ -197,16 +197,20 @@ private ConsoleAnnotator createAnnotator(StaplerRequest2 req) throws IOExcept
private ConsoleAnnotator getConsoleAnnotator(ObjectInputStream ois) throws IOException, ClassNotFoundException {
return (ConsoleAnnotator) ois.readObject();
}
-
@CheckReturnValue
@Override
public long writeLogTo(long start, Writer w) throws IOException {
- if (isHtml())
+ if (isHtml()) {
return writeHtmlTo(start, w);
- else
- return super.writeLogTo(start, w);
+ }
+
+ long bytesRead = super.writeLogTo(start, w);
+ w.flush();
+
+ return bytesRead;
}
+
/**
* Strips annotations using a {@link PlainTextConsoleOutputStream}.
* {@inheritDoc}
@@ -231,17 +235,29 @@ public long writeHtmlTo(long start, Writer w) throws IOException {
ConsoleAnnotationOutputStream caw = new ConsoleAnnotationOutputStream<>(
w, createAnnotator(Stapler.getCurrentRequest2()), context, charset);
long r = super.writeLogTo(start, caw);
+ long bytesRead = 0;
+
+ try (Writer writer = w) {
+ bytesRead = super.writeLogTo(start, writer);
+ writer.flush();
+ }
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Cipher sym = PASSING_ANNOTATOR.encrypt();
- ObjectOutputStream oos = AnonymousClassWarnings.checkingObjectOutputStream(new GZIPOutputStream(new CipherOutputStream(baos, sym)));
- oos.writeLong(System.currentTimeMillis()); // send timestamp to prevent a replay attack
+ ObjectOutputStream oos = AnonymousClassWarnings.checkingObjectOutputStream(
+ new GZIPOutputStream(new CipherOutputStream(baos, sym))
+ );
+
+ oos.writeLong(System.currentTimeMillis());
oos.writeObject(caw.getConsoleAnnotator());
oos.close();
+
StaplerResponse2 rsp = Stapler.getCurrentResponse2();
- if (rsp != null)
+ if (rsp != null) {
rsp.setHeader("X-ConsoleAnnotator", Base64.getEncoder().encodeToString(baos.toByteArray()));
- return r;
+ }
+
+ return bytesRead;
}
/**
diff --git a/core/src/main/java/hudson/util/ChunkedInputStream.java b/core/src/main/java/hudson/util/ChunkedInputStream.java
index cfe61a17fcf1..f4fff97bfe19 100644
--- a/core/src/main/java/hudson/util/ChunkedInputStream.java
+++ b/core/src/main/java/hudson/util/ChunkedInputStream.java
@@ -134,6 +134,9 @@ public int read(byte[] b, int off, int len) throws IOException {
len = Math.min(len, chunkSize - pos);
int count = in.read(b, off, len);
pos += count;
+ if (pos >= chunkSize) {
+ in.skip(2);
+ }
return count;
}
@@ -273,6 +276,9 @@ private static int getChunkSizeFromInputStream(final InputStream in)
} catch (NumberFormatException e) {
throw new IOException("Bad chunk size: " + dataString, e);
}
+ if (result > 10 * 1024 * 1024) {
+ throw new IOException("Chunk size too large: " + result);
+ }
return result;
}