Fix explicitly little-endian accessors in SwappedByteBuf (#10747)

Motivation:
Some buffers implement ByteBuf#order(order) by wrapping themselves in a SwappedByteBuf.
The SwappedByteBuf is then responsible for swapping the byte order on accesses.
The explicitly little-endian accessor methods, however, should not be swapped to big-endian, but instead remain explicitly little-endian.

Modification:
The SwappedByteBuf was passing through calls to e.g. writeIntLE, to the big-endian equivalent, e.g. writeInt.
This has been changed so that these calls delegate to their explicitly little-endian counterpart.

Result:
This makes all buffers that make use of SwappedByteBuf for their endian-ness configuration, consistent with all the buffers that use other implementation strategies.
In the end, all buffers now behave exactly the same, when using their explicitly little-endian accessor methods.
This commit is contained in:
Chris Vest 2020-10-29 10:35:47 +01:00 committed by GitHub
parent b4edf21bd3
commit 96da45de2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 14 deletions

View File

@ -438,7 +438,8 @@ public final class ByteBufUtil {
*/
@SuppressWarnings("deprecation")
public static ByteBuf writeShortBE(ByteBuf buf, int shortValue) {
return buf.order() == ByteOrder.BIG_ENDIAN? buf.writeShort(shortValue) : buf.writeShortLE(shortValue);
return buf.order() == ByteOrder.BIG_ENDIAN? buf.writeShort(shortValue) :
buf.writeShort(swapShort((short) shortValue));
}
/**
@ -446,7 +447,8 @@ public final class ByteBufUtil {
*/
@SuppressWarnings("deprecation")
public static ByteBuf setShortBE(ByteBuf buf, int index, int shortValue) {
return buf.order() == ByteOrder.BIG_ENDIAN? buf.setShort(index, shortValue) : buf.setShortLE(index, shortValue);
return buf.order() == ByteOrder.BIG_ENDIAN? buf.setShort(index, shortValue) :
buf.setShort(index, swapShort((short) shortValue));
}
/**
@ -454,7 +456,8 @@ public final class ByteBufUtil {
*/
@SuppressWarnings("deprecation")
public static ByteBuf writeMediumBE(ByteBuf buf, int mediumValue) {
return buf.order() == ByteOrder.BIG_ENDIAN? buf.writeMedium(mediumValue) : buf.writeMediumLE(mediumValue);
return buf.order() == ByteOrder.BIG_ENDIAN? buf.writeMedium(mediumValue) :
buf.writeMedium(swapMedium(mediumValue));
}
/**

View File

@ -543,7 +543,7 @@ public class SwappedByteBuf extends ByteBuf {
@Override
public short readShortLE() {
return buf.readShort();
return buf.readShortLE();
}
@Override
@ -563,7 +563,7 @@ public class SwappedByteBuf extends ByteBuf {
@Override
public int readMediumLE() {
return buf.readMedium();
return buf.readMediumLE();
}
@Override
@ -583,7 +583,7 @@ public class SwappedByteBuf extends ByteBuf {
@Override
public int readIntLE() {
return buf.readInt();
return buf.readIntLE();
}
@Override
@ -603,7 +603,7 @@ public class SwappedByteBuf extends ByteBuf {
@Override
public long readLongLE() {
return buf.readLong();
return buf.readLongLE();
}
@Override
@ -719,7 +719,7 @@ public class SwappedByteBuf extends ByteBuf {
@Override
public ByteBuf writeShortLE(int value) {
buf.writeShort((short) value);
buf.writeShortLE((short) value);
return this;
}
@ -731,7 +731,7 @@ public class SwappedByteBuf extends ByteBuf {
@Override
public ByteBuf writeMediumLE(int value) {
buf.writeMedium(value);
buf.writeMediumLE(value);
return this;
}
@ -743,7 +743,7 @@ public class SwappedByteBuf extends ByteBuf {
@Override
public ByteBuf writeIntLE(int value) {
buf.writeInt(value);
buf.writeIntLE(value);
return this;
}
@ -755,7 +755,7 @@ public class SwappedByteBuf extends ByteBuf {
@Override
public ByteBuf writeLongLE(long value) {
buf.writeLong(value);
buf.writeLongLE(value);
return this;
}

View File

@ -4939,4 +4939,63 @@ public abstract class AbstractByteBufTest {
buffer.release();
}
}
@Test
public void testEndiannessIndexOf() {
buffer.clear();
final int v = 0x02030201;
buffer.writeIntLE(v);
buffer.writeByte(0x01);
assertEquals(-1, buffer.indexOf(1, 4, (byte) 1));
assertEquals(-1, buffer.indexOf(4, 1, (byte) 1));
assertEquals(1, buffer.indexOf(1, 4, (byte) 2));
assertEquals(3, buffer.indexOf(4, 1, (byte) 2));
}
@Test
public void explicitLittleEndianReadMethodsMustAlwaysUseLittleEndianByteOrder() {
buffer.clear();
buffer.writeBytes(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08});
assertEquals(0x0201, buffer.readShortLE());
buffer.readerIndex(0);
assertEquals(0x0201, buffer.readUnsignedShortLE());
buffer.readerIndex(0);
assertEquals(0x030201, buffer.readMediumLE());
buffer.readerIndex(0);
assertEquals(0x030201, buffer.readUnsignedMediumLE());
buffer.readerIndex(0);
assertEquals(0x04030201, buffer.readIntLE());
buffer.readerIndex(0);
assertEquals(0x04030201, buffer.readUnsignedIntLE());
buffer.readerIndex(0);
assertEquals(0x04030201, Float.floatToRawIntBits(buffer.readFloatLE()));
buffer.readerIndex(0);
assertEquals(0x0807060504030201L, buffer.readLongLE());
buffer.readerIndex(0);
assertEquals(0x0807060504030201L, Double.doubleToRawLongBits(buffer.readDoubleLE()));
buffer.readerIndex(0);
}
@Test
public void explicitLittleEndianWriteMethodsMustAlwaysUseLittleEndianByteOrder() {
buffer.clear();
buffer.writeShortLE(0x0102);
assertEquals(0x0102, buffer.readShortLE());
buffer.clear();
buffer.writeMediumLE(0x010203);
assertEquals(0x010203, buffer.readMediumLE());
buffer.clear();
buffer.writeIntLE(0x01020304);
assertEquals(0x01020304, buffer.readIntLE());
buffer.clear();
buffer.writeFloatLE(Float.intBitsToFloat(0x01020304));
assertEquals(0x01020304, Float.floatToRawIntBits(buffer.readFloatLE()));
buffer.clear();
buffer.writeLongLE(0x0102030405060708L);
assertEquals(0x0102030405060708L, buffer.readLongLE());
buffer.clear();
buffer.writeDoubleLE(Double.longBitsToDouble(0x0102030405060708L));
assertEquals(0x0102030405060708L, Double.doubleToRawLongBits(buffer.readDoubleLE()));
}
}

View File

@ -189,7 +189,7 @@ public class ByteBufUtilTest {
buf = buffer(2).order(ByteOrder.LITTLE_ENDIAN);
ByteBufUtil.writeShortBE(buf, expected);
assertEquals((short) expected, buf.readShortLE());
assertEquals(ByteBufUtil.swapShort((short) expected), buf.readShortLE());
buf.resetReaderIndex();
assertEquals(ByteBufUtil.swapShort((short) expected), buf.readShort());
buf.release();
@ -209,7 +209,7 @@ public class ByteBufUtilTest {
buf = Unpooled.wrappedBuffer(new byte[2]).order(ByteOrder.LITTLE_ENDIAN);
ByteBufUtil.setShortBE(buf, 0, shortValue);
assertEquals((short) shortValue, buf.readShortLE());
assertEquals(ByteBufUtil.swapShort((short) shortValue), buf.readShortLE());
buf.resetReaderIndex();
assertEquals(ByteBufUtil.swapShort((short) shortValue), buf.readShort());
buf.release();
@ -229,7 +229,7 @@ public class ByteBufUtilTest {
buf = buffer(4).order(ByteOrder.LITTLE_ENDIAN);
ByteBufUtil.writeMediumBE(buf, mediumValue);
assertEquals(mediumValue, buf.readMediumLE());
assertEquals(ByteBufUtil.swapMedium(mediumValue), buf.readMediumLE());
buf.resetReaderIndex();
assertEquals(ByteBufUtil.swapMedium(mediumValue), buf.readMedium());
buf.release();