mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-09 03:37:03 +01:00
Garmin: Fix crash on large gpx import
This commit is contained in:
parent
79c2fc21a4
commit
0e985d5461
@ -128,7 +128,7 @@ public class FitFile {
|
|||||||
if (!canGenerateOutput)
|
if (!canGenerateOutput)
|
||||||
throw new IllegalArgumentException("Generation of previously parsed FIT file not supported.");
|
throw new IllegalArgumentException("Generation of previously parsed FIT file not supported.");
|
||||||
|
|
||||||
MessageWriter temporary = new MessageWriter();
|
MessageWriter temporary = new MessageWriter(writer.getLimit());
|
||||||
temporary.setByteOrder(ByteOrder.LITTLE_ENDIAN);
|
temporary.setByteOrder(ByteOrder.LITTLE_ENDIAN);
|
||||||
RecordDefinition prevDefinition = null;
|
RecordDefinition prevDefinition = null;
|
||||||
for (final RecordData rd : dataRecords) {
|
for (final RecordData rd : dataRecords) {
|
||||||
@ -147,7 +147,24 @@ public class FitFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getOutgoingMessage() {
|
public byte[] getOutgoingMessage() {
|
||||||
final MessageWriter writer = new MessageWriter();
|
// Compute the worst case scenario buffer size for the fit file
|
||||||
|
// A ~1.6MB gpx file with ~16k points results in a ~320KB buffer, ~150KB of which get actually used
|
||||||
|
final int dataRecordsSize = dataRecords.stream()
|
||||||
|
.mapToInt(r -> {
|
||||||
|
// Worst case scenario, for each data record
|
||||||
|
|
||||||
|
// one distinct record definition: 5 bytes + (number of field definitions * 3 + 1)
|
||||||
|
final List<FieldDefinition> definitions = r.getRecordDefinition().getFieldDefinitions();
|
||||||
|
final int recordDefinitionOverhead = 5 + (definitions != null ? definitions.size() * 3 + 1 : 0);
|
||||||
|
|
||||||
|
// 1 + size of the value holder
|
||||||
|
final int dataRecordOverhead = 1 + r.valueHolder.limit();
|
||||||
|
|
||||||
|
return recordDefinitionOverhead + dataRecordOverhead;
|
||||||
|
}).sum();
|
||||||
|
|
||||||
|
// Final size = 14b header + data records + 2b crc
|
||||||
|
final MessageWriter writer = new MessageWriter(14 + dataRecordsSize + 2);
|
||||||
this.generateOutgoingDataPayload(writer);
|
this.generateOutgoingDataPayload(writer);
|
||||||
return writer.getBytes();
|
return writer.getBytes();
|
||||||
}
|
}
|
||||||
|
@ -57,8 +57,6 @@ public class MessageWriter {
|
|||||||
final int size = bytes.length;
|
final int size = bytes.length;
|
||||||
if (size > 255) throw new IllegalArgumentException("Too long string");
|
if (size > 255) throw new IllegalArgumentException("Too long string");
|
||||||
|
|
||||||
if (byteBuffer.position() + 1 + size > byteBuffer.capacity())
|
|
||||||
throw new IllegalStateException();
|
|
||||||
byteBuffer.put((byte) size);
|
byteBuffer.put((byte) size);
|
||||||
byteBuffer.put(bytes);
|
byteBuffer.put(bytes);
|
||||||
}
|
}
|
||||||
@ -76,12 +74,15 @@ public class MessageWriter {
|
|||||||
return byteBuffer.position();
|
return byteBuffer.position();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getLimit() {
|
||||||
|
return byteBuffer.limit();
|
||||||
|
}
|
||||||
|
|
||||||
public void writeBytes(byte[] bytes) {
|
public void writeBytes(byte[] bytes) {
|
||||||
writeBytes(bytes, 0, bytes.length);
|
writeBytes(bytes, 0, bytes.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeBytes(byte[] bytes, int offset, int size) {
|
public void writeBytes(byte[] bytes, int offset, int size) {
|
||||||
if (byteBuffer.position() + size > byteBuffer.capacity()) throw new IllegalStateException();
|
|
||||||
byteBuffer.put(Arrays.copyOfRange(bytes, offset, offset + size));
|
byteBuffer.put(Arrays.copyOfRange(bytes, offset, offset + size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user