13
0
geforkt von Mirrors/Velocity

Fix issues with decoding and Java fallback native

Dieser Commit ist enthalten in:
Andrew Steinborn 2019-10-19 23:56:44 -04:00
Ursprung a16684564b
Commit 6ff5cac4d3
4 geänderte Dateien mit 36 neuen und 20 gelöschten Zeilen

Datei anzeigen

@ -37,12 +37,13 @@ public class JavaVelocityCipher implements VelocityCipher {
@Override @Override
public void process(ByteBuf source) { public void process(ByteBuf source) {
ensureNotDisposed(); ensureNotDisposed();
Preconditions.checkArgument(source.hasArray(), "No source array");
int inBytes = source.readableBytes(); int inBytes = source.readableBytes();
byte[] asBytes = ByteBufUtil.getBytes(source);
try { try {
cipher.update(asBytes, 0, inBytes, asBytes); cipher.update(source.array(), source.arrayOffset(), inBytes, source.array(),
source.arrayOffset());
} catch (ShortBufferException ex) { } catch (ShortBufferException ex) {
/* This _really_ shouldn't happen - AES CFB8 will work in place. /* This _really_ shouldn't happen - AES CFB8 will work in place.
If you run into this, that means that for whatever reason the Java Runtime has determined If you run into this, that means that for whatever reason the Java Runtime has determined
@ -64,6 +65,6 @@ public class JavaVelocityCipher implements VelocityCipher {
@Override @Override
public BufferPreference preferredBufferType() { public BufferPreference preferredBufferType() {
return BufferPreference.HEAP_PREFERRED; return BufferPreference.HEAP_REQUIRED;
} }
} }

Datei anzeigen

@ -1,6 +1,10 @@
package com.velocitypowered.natives.util; package com.velocitypowered.natives.util;
public enum BufferPreference { public enum BufferPreference {
/**
* A heap buffer is required.
*/
HEAP_REQUIRED,
/** /**
* A heap buffer is preferred (but not required). * A heap buffer is preferred (but not required).
*/ */

Datei anzeigen

@ -20,28 +20,30 @@ public class MoreByteBufUtils {
* @return a buffer compatible with the native * @return a buffer compatible with the native
*/ */
public static ByteBuf ensureCompatible(ByteBufAllocator alloc, Native nativeStuff, ByteBuf buf) { public static ByteBuf ensureCompatible(ByteBufAllocator alloc, Native nativeStuff, ByteBuf buf) {
if (nativeStuff.preferredBufferType() != BufferPreference.DIRECT_REQUIRED if (isCompatible(nativeStuff, buf)) {
|| buf.hasMemoryAddress()) {
return buf.retain(); return buf.retain();
} }
// It's not, so we must make a direct copy. // It's not, so we must make a direct copy.
ByteBuf newBuf = alloc.directBuffer(buf.readableBytes()); ByteBuf newBuf = preferredBuffer(alloc, nativeStuff, buf.readableBytes());
newBuf.writeBytes(buf); newBuf.writeBytes(buf);
return newBuf; return newBuf;
} }
/** private static boolean isCompatible(Native nativeStuff, ByteBuf buf) {
* Creates a {@link ByteBuf} that will have the best performance with the specified BufferPreference preferred = nativeStuff.preferredBufferType();
* {@code nativeStuff}. switch (preferred) {
* case DIRECT_PREFERRED:
* @param alloc the {@link ByteBufAllocator} to use case HEAP_PREFERRED:
* @param nativeStuff the native we are working with // The native prefers this type, but doesn't strictly require we provide it.
* @return a buffer compatible with the native return true;
*/ case DIRECT_REQUIRED:
public static ByteBuf preferredBuffer(ByteBufAllocator alloc, Native nativeStuff) { return buf.hasMemoryAddress();
return nativeStuff.preferredBufferType() != BufferPreference.HEAP_PREFERRED case HEAP_REQUIRED:
? alloc.directBuffer() : alloc.heapBuffer(); return buf.hasArray();
default:
throw new AssertionError("Preferred buffer type unknown");
}
} }
/** /**
@ -55,7 +57,15 @@ public class MoreByteBufUtils {
*/ */
public static ByteBuf preferredBuffer(ByteBufAllocator alloc, Native nativeStuff, public static ByteBuf preferredBuffer(ByteBufAllocator alloc, Native nativeStuff,
int initialCapacity) { int initialCapacity) {
return nativeStuff.preferredBufferType() != BufferPreference.HEAP_PREFERRED switch (nativeStuff.preferredBufferType()) {
? alloc.directBuffer(initialCapacity) : alloc.heapBuffer(initialCapacity); case HEAP_REQUIRED:
case HEAP_PREFERRED:
return alloc.heapBuffer(initialCapacity);
case DIRECT_PREFERRED:
case DIRECT_REQUIRED:
return alloc.directBuffer(initialCapacity);
default:
throw new AssertionError("Preferred buffer type unknown");
}
} }
} }

Datei anzeigen

@ -18,10 +18,11 @@ public class MinecraftCipherDecoder extends ByteToMessageDecoder {
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
ByteBuf compatible = MoreByteBufUtils.ensureCompatible(ctx.alloc(), cipher, in); ByteBuf compatible = MoreByteBufUtils.ensureCompatible(ctx.alloc(), cipher, in).slice();
try { try {
cipher.process(compatible); cipher.process(compatible);
out.add(compatible); out.add(compatible);
in.skipBytes(in.readableBytes());
} catch (Exception e) { } catch (Exception e) {
compatible.release(); // compatible will never be used if we throw an exception compatible.release(); // compatible will never be used if we throw an exception
throw e; throw e;