Skip to content

Commit

Permalink
Guard against read producing a too-long String
Browse files Browse the repository at this point in the history
Badly-behaved #read implementations may produce String output that
exceeds the requested length, as theorized in jruby#8391. If
this code blindly attempts to copy all bytes from such a String,
it may cause an ArrayIndexOutOfBoundsError when it writes over the
end of the passed-in buffer.

This change guards against such #read implementations by raising
a hard error; we do not maintain a buffer in this class, so we
can't just hold onto the extra bytes, and we don't want to just
silently discard them. A hard error will let a user of this class
find bad #read implementations more quickly and fix the real
problem.

Fixes bug #1 from jruby#8391.
  • Loading branch information
headius committed Oct 30, 2024
1 parent a34ed75 commit 477d0aa
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions core/src/main/java/org/jruby/util/IOInputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,15 @@ public int read(byte[] b, int off, int len) throws IOException {
if (readValue.isNil()) return -1;

ByteList str = readValue.convertToString().getByteList();
System.arraycopy(str.getUnsafeBytes(), str.getBegin(), b, off, str.getRealSize());

return str.getRealSize();
int readSize = str.realSize();

if (readSize > len) {
throw runtime.newIOError("read call of " + len + " bytes produced a String of length " + readSize);
}

System.arraycopy(str.getUnsafeBytes(), str.getBegin(), b, off, readSize);

return readSize;
}
}

0 comments on commit 477d0aa

Please sign in to comment.