diff --git a/runtime/src/main/java/org/capnproto/Serialize.java b/runtime/src/main/java/org/capnproto/Serialize.java index 5e7a7f4..c8720be 100644 --- a/runtime/src/main/java/org/capnproto/Serialize.java +++ b/runtime/src/main/java/org/capnproto/Serialize.java @@ -82,6 +82,10 @@ public final class Serialize { segment0Size = firstWord.getInt(4); } + if (segment0Size < 0) { + throw new DecodeException("segment 0 has more than 2^31 words, which is unsupported"); + } + long totalWords = segment0Size; // in words @@ -92,6 +96,11 @@ public final class Serialize { fillBuffer(moreSizesRaw, bc); for (int ii = 0; ii < segmentCount - 1; ++ii) { int size = moreSizesRaw.getInt(ii * 4); + if (size < 0) { + throw new DecodeException("segment " + (ii + 1) + + " has more than 2^31 words, which is unsupported"); + } + moreSizes.add(size); totalWords += size; } diff --git a/runtime/src/test/java/org/capnproto/SerializeTest.java b/runtime/src/test/java/org/capnproto/SerializeTest.java index b83cb85..3fdcc0a 100644 --- a/runtime/src/test/java/org/capnproto/SerializeTest.java +++ b/runtime/src/test/java/org/capnproto/SerializeTest.java @@ -129,4 +129,22 @@ public class SerializeTest { 3, 0, 0, 0, 0, 0, 0, 0 }); } + + @Test(expected=DecodeException.class) + public void testSegment0SizeOverflow() throws java.io.IOException { + byte[] input = {0, 0, 0, 0, -1, -1, -1, -113}; + java.nio.channels.ReadableByteChannel channel = + java.nio.channels.Channels.newChannel(new java.io.ByteArrayInputStream(input)); + MessageReader message = Serialize.read(channel); + } + + @Test(expected=DecodeException.class) + public void testSegment1SizeOverflow() throws java.io.IOException { + byte[] input = { + 1, 0, 0, 0, 1, 0, 0, 0, + -1, -1, -1, -113, 0, 0, 0, 0}; + java.nio.channels.ReadableByteChannel channel = + java.nio.channels.Channels.newChannel(new java.io.ByteArrayInputStream(input)); + MessageReader message = Serialize.read(channel); + } }