From 11e815fcc3235fab14039465c6bc63d7ad0cac7f Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Wed, 26 Sep 2018 15:14:14 -0700 Subject: [PATCH] Do not use buffer limit as indicator of frame completion. If the frame happens to be exactly the same size as the buffer capacity, we will erroneously think that the last frame was complete because the limit is normally at the buffer capacity. This only exploded when we had both a perfectly sized frame and failed to read it in a single call to read, which apparently took 17 years to happen, and many billions of frames read. --- .../main/java/com/threerings/io/FramedInputStream.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/threerings/io/FramedInputStream.java b/core/src/main/java/com/threerings/io/FramedInputStream.java index 6fdeb4ce3..484620133 100644 --- a/core/src/main/java/com/threerings/io/FramedInputStream.java +++ b/core/src/main/java/com/threerings/io/FramedInputStream.java @@ -80,7 +80,9 @@ public class FramedInputStream extends InputStream throws IOException { // flush data from any previous frame from the buffer - if (_buffer.limit() == _length) { + if (_haveCompleteFrame) { + _haveCompleteFrame = false; + // this will remove the old frame's bytes from the buffer, // shift our old data to the start of the buffer, position the // buffer appropriately for appending new data onto the end of @@ -179,6 +181,7 @@ public class FramedInputStream extends InputStream // prepare the buffer such that this frame can be read _buffer.position(HEADER_SIZE); _buffer.limit(_length); + _haveCompleteFrame = true; return true; } @@ -312,6 +315,9 @@ public class FramedInputStream extends InputStream * may comprise more than one frame. */ protected int _have = 0; + /** Tracks whether we read a complete frame in our last call to {@link #readFrame}. */ + protected boolean _haveCompleteFrame; + /** The size of the frame header (a 32-bit integer). */ protected static final int HEADER_SIZE = 4;