diff --git a/src/hub/dataSources/wpilog/indexer/wpilogIndexer.c b/src/hub/dataSources/wpilog/indexer/wpilogIndexer.c index 79602cd3..fbc93d40 100644 --- a/src/hub/dataSources/wpilog/indexer/wpilogIndexer.c +++ b/src/hub/dataSources/wpilog/indexer/wpilogIndexer.c @@ -36,12 +36,19 @@ void* run(void* buffer, int bufferSize) { uint8_t dataSizeLength = ((lengthBitfield >> 2) & 0x3) + 1; uint8_t timestampLength = ((lengthBitfield >> 4) & 0x7) + 1; uint8_t headerLength = 1 + entryLength + dataSizeLength + timestampLength; + if (bufferSize < offset + headerLength) { + break; + } uint32_t entry = readVarInt(buffer, offset + 1, entryLength); uint32_t dataSize = readVarInt(buffer, offset + 1 + entryLength, dataSizeLength); int64_t timestamp = readVarInt( buffer, offset + 1 + entryLength + dataSizeLength, timestampLength); + if (bufferSize < offset + headerLength + dataSize || entry < 0 || + dataSize < 0) { + break; + } // Update timestamp range if (entry != CONTROL_ENTRY) { diff --git a/src/hub/dataSources/wpilog/wpilogWorker.ts b/src/hub/dataSources/wpilog/wpilogWorker.ts index 03b0a55e..32585217 100644 --- a/src/hub/dataSources/wpilog/wpilogWorker.ts +++ b/src/hub/dataSources/wpilog/wpilogWorker.ts @@ -48,56 +48,56 @@ async function start(data: Uint8Array) { (entry, position) => { if (entry === CONTROL_ENTRY) { let record = decoder?.getRecordAtPosition(position)[0]; - if (record === null || record === undefined) { - console.warn("Encountered invalid control record at offset", position); - } else if (record.isStart()) { - const startData = record.getStartData(); - entryIds[startData.entry] = startData.name; - entryTypes[startData.name] = startData.type; - dataRecordPositions[startData.name] = []; - switch (startData.type) { - case "boolean": - log.createBlankField(startData.name, LoggableType.Boolean); - break; - case "int": - case "int64": - case "float": - case "double": - log.createBlankField(startData.name, LoggableType.Number); - break; - case "string": - case "json": - log.createBlankField(startData.name, LoggableType.String); - break; - case "boolean[]": - log.createBlankField(startData.name, LoggableType.BooleanArray); - break; - case "int[]": - case "int64[]": - case "float[]": - case "double[]": - log.createBlankField(startData.name, LoggableType.NumberArray); - break; - case "string[]": - log.createBlankField(startData.name, LoggableType.StringArray); - break; - default: // Default to raw - log.createBlankField(startData.name, LoggableType.Raw); - if (startData.type.startsWith(STRUCT_PREFIX)) { - let schemaType = startData.type.split(STRUCT_PREFIX)[1]; - log.setStructuredType(startData.name, schemaType); - } else if (startData.type.startsWith(PROTO_PREFIX)) { - let schemaType = startData.type.split(PROTO_PREFIX)[1]; - log.setStructuredType(startData.name, schemaType); - } - break; - } - log.setWpilibType(startData.name, startData.type); - log.setMetadataString(startData.name, startData.metadata); - } else if (record.isSetMetadata()) { - let setMetadataData = record.getSetMetadataData(); - if (setMetadataData.entry in entryIds) { - log.setMetadataString(entryIds[setMetadataData.entry], setMetadataData.metadata); + if (record !== null && record !== undefined) { + if (record.isStart()) { + const startData = record.getStartData(); + entryIds[startData.entry] = startData.name; + entryTypes[startData.name] = startData.type; + dataRecordPositions[startData.name] = []; + switch (startData.type) { + case "boolean": + log.createBlankField(startData.name, LoggableType.Boolean); + break; + case "int": + case "int64": + case "float": + case "double": + log.createBlankField(startData.name, LoggableType.Number); + break; + case "string": + case "json": + log.createBlankField(startData.name, LoggableType.String); + break; + case "boolean[]": + log.createBlankField(startData.name, LoggableType.BooleanArray); + break; + case "int[]": + case "int64[]": + case "float[]": + case "double[]": + log.createBlankField(startData.name, LoggableType.NumberArray); + break; + case "string[]": + log.createBlankField(startData.name, LoggableType.StringArray); + break; + default: // Default to raw + log.createBlankField(startData.name, LoggableType.Raw); + if (startData.type.startsWith(STRUCT_PREFIX)) { + let schemaType = startData.type.split(STRUCT_PREFIX)[1]; + log.setStructuredType(startData.name, schemaType); + } else if (startData.type.startsWith(PROTO_PREFIX)) { + let schemaType = startData.type.split(PROTO_PREFIX)[1]; + log.setStructuredType(startData.name, schemaType); + } + break; + } + log.setWpilibType(startData.name, startData.type); + log.setMetadataString(startData.name, startData.metadata); + } else if (record.isSetMetadata()) { + let setMetadataData = record.getSetMetadataData(); + if (setMetadataData.entry in entryIds) { + log.setMetadataString(entryIds[setMetadataData.entry], setMetadataData.metadata); + } } } } else if (entry in entryIds) {