diff --git a/runtime/src/main/java/org/capnproto/MessageReader.java b/runtime/src/main/java/org/capnproto/MessageReader.java index cc6cbd5..3b1dad5 100644 --- a/runtime/src/main/java/org/capnproto/MessageReader.java +++ b/runtime/src/main/java/org/capnproto/MessageReader.java @@ -27,12 +27,9 @@ public final class MessageReader { final ReaderArena arena; final int nestingLimit; - final static long DEFAULT_TRAVERSAL_LIMIT_IN_WORDS = 8 * 1024 * 1024; - final static int DEFAULT_NESTING_LIMIT = 64; - - public MessageReader(ByteBuffer[] segmentSlices, long traversalLimitInWords, int nestingLimit) { - this.nestingLimit = nestingLimit; - this.arena = new ReaderArena(segmentSlices, traversalLimitInWords); + public MessageReader(ByteBuffer[] segmentSlices, ReaderOptions options) { + this.nestingLimit = options.nestingLimit; + this.arena = new ReaderArena(segmentSlices, options.traversalLimitInWords); } public T getRoot(FromPointerReader factory) { diff --git a/runtime/src/main/java/org/capnproto/ReaderOptions.java b/runtime/src/main/java/org/capnproto/ReaderOptions.java new file mode 100644 index 0000000..fa22b40 --- /dev/null +++ b/runtime/src/main/java/org/capnproto/ReaderOptions.java @@ -0,0 +1,39 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package org.capnproto; + +public final class ReaderOptions { + public final long traversalLimitInWords; + public final int nestingLimit; + + public ReaderOptions(long traversalLimitInWords, int nestingLimit) { + this.traversalLimitInWords = traversalLimitInWords; + this.nestingLimit = nestingLimit; + } + + final static long DEFAULT_TRAVERSAL_LIMIT_IN_WORDS = 8 * 1024 * 1024; + final static int DEFAULT_NESTING_LIMIT = 64; + + public static final ReaderOptions DEFAULT_READER_OPTIONS = + new ReaderOptions(DEFAULT_TRAVERSAL_LIMIT_IN_WORDS, DEFAULT_NESTING_LIMIT); + +} diff --git a/runtime/src/main/java/org/capnproto/Serialize.java b/runtime/src/main/java/org/capnproto/Serialize.java index d9fe344..a84a69a 100644 --- a/runtime/src/main/java/org/capnproto/Serialize.java +++ b/runtime/src/main/java/org/capnproto/Serialize.java @@ -48,10 +48,10 @@ public final class Serialize { } public static MessageReader read(ReadableByteChannel bc) throws IOException { - return read(bc, MessageReader.DEFAULT_TRAVERSAL_LIMIT_IN_WORDS, MessageReader.DEFAULT_NESTING_LIMIT); + return read(bc, ReaderOptions.DEFAULT_READER_OPTIONS); } - public static MessageReader read(ReadableByteChannel bc, long traversalLimitInWords, int nestingLimit) throws IOException { + public static MessageReader read(ReadableByteChannel bc, ReaderOptions options) throws IOException { ByteBuffer firstWord = makeByteBuffer(Constants.BYTES_PER_WORD); fillBuffer(firstWord, bc); @@ -81,8 +81,7 @@ public final class Serialize { } } - // TODO check that totalWords is reasonable - if (totalWords > traversalLimitInWords) { + if (totalWords > options.traversalLimitInWords) { throw new DecodeException("Message size exceeds traversal limit."); } @@ -105,7 +104,7 @@ public final class Serialize { offset += moreSizes.get(ii - 1); } - return new MessageReader(segmentSlices, traversalLimitInWords, nestingLimit); + return new MessageReader(segmentSlices, options); } public static void write(WritableByteChannel outputChannel, diff --git a/runtime/src/main/java/org/capnproto/SerializePacked.java b/runtime/src/main/java/org/capnproto/SerializePacked.java index dcddc55..caf10dc 100644 --- a/runtime/src/main/java/org/capnproto/SerializePacked.java +++ b/runtime/src/main/java/org/capnproto/SerializePacked.java @@ -24,13 +24,22 @@ package org.capnproto; public final class SerializePacked { public static MessageReader read(BufferedInputStream input) throws java.io.IOException { + return read(input, ReaderOptions.DEFAULT_READER_OPTIONS); + } + + public static MessageReader read(BufferedInputStream input, ReaderOptions options) throws java.io.IOException { PackedInputStream packedInput = new PackedInputStream(input); - return Serialize.read(packedInput); + return Serialize.read(packedInput, options); } public static MessageReader readUnbuffered(java.nio.channels.ReadableByteChannel input) throws java.io.IOException { + return readUnbuffered(input, ReaderOptions.DEFAULT_READER_OPTIONS); + } + + public static MessageReader readUnbuffered(java.nio.channels.ReadableByteChannel input, + ReaderOptions options) throws java.io.IOException { PackedInputStream packedInput = new PackedInputStream(new BufferedInputStreamWrapper(input)); - return Serialize.read(packedInput); + return Serialize.read(packedInput, options); } public static void write(BufferedOutputStream output,