Skip to content

Commit

Permalink
Custom exception for buffer over/underflow (#874)
Browse files Browse the repository at this point in the history
* More specific exceptions for buffer over/underflow

* cleaning leftovers

* formatted code and junit5 style exception tests

* Removed KryoIOException

Co-authored-by: msx80 <msx80@github>
  • Loading branch information
msx80 and msx80 authored Jan 20, 2022
1 parent 1304ec5 commit b1cb816
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/com/esotericsoftware/kryo/Kryo.java
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ public void addDefaultSerializer (Class type, SerializerFactory serializerFactor
/** Instances with the specified class name will use the specified serializer when {@link #register(Class)} or
* {@link #register(Class, int)} are called.
* @see #setDefaultSerializer(Class) */
private void addDefaultSerializer(String className, Class<? extends Serializer> serializer) {
private void addDefaultSerializer (String className, Class<? extends Serializer> serializer) {
try {
addDefaultSerializer(Class.forName(className), serializer);
} catch (ClassNotFoundException e) {
Expand Down
5 changes: 3 additions & 2 deletions src/com/esotericsoftware/kryo/io/ByteBufferInput.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package com.esotericsoftware.kryo.io;

import com.esotericsoftware.kryo.KryoException;
import com.esotericsoftware.kryo.io.KryoBufferUnderflowException;
import com.esotericsoftware.kryo.util.Util;

import java.io.IOException;
Expand Down Expand Up @@ -169,7 +170,7 @@ protected int require (int required) throws KryoException {
// Try to fill the buffer.
if (remaining > 0) {
count = fill(byteBuffer, limit, capacity - limit);
if (count == -1) throw new KryoException("Buffer underflow.");
if (count == -1) throw new KryoBufferUnderflowException("Buffer underflow.");
setBufferPosition(byteBuffer, position);
remaining += count;
if (remaining >= required) {
Expand All @@ -188,7 +189,7 @@ protected int require (int required) throws KryoException {
count = fill(byteBuffer, remaining, capacity - remaining);
if (count == -1) {
if (remaining >= required) break;
throw new KryoException("Buffer underflow.");
throw new KryoBufferUnderflowException("Buffer underflow.");
}
remaining += count;
if (remaining >= required) break; // Enough has been read.
Expand Down
6 changes: 4 additions & 2 deletions src/com/esotericsoftware/kryo/io/ByteBufferOutput.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package com.esotericsoftware.kryo.io;

import com.esotericsoftware.kryo.KryoException;
import com.esotericsoftware.kryo.io.KryoBufferOverflowException;
import com.esotericsoftware.kryo.util.Util;

import java.io.IOException;
Expand Down Expand Up @@ -184,8 +185,9 @@ protected boolean require (int required) throws KryoException {
if (capacity - position >= required) return true;
if (required > maxCapacity - position) {
if (required > maxCapacity)
throw new KryoException("Buffer overflow. Max capacity: " + maxCapacity + ", required: " + required);
throw new KryoException("Buffer overflow. Available: " + (maxCapacity - position) + ", required: " + required);
throw new KryoBufferOverflowException("Buffer overflow. Max capacity: " + maxCapacity + ", required: " + required);
throw new KryoBufferOverflowException(
"Buffer overflow. Available: " + (maxCapacity - position) + ", required: " + required);
}
if (capacity == 0) capacity = 16;
do {
Expand Down
8 changes: 5 additions & 3 deletions src/com/esotericsoftware/kryo/io/Input.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package com.esotericsoftware.kryo.io;

import com.esotericsoftware.kryo.KryoException;
import com.esotericsoftware.kryo.io.KryoBufferUnderflowException;
import com.esotericsoftware.kryo.util.Pool.Poolable;
import com.esotericsoftware.kryo.util.Util;

Expand Down Expand Up @@ -189,7 +190,8 @@ protected int fill (byte[] buffer, int offset, int count) throws KryoException {
/** Fills the buffer with at least the number of bytes specified.
* @param required Must be > 0.
* @return The number of bytes remaining in the buffer, which will be at least <code>required</code> bytes.
* @throws KryoException if {@link #fill(byte[], int, int)} is unable to provide more bytes (buffer underflow). */
* @throws KryoBufferUnderflowException if {@link #fill(byte[], int, int)} is unable to provide more bytes (buffer
* underflow). */
protected int require (int required) throws KryoException {
int remaining = limit - position;
if (remaining >= required) return remaining;
Expand All @@ -199,7 +201,7 @@ protected int require (int required) throws KryoException {
// Try to fill the buffer.
if (remaining > 0) {
count = fill(buffer, limit, capacity - limit);
if (count == -1) throw new KryoException("Buffer underflow.");
if (count == -1) throw new KryoBufferUnderflowException("Buffer underflow.");
remaining += count;
if (remaining >= required) {
limit += count;
Expand All @@ -216,7 +218,7 @@ protected int require (int required) throws KryoException {
count = fill(buffer, remaining, capacity - remaining);
if (count == -1) {
if (remaining >= required) break;
throw new KryoException("Buffer underflow.");
throw new KryoBufferUnderflowException("Buffer underflow.");
}
remaining += count;
if (remaining >= required) break; // Enough has been read.
Expand Down
41 changes: 41 additions & 0 deletions src/com/esotericsoftware/kryo/io/KryoBufferOverflowException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* Copyright (c) 2008-2020, Nathan Sweet
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */

package com.esotericsoftware.kryo.io;

import com.esotericsoftware.kryo.KryoException;

public class KryoBufferOverflowException extends KryoException {

public KryoBufferOverflowException () {
super();
}

public KryoBufferOverflowException (String message, Throwable cause) {
super(message, cause);
}

public KryoBufferOverflowException (String message) {
super(message);
}

public KryoBufferOverflowException (Throwable cause) {
super(cause);
}
}
41 changes: 41 additions & 0 deletions src/com/esotericsoftware/kryo/io/KryoBufferUnderflowException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* Copyright (c) 2008-2020, Nathan Sweet
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */

package com.esotericsoftware.kryo.io;

import com.esotericsoftware.kryo.KryoException;

public class KryoBufferUnderflowException extends KryoException {

public KryoBufferUnderflowException () {
super();
}

public KryoBufferUnderflowException (String message, Throwable cause) {
super(message, cause);
}

public KryoBufferUnderflowException (String message) {
super(message);
}

public KryoBufferUnderflowException (Throwable cause) {
super(cause);
}
}
6 changes: 4 additions & 2 deletions src/com/esotericsoftware/kryo/io/Output.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package com.esotericsoftware.kryo.io;

import com.esotericsoftware.kryo.KryoException;
import com.esotericsoftware.kryo.io.KryoBufferOverflowException;
import com.esotericsoftware.kryo.util.Pool.Poolable;
import com.esotericsoftware.kryo.util.Util;

Expand Down Expand Up @@ -182,8 +183,9 @@ protected boolean require (int required) throws KryoException {
if (capacity - position >= required) return true;
if (required > maxCapacity - position) {
if (required > maxCapacity)
throw new KryoException("Buffer overflow. Max capacity: " + maxCapacity + ", required: " + required);
throw new KryoException("Buffer overflow. Available: " + (maxCapacity - position) + ", required: " + required);
throw new KryoBufferOverflowException("Buffer overflow. Max capacity: " + maxCapacity + ", required: " + required);
throw new KryoBufferOverflowException(
"Buffer overflow. Available: " + (maxCapacity - position) + ", required: " + required);
}
if (capacity == 0) capacity = 16;
do {
Expand Down
29 changes: 29 additions & 0 deletions test/com/esotericsoftware/kryo/io/ByteBufferInputOutputTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import static org.junit.jupiter.api.Assertions.*;

import com.esotericsoftware.kryo.KryoTestCase;
import com.esotericsoftware.kryo.io.KryoBufferOverflowException;
import com.esotericsoftware.kryo.io.KryoBufferUnderflowException;

import java.io.ByteArrayInputStream;
import java.nio.Buffer;
Expand Down Expand Up @@ -87,4 +89,31 @@ void testByteBufferOutputPosition () {
assertEquals(10, inputBuffer.readInt());
assertEquals(9, byteBuffer.position());
}

@Test
void testOverflow () {
ByteBufferOutput buffer = new ByteBufferOutput(1);
buffer.writeByte(51);
KryoBufferOverflowException thrown = assertThrows(
KryoBufferOverflowException.class,
() -> buffer.writeByte(65),
"Exception expected but none thrown"
);

assertTrue(thrown.getMessage().startsWith("Buffer overflow"));
}

@Test
void testUnderflow () {
ByteBufferInput buffer = new ByteBufferInput(1);

KryoBufferUnderflowException thrown = assertThrows(
KryoBufferUnderflowException.class,
() -> buffer.readBytes(2),
"Exception expected but none thrown"
);

assertTrue(thrown.getMessage().equals("Buffer underflow."));
}

}
29 changes: 29 additions & 0 deletions test/com/esotericsoftware/kryo/io/InputOutputTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.KryoTestCase;
import com.esotericsoftware.kryo.Registration;
import com.esotericsoftware.kryo.io.KryoBufferUnderflowException;
import com.esotericsoftware.kryo.io.KryoBufferOverflowException;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
Expand Down Expand Up @@ -110,6 +112,33 @@ void testWriteBytes () throws IOException {
61, 62, 63, 64, 65}, buffer.toBytes());
}

@Test
void testOverflow () throws IOException {
Output buffer = new Output(1);
buffer.writeByte(51);

KryoBufferOverflowException thrown = assertThrows(
KryoBufferOverflowException.class,
() -> buffer.writeByte(65),
"Exception expected but none thrown"
);

assertTrue(thrown.getMessage().startsWith("Buffer overflow"));
}

@Test
void testUnderflow () throws IOException {
Input buffer = new Input(1);

KryoBufferUnderflowException thrown = assertThrows(
KryoBufferUnderflowException.class,
() -> buffer.readBytes(2),
"Exception expected but none thrown"
);

assertTrue(thrown.getMessage().equals("Buffer underflow."));
}

@Test
void testStrings () throws IOException {
runStringTest(new Output(4096));
Expand Down

0 comments on commit b1cb816

Please sign in to comment.