mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Allow empty frames.
This commit is contained in:
@@ -54,7 +54,7 @@ implements ConnectionReader {
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if(betweenFrames && !readFrame()) return -1;
|
||||
if(betweenFrames && !readNonEmptyFrame()) return -1;
|
||||
int i = payload[payloadOff];
|
||||
payloadOff++;
|
||||
payloadLen--;
|
||||
@@ -69,7 +69,7 @@ implements ConnectionReader {
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if(betweenFrames && !readFrame()) return -1;
|
||||
if(betweenFrames && !readNonEmptyFrame()) return -1;
|
||||
len = Math.min(len, payloadLen);
|
||||
System.arraycopy(payload, payloadOff, b, off, len);
|
||||
payloadOff += len;
|
||||
@@ -78,7 +78,15 @@ implements ConnectionReader {
|
||||
return len;
|
||||
}
|
||||
|
||||
private boolean readFrame() throws IOException {
|
||||
private boolean readNonEmptyFrame() throws IOException {
|
||||
int payload = 0;
|
||||
do {
|
||||
payload = readFrame();
|
||||
} while(payload == 0);
|
||||
return payload > 0;
|
||||
}
|
||||
|
||||
private int readFrame() throws IOException {
|
||||
assert betweenFrames;
|
||||
// Don't allow more than 2^32 frames to be read
|
||||
if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException();
|
||||
@@ -89,7 +97,7 @@ implements ConnectionReader {
|
||||
if(read == -1) break;
|
||||
offset += read;
|
||||
}
|
||||
if(offset == 0) return false; // EOF between frames
|
||||
if(offset == 0) return -1; // EOF between frames
|
||||
if(offset < header.length) throw new EOFException(); // Unexpected EOF
|
||||
// Check that the frame number is correct and the length is legal
|
||||
if(!HeaderEncoder.validateHeader(header, frame, maxPayloadLength))
|
||||
@@ -122,8 +130,8 @@ implements ConnectionReader {
|
||||
byte[] expectedMac = mac.doFinal();
|
||||
decrypter.readMac(footer);
|
||||
if(!Arrays.equals(expectedMac, footer)) throw new FormatException();
|
||||
betweenFrames = false;
|
||||
frame++;
|
||||
return true;
|
||||
if(payloadLen > 0) betweenFrames = false;
|
||||
return payloadLen;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package net.sf.briar.transport;
|
||||
|
||||
import net.sf.briar.api.transport.TransportConstants;
|
||||
import static net.sf.briar.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
|
||||
import net.sf.briar.util.ByteUtils;
|
||||
|
||||
class HeaderEncoder {
|
||||
|
||||
static void encodeHeader(byte[] header, long frame, int payload,
|
||||
int padding) {
|
||||
if(header.length < TransportConstants.FRAME_HEADER_LENGTH)
|
||||
if(header.length < FRAME_HEADER_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
if(frame < 0 || frame > ByteUtils.MAX_32_BIT_UNSIGNED)
|
||||
throw new IllegalArgumentException();
|
||||
@@ -21,24 +21,22 @@ class HeaderEncoder {
|
||||
}
|
||||
|
||||
static boolean validateHeader(byte[] header, long frame, int max) {
|
||||
if(header.length < TransportConstants.FRAME_HEADER_LENGTH)
|
||||
return false;
|
||||
if(header.length < FRAME_HEADER_LENGTH) return false;
|
||||
if(ByteUtils.readUint32(header, 0) != frame) return false;
|
||||
int payload = ByteUtils.readUint16(header, 4);
|
||||
int padding = ByteUtils.readUint16(header, 6);
|
||||
if(payload + padding == 0) return false;
|
||||
if(payload + padding > max) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int getPayloadLength(byte[] header) {
|
||||
if(header.length < TransportConstants.FRAME_HEADER_LENGTH)
|
||||
if(header.length < FRAME_HEADER_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
return ByteUtils.readUint16(header, 4);
|
||||
}
|
||||
|
||||
static int getPaddingLength(byte[] header) {
|
||||
if(header.length < TransportConstants.FRAME_HEADER_LENGTH)
|
||||
if(header.length < FRAME_HEADER_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
return ByteUtils.readUint16(header, 6);
|
||||
}
|
||||
|
||||
@@ -33,10 +33,8 @@ public class ConnectionReaderImplTest extends TransportTest {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(frame);
|
||||
ConnectionDecrypter d = new NullConnectionDecrypter(in);
|
||||
ConnectionReader r = new ConnectionReaderImpl(d, mac, macKey);
|
||||
try {
|
||||
r.getInputStream().read();
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
// There should be no bytes available before EOF
|
||||
assertEquals(-1, r.getInputStream().read());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user