Closed cervm closed 1 month ago
thanks
fixed in 1.33.5
What device was that? I may check the Android port if I have time for this case.
I don't see a way it could break.
lets say bytes.length
is 2
fieldLen
is 1
and n
is 1
then this check will still work // Ensuring we don't go past the bytes array
Map<Integer, byte[]> getManufacturerSpecificData(ScanRecord adv) {
byte[] bytes = adv.getBytes();
Map<Integer, byte[]> manufacturerDataMap = new HashMap<>();
int n = 0;
while (n < bytes.length) {
// layout:
// n[0] = fieldlen
// n[1] = datatype (MSD)
// n[2] = manufacturerId (low)
// n[3] = manufacturerId (high)
// n[4] = data...
int fieldLen = bytes[n] & 0xFF;
// no more or malformed data
if (fieldLen <= 0) {
break;
}
// Ensuring we don't go past the bytes array
if (n + fieldLen >= bytes.length) {
break;
}
int dataType = bytes[n + 1] & 0xFF;
// Manufacturer Specific Data magic number
// At least 3 bytes: 2 for manufacturer ID & 1 for dataType
if (dataType == 0xFF && fieldLen >= 3) {
// Manufacturer Id
int high = (bytes[n + 3] & 0xFF) << 8;
int low = (bytes[n + 2] & 0xFF);
int manufacturerId = high | low;
// the length of the msd data,
// excluding manufacturerId & dataType
int msdLen = fieldLen - 3;
// ptr to msd data
// excluding manufacturerId & dataType
int msdPtr = n + 4;
// add to map
if (manufacturerDataMap.containsKey(manufacturerId)) {
// If the manufacturer ID already exists, append the new data to the existing list
byte[] existingData = manufacturerDataMap.get(manufacturerId);
byte[] mergedData = new byte[existingData.length + msdLen];
// Merge arrays
System.arraycopy(existingData, 0, mergedData, 0, existingData.length);
System.arraycopy(bytes, msdPtr, mergedData, existingData.length, msdLen);
manufacturerDataMap.put(manufacturerId, mergedData);
} else {
// Otherwise, put the new manufacturer ID and its data into the map
byte[] data = new byte[msdLen];
// Starting from n+4 because manufacturerId occupies n+2 and n+3
System.arraycopy(bytes, msdPtr, data, 0, data.length);
manufacturerDataMap.put(manufacturerId, data);
}
}
n += fieldLen + 1;
}
return manufacturerDataMap;
}
Our app was crashing when a nearby device advertised with only 1 byte of data. This was due to the assumption that the first two bytes always contained the manufacturer ID. This fix prevents going to a negative index causing the app to crash completely.