From d044a11bc0e812f18f96bef57b10597f55f3ee4a Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Mon, 22 Jun 2015 12:09:47 -0700 Subject: [PATCH] Switch to varin32 for contact input/output stream headers. // FREEBIE --- .../DeviceContactsInputStream.java | 43 ++++++++++++++----- .../DeviceContactsOutputStream.java | 10 ++--- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceContactsInputStream.java b/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceContactsInputStream.java index d66727f3bd..a7164fa3bb 100644 --- a/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceContactsInputStream.java +++ b/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceContactsInputStream.java @@ -18,7 +18,7 @@ public class DeviceContactsInputStream { } public DeviceContact read() throws IOException { - long detailsLength = readRawVarint64(); + long detailsLength = readRawVarint32(); byte[] detailsSerialized = new byte[(int)detailsLength]; Util.readFully(in, detailsSerialized); @@ -38,19 +38,40 @@ public class DeviceContactsInputStream { return new DeviceContact(number, name, avatar); } - private long readRawVarint64() throws IOException { - int shift = 0; - long result = 0; - while (shift < 64) { - final byte b = (byte)in.read(); - result |= (long)(b & 0x7F) << shift; - if ((b & 0x80) == 0) { - return result; + public int readRawVarint32() throws IOException { + byte tmp = (byte)in.read(); + if (tmp >= 0) { + return tmp; + } + int result = tmp & 0x7f; + if ((tmp = (byte)in.read()) >= 0) { + result |= tmp << 7; + } else { + result |= (tmp & 0x7f) << 7; + if ((tmp = (byte)in.read()) >= 0) { + result |= tmp << 14; + } else { + result |= (tmp & 0x7f) << 14; + if ((tmp = (byte)in.read()) >= 0) { + result |= tmp << 21; + } else { + result |= (tmp & 0x7f) << 21; + result |= (tmp = (byte)in.read()) << 28; + if (tmp < 0) { + // Discard upper 32 bits. + for (int i = 0; i < 5; i++) { + if ((byte)in.read() >= 0) { + return result; + } + } + + throw new IOException("Malformed varint!"); + } + } } - shift += 7; } - throw new IOException("Malformed varint!"); + return result; } private static final class LimitedInputStream extends FilterInputStream { diff --git a/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceContactsOutputStream.java b/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceContactsOutputStream.java index ea160e5191..fec53abdf7 100644 --- a/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceContactsOutputStream.java +++ b/java/src/main/java/org/whispersystems/textsecure/api/messages/multidevice/DeviceContactsOutputStream.java @@ -56,17 +56,17 @@ public class DeviceContactsOutputStream { byte[] serializedContactDetails = contactDetails.build().toByteArray(); - writeVarint64(serializedContactDetails.length); + writeVarint32(serializedContactDetails.length); out.write(serializedContactDetails); } - public void writeVarint64(long value) throws IOException { + private void writeVarint32(int value) throws IOException { while (true) { - if ((value & ~0x7FL) == 0) { - out.write((int) value); + if ((value & ~0x7F) == 0) { + out.write(value); return; } else { - out.write(((int) value & 0x7F) | 0x80); + out.write((value & 0x7F) | 0x80); value >>>= 7; } }