mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
scpfluxsource: Support more than 5 revolutions
This prevents uninitialized memory reads for files with many revolutions. See #322.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include "fluxmap.h"
|
||||
#include "kryoflux.h"
|
||||
#include "lib/fluxsource/fluxsource.pb.h"
|
||||
#include "lib/utils.h"
|
||||
#include "fluxsource/fluxsource.h"
|
||||
#include "scp.h"
|
||||
#include "proto.h"
|
||||
@@ -57,20 +58,31 @@ public:
|
||||
std::unique_ptr<Fluxmap> readFlux(int track, int side)
|
||||
{
|
||||
int strack = strackno(track, side);
|
||||
if (strack >= ARRAY_SIZE(_header.track))
|
||||
return std::unique_ptr<Fluxmap>();
|
||||
uint32_t offset = Bytes(_header.track[strack], 4).reader().read_le32();
|
||||
if (offset == 0)
|
||||
return std::unique_ptr<Fluxmap>();
|
||||
|
||||
ScpTrack trackheader;
|
||||
ScpTrackStart trackstart;
|
||||
_if.seekg(offset, std::ios::beg);
|
||||
_if.read((char*) &trackheader, sizeof(trackheader));
|
||||
_if.read((char*) &trackstart, sizeof(trackstart));
|
||||
check_for_error();
|
||||
|
||||
if ((trackheader.track_id[0] != 'T')
|
||||
|| (trackheader.track_id[1] != 'R')
|
||||
|| (trackheader.track_id[2] != 'K'))
|
||||
if ((trackstart.track_id[0] != 'T')
|
||||
|| (trackstart.track_id[1] != 'R')
|
||||
|| (trackstart.track_id[2] != 'K'))
|
||||
Error() << "corrupt SCP file";
|
||||
|
||||
std::vector<ScpTrackRevolution> revs(_header.revolutions);
|
||||
for (int revolution = 0; revolution < _header.revolutions; revolution++)
|
||||
{
|
||||
ScpTrackRevolution trackrev;
|
||||
_if.read((char*) &trackrev, sizeof(trackrev));
|
||||
check_for_error();
|
||||
revs[revolution] = trackrev;
|
||||
}
|
||||
|
||||
std::unique_ptr<Fluxmap> fluxmap(new Fluxmap);
|
||||
nanoseconds_t pending = 0;
|
||||
unsigned inputBytes = 0;
|
||||
@@ -79,8 +91,8 @@ public:
|
||||
if (revolution != 0)
|
||||
fluxmap->appendIndex();
|
||||
|
||||
uint32_t datalength = Bytes(trackheader.revolution[revolution].length, 4).reader().read_le32();
|
||||
uint32_t dataoffset = Bytes(trackheader.revolution[revolution].offset, 4).reader().read_le32();
|
||||
uint32_t datalength = Bytes(revs[revolution].length, 4).reader().read_le32();
|
||||
uint32_t dataoffset = Bytes(revs[revolution].offset, 4).reader().read_le32();
|
||||
|
||||
Bytes data(datalength*2);
|
||||
_if.seekg(dataoffset + offset, std::ios::beg);
|
||||
|
||||
21
lib/scp.h
21
lib/scp.h
@@ -27,17 +27,24 @@ enum
|
||||
SCP_FLAG_FOOTER = (1<<5)
|
||||
};
|
||||
|
||||
struct ScpTrackStart
|
||||
{
|
||||
char track_id[3]; // 'TRK'
|
||||
uint8_t strack; // SCP track number
|
||||
};
|
||||
|
||||
struct ScpTrackRevolution
|
||||
{
|
||||
uint8_t index[4]; // time for one revolution
|
||||
uint8_t length[4]; // number of bitcells
|
||||
uint8_t offset[4]; // offset to bitcell data, relative to track header
|
||||
};
|
||||
|
||||
struct ScpTrack
|
||||
{
|
||||
char track_id[3]; // 'TRK'
|
||||
uint8_t strack; // SCP track number
|
||||
struct
|
||||
{
|
||||
uint8_t index[4]; // time for one revolution
|
||||
uint8_t length[4]; // number of bitcells
|
||||
uint8_t offset[4]; // offset to bitcell data, relative to track header
|
||||
}
|
||||
revolution[5];
|
||||
struct ScpTrackRevolution revolution[5];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
extern bool beginsWith(const std::string& value, const std::string& beginning);
|
||||
extern bool endsWith(const std::string& value, const std::string& ending);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user