Merge remote-tracking branch 'sandstorm/master'

This commit is contained in:
Vaci Koblizek 2022-05-02 17:18:21 +01:00
commit 949103ca5d
4 changed files with 33 additions and 6 deletions

View file

@ -23,7 +23,7 @@ clean :
rm -f capnpc-java capnpc-java.exe rm -f capnpc-java capnpc-java.exe
capnpc-java : $(CAPNPC_JAVA_SOURCES) capnpc-java : $(CAPNPC_JAVA_SOURCES)
$(CXX) $(CAPNPC_JAVA_SOURCES) $(CXX_FLAGS) -o capnpc-java $(CXX) $(CAPNPC_JAVA_SOURCES) $(CXX_FLAGS) $(CFLAGS) $(LDFLAGS) -o capnpc-java
install: install:
mkdir -p ${PREFIX}/bin mkdir -p ${PREFIX}/bin

View file

@ -44,6 +44,6 @@ public class SegmentReader {
public final boolean in_bounds(int start, int size) { public final boolean in_bounds(int start, int size) {
if (start < 0 || size < 0) return false; if (start < 0 || size < 0) return false;
long sizeInWords = size * Constants.BYTES_PER_WORD; long sizeInWords = size * Constants.BYTES_PER_WORD;
return (long) start + sizeInWords < (long) this.buffer.capacity(); return (long) start + sizeInWords <= (long) this.buffer.capacity();
} }
} }

View file

@ -947,13 +947,18 @@ final class WireHelpers {
int refTarget = WirePointer.target(refOffset, ref); int refTarget = WirePointer.target(refOffset, ref);
FollowFarsResult resolved = followFars(ref, refTarget, segment); FollowFarsResult resolved = followFars(ref, refTarget, segment);
int dataSizeWords = StructPointer.dataSize(resolved.ref);
if (WirePointer.kind(resolved.ref) != WirePointer.STRUCT) { if (WirePointer.kind(resolved.ref) != WirePointer.STRUCT) {
throw new DecodeException("Message contains non-struct pointer where struct pointer was expected."); throw new DecodeException("Message contains non-struct pointer where struct pointer was expected.");
} }
resolved.segment.arena.checkReadLimit(StructPointer.wordSize(resolved.ref)); int dataSizeWords = StructPointer.dataSize(resolved.ref);
int ptrCount = StructPointer.ptrCount(resolved.ref);
int wordSize = dataSizeWords + ptrCount;
resolved.segment.arena.checkReadLimit(wordSize);
if (!bounds_check(resolved.segment, resolved.ptr, wordSize)) {
throw new DecodeException("Message contains out-of-bounds struct pointer");
}
return factory.constructReader(resolved.segment, return factory.constructReader(resolved.segment,
capTable, capTable,
@ -962,7 +967,6 @@ final class WireHelpers {
dataSizeWords * Constants.BITS_PER_WORD, dataSizeWords * Constants.BITS_PER_WORD,
(short)StructPointer.ptrCount(resolved.ref), (short)StructPointer.ptrCount(resolved.ref),
nestingLimit - 1); nestingLimit - 1);
} }
static StructReader readStructPointer(SegmentReader segment, static StructReader readStructPointer(SegmentReader segment,

View file

@ -63,6 +63,29 @@ public class LayoutTest {
Assert.assertEquals(reader._getBooleanField(64), false); Assert.assertEquals(reader._getBooleanField(64), false);
} }
/**
* @see <a href="https://github.com/capnproto/capnproto-java/issues/122">#122</a>
*/
@Test(expected = DecodeException.class)
public void readStructPointerShouldThrowDecodeExceptionOnOutOfBoundsStructPointer() {
byte[] brokenMSG = new byte[]{
0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, //declare word size of 7, with payload of only 6 words
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
ByteBuffer buffer = ByteBuffer.wrap(brokenMSG);
buffer.order(ByteOrder.LITTLE_ENDIAN);
ReaderArena arena = new ReaderArena(new ByteBuffer[]{ buffer }, 0x7fffffffffffffffL);
StructReader reader = WireHelpers.readStructPointer(new BareStructReader(), arena.tryGetSegment(0), null, 0, null, 0, 0x7fffffff);
}
private class BareStructBuilder implements StructBuilder.Factory<StructBuilder> { private class BareStructBuilder implements StructBuilder.Factory<StructBuilder> {
private StructSize structSize; private StructSize structSize;