Patching Cleanup

This commit is contained in:
Brian Neumann-Fopiano
2026-09-11 00:38:08 -04:00
parent bf12f30d26
commit 29a31a69e0
44 changed files with 1340 additions and 970 deletions
@@ -125,13 +125,7 @@ public final class IrisWireReader {
* @throws ProtocolException if the length is negative or exceeds the remaining bytes
*/
public String readString() throws ProtocolException {
int declaredLength = readVarInt();
if (declaredLength < 0) {
throw new ProtocolException("negative string length");
}
if (declaredLength > remaining()) {
throw new ProtocolException("string length exceeds remaining frame bytes");
}
int declaredLength = readLength("negative string length", "string length exceeds remaining frame bytes");
String value = new String(frame, position, declaredLength, StandardCharsets.UTF_8);
position += declaredLength;
return value;
@@ -143,19 +137,24 @@ public final class IrisWireReader {
* @throws ProtocolException if the length is negative or exceeds the remaining bytes
*/
public byte[] readBytes() throws ProtocolException {
int declaredLength = readVarInt();
if (declaredLength < 0) {
throw new ProtocolException("negative byte array length");
}
if (declaredLength > remaining()) {
throw new ProtocolException("byte array length exceeds remaining frame bytes");
}
int declaredLength = readLength("negative byte array length", "byte array length exceeds remaining frame bytes");
byte[] value = new byte[declaredLength];
System.arraycopy(frame, position, value, 0, declaredLength);
position += declaredLength;
return value;
}
private int readLength(String negativeMessage, String oversizedMessage) throws ProtocolException {
int declaredLength = readVarInt();
if (declaredLength < 0) {
throw new ProtocolException(negativeMessage);
}
if (declaredLength > remaining()) {
throw new ProtocolException(oversizedMessage);
}
return declaredLength;
}
private int remaining() {
return limit - position;
}
@@ -104,11 +104,7 @@ public final class IrisWireWriter {
* Writes a varint-length-prefixed UTF-8 string. {@code value} must not be null.
*/
public void writeString(String value) {
byte[] encoded = value.getBytes(StandardCharsets.UTF_8);
writeVarInt(encoded.length);
ensure(encoded.length);
System.arraycopy(encoded, 0, buffer, length, encoded.length);
length += encoded.length;
writeBytes(value.getBytes(StandardCharsets.UTF_8));
}
/**
@@ -0,0 +1,87 @@
package art.arcane.iris.spi.protocol;
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class IrisWirePayloadTest {
@Test
public void preservesMixedPayloadEncodingAndIndependentCopies() throws Exception {
IrisWireWriter writer = new IrisWireWriter();
byte[] payload = {0, (byte) 0xff};
writer.writeString("é\u0000");
writer.writeBytes(payload);
writer.writeString("");
writer.writeBytes(new byte[0]);
writer.writeInt(0x12345678);
payload[0] = 42;
byte[] frame = writer.toByteArray();
assertArrayEquals(new byte[]{3, (byte) 0xc3, (byte) 0xa9, 0, 2, 0, (byte) 0xff,
0, 0, 0x12, 0x34, 0x56, 0x78}, frame);
IrisWireReader reader = new IrisWireReader(frame);
assertEquals("é\u0000", reader.readString());
byte[] decoded = reader.readBytes();
assertArrayEquals(new byte[]{0, (byte) 0xff}, decoded);
decoded[0] = 42;
assertEquals(0, frame[5]);
assertEquals("", reader.readString());
assertArrayEquals(new byte[0], reader.readBytes());
assertEquals(0x12345678, reader.readInt());
}
@Test
public void preservesPayloadLengthErrorsAndConsumesOnlyThePrefix() throws Exception {
byte[] negative = {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x0f, 1};
byte[] oversized = {2, 1};
IrisWireReader negativeString = new IrisWireReader(negative);
IrisWireReader negativeBytes = new IrisWireReader(negative);
IrisWireReader oversizedString = new IrisWireReader(oversized);
IrisWireReader oversizedBytes = new IrisWireReader(oversized);
assertEquals("negative string length", assertThrows(ProtocolException.class, negativeString::readString).getMessage());
assertEquals("negative byte array length", assertThrows(ProtocolException.class, negativeBytes::readBytes).getMessage());
assertEquals("string length exceeds remaining frame bytes",
assertThrows(ProtocolException.class, oversizedString::readString).getMessage());
assertEquals("byte array length exceeds remaining frame bytes",
assertThrows(ProtocolException.class, oversizedBytes::readBytes).getMessage());
assertTrue(negativeString.readBoolean());
assertTrue(negativeBytes.readBoolean());
assertTrue(oversizedString.readBoolean());
assertTrue(oversizedBytes.readBoolean());
}
@Test
public void preservesFrameCapAndPrefixWrittenBeforePayloadOverflow() {
int maximumPayload = IrisProtocol.MAX_FRAME_BYTES - 3;
IrisWireWriter exactString = new IrisWireWriter();
IrisWireWriter exactBytes = new IrisWireWriter();
exactString.writeString("x".repeat(maximumPayload));
exactBytes.writeBytes(new byte[maximumPayload]);
assertEquals(IrisProtocol.MAX_FRAME_BYTES, exactString.toByteArray().length);
assertEquals(IrisProtocol.MAX_FRAME_BYTES, exactBytes.toByteArray().length);
IrisWireWriter oversizedString = new IrisWireWriter();
IrisWireWriter oversizedBytes = new IrisWireWriter();
IrisWireWriter prefix = new IrisWireWriter();
prefix.writeVarInt(maximumPayload + 1);
String message = "Iris protocol frame exceeds " + IrisProtocol.MAX_FRAME_BYTES + " byte cap";
assertEquals(message, assertThrows(IllegalStateException.class,
() -> oversizedString.writeString("x".repeat(maximumPayload + 1))).getMessage());
assertEquals(message, assertThrows(IllegalStateException.class,
() -> oversizedBytes.writeBytes(new byte[maximumPayload + 1])).getMessage());
assertArrayEquals(prefix.toByteArray(), oversizedString.toByteArray());
assertArrayEquals(prefix.toByteArray(), oversizedBytes.toByteArray());
}
@Test
public void rejectsNullPayloadsWithoutWriting() {
IrisWireWriter writer = new IrisWireWriter();
assertThrows(NullPointerException.class, () -> writer.writeString(null));
assertThrows(NullPointerException.class, () -> writer.writeBytes(null));
assertArrayEquals(new byte[0], writer.toByteArray());
}
}