Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow InputStreamStreamInput array size validation where applicable #26692

Merged
merged 3 commits into from
Sep 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,28 @@
public class InputStreamStreamInput extends StreamInput {

private final InputStream is;
private final long sizeLimit;

/**
* Creates a new InputStreamStreamInput with unlimited size
* @param is the input stream to wrap
*/
public InputStreamStreamInput(InputStream is) {
this(is, Long.MAX_VALUE);
}

/**
* Creates a new InputStreamStreamInput with a size limit
* @param is the input stream to wrap
* @param sizeLimit a hard limit of the number of bytes in the given input stream. This is used for internal input validation
*/
public InputStreamStreamInput(InputStream is, long sizeLimit) {
this.is = is;
if (sizeLimit < 0) {
throw new IllegalArgumentException("size limit must be positive");
}
this.sizeLimit = sizeLimit;

}

@Override
Expand Down Expand Up @@ -98,6 +117,8 @@ public long skip(long n) throws IOException {

@Override
protected void ensureCanReadBytes(int length) throws EOFException {
// TODO what can we do here?
if (length > sizeLimit) {
throw new EOFException("tried to read: " + length + " bytes but this stream is limited to: " + sizeLimit);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,7 @@ public static StreamInput wrap(byte[] bytes) {
}

public static StreamInput wrap(byte[] bytes, int offset, int length) {
return new InputStreamStreamInput(new ByteArrayInputStream(bytes, offset, length));
return new InputStreamStreamInput(new ByteArrayInputStream(bytes, offset, length), length);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ public static TranslogReader open(
final FileChannel channel, final Path path, final Checkpoint checkpoint, final String translogUUID) throws IOException {

try {
InputStreamStreamInput headerStream = new InputStreamStreamInput(java.nio.channels.Channels.newInputStream(channel)); // don't close
InputStreamStreamInput headerStream = new InputStreamStreamInput(java.nio.channels.Channels.newInputStream(channel),
channel.size()); // don't close
// Lucene's CodecUtil writes a magic number of 0x3FD76C17 with the
// header, in binary this looks like:
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.elasticsearch.test.ESTestCase;

import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -192,6 +193,22 @@ public void testInputStreamStreamInputDelegatesAvailable() throws IOException {
assertEquals(streamInput.available(), length - bytesToRead);
}

public void testReadArraySize() throws IOException {
BytesStreamOutput stream = new BytesStreamOutput();
byte[] array = new byte[randomIntBetween(1, 10)];
for (int i = 0; i < array.length; i++) {
array[i] = randomByte();
}
stream.writeByteArray(array);
InputStreamStreamInput streamInput = new InputStreamStreamInput(StreamInput.wrap(BytesReference.toBytes(stream.bytes())), array
.length-1);
expectThrows(EOFException.class, streamInput::readByteArray);
streamInput = new InputStreamStreamInput(StreamInput.wrap(BytesReference.toBytes(stream.bytes())), BytesReference.toBytes(stream
.bytes()).length);

assertArrayEquals(array, streamInput.readByteArray());
}

public void testWritableArrays() throws IOException {

final String[] strings = generateRandomStringArray(10, 10, false, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,8 @@ static PercolateQuery.QueryStore createStore(MappedFieldType queryBuilderFieldTy
if (binaryDocValues.advanceExact(docId)) {
BytesRef qbSource = binaryDocValues.binaryValue();
try (InputStream in = new ByteArrayInputStream(qbSource.bytes, qbSource.offset, qbSource.length)) {
try (StreamInput input = new NamedWriteableAwareStreamInput(new InputStreamStreamInput(in), registry)) {
try (StreamInput input = new NamedWriteableAwareStreamInput(
new InputStreamStreamInput(in, qbSource.length), registry)) {
input.setVersion(indexVersion);
// Query builder's content is stored via BinaryFieldMapper, which has a custom encoding
// to encode multiple binary values into a single binary doc values field.
Expand Down