Skip to content

Commit e6e6093

Browse files
committed
Merge branch 'master' of github.com:sandialabs/SpecUtils
2 parents e5c4bc7 + 063e4df commit e6e6093

File tree

2 files changed

+64
-10
lines changed

2 files changed

+64
-10
lines changed

fuzz_test/README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,28 @@ cd build_fuzzing
3333
# Replace /path/to/your/boost/install with your actual Boost installation path
3434
cmake -DCMAKE_BUILD_TYPE="RelWithDebInfo" \
3535
-DCMAKE_IGNORE_PATH="/Applications/Xcode.app" \
36-
-DCMAKE_PREFIX_PATH="/opt/homebrew/opt/llvm;/path/to/your/boost/install" \
36+
-DCMAKE_PREFIX_PATH="/opt/homebrew/opt/llvm" \
3737
-DCMAKE_CXX_COMPILER="/opt/homebrew/opt/llvm/bin/clang++" \
3838
-DCMAKE_C_COMPILER="/opt/homebrew/opt/llvm/bin/clang" \
3939
-DCMAKE_CXX_FLAGS="-stdlib=libc++" \
4040
-DCMAKE_EXE_LINKER_FLAGS="-stdlib=libc++ -L/opt/homebrew/opt/llvm/lib/c++ -lc++abi" \
4141
-DSpecUtils_BUILD_FUZZING_TESTS=ON \
4242
-DSpecUtils_BUILD_REGRESSION_TEST=OFF \
4343
-DSpecUtils_ENABLE_EQUALITY_CHECKS=ON \
44-
-DSpecUtils_ENABLE_URI_SPECTRA=ON \
45-
-DSpecUtils_FLT_PARSE_METHOD=boost \
44+
-DSpecUtils_ENABLE_URI_SPECTRA=OFF \
45+
-DSpecUtils_FLT_PARSE_METHOD=FastFloat \
46+
-DSpecUtils_FETCH_FAST_FLOAT=ON \
47+
-DSpecUtils_USING_NO_THREADING=ON \
4648
..
4749
```
4850

51+
If you want to to anable URI spectra, on macOS, you need to not use the system `zlib`, as
52+
bringing that in brings in the system include path, but we need to keep the system includes
53+
to all be from brews install of llvm/clang.
54+
(compiling and installing from code at https://github.com/madler/zlib is pretty simple)
55+
Also, the using threading was causing some issues when linking for me on macOS, so I just disabled.
56+
57+
4958
### Step 4: Build the project
5059
```bash
5160
cmake --build . --config RelWithDebInfo -j8

src/CAMIO.cpp

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ void CAMIO::ReadBlock(CAMBlock block) {
736736

737737
// Helper function to read a uint16_t from the data buffer
738738
static uint16_t ReadUInt16(const std::vector<byte_type>& data, size_t offset) {
739-
if( offset + sizeof(uint16_t) > data.size() )
739+
if( (offset + sizeof(uint16_t)) > data.size() )
740740
throw std::out_of_range( "ReadUInt16: offset " + std::to_string(offset) + " out of range (data size: " + std::to_string(data.size()) + ")" );
741741

742742
uint16_t value;
@@ -756,6 +756,9 @@ static uint32_t ReadUInt32(const std::vector<byte_type>& data, size_t offset) {
756756

757757
// read the geometry block
758758
void CAMIO::ReadGeometryBlock(size_t pos, uint16_t records) {
759+
if( (pos + 0x28 + 2) > readData->size() )
760+
throw std::runtime_error( "Data smaller than geometry block" );
761+
759762
// Get record offset and entry offset
760763
uint16_t commonFlag = ReadUInt16(*readData, pos + 0x04);
761764
uint16_t recOffset = commonFlag == 0x700 ? 0 : ReadUInt16(*readData, pos + 0x22);
@@ -824,6 +827,9 @@ void CAMIO::ReadGeometryBlock(size_t pos, uint16_t records) {
824827

825828
// read the lines block
826829
void CAMIO::ReadLinesBlock(size_t pos, uint16_t records) {
830+
if( (pos + 0x22 + 2) > readData->size() )
831+
throw std::runtime_error( "Data smaller than lines block" );
832+
827833
// Get record offset and size
828834
uint16_t commonFlag = ReadUInt16(*readData, pos + 0x04);
829835
uint16_t recOffset = (commonFlag == 0x700 || commonFlag == 0x300) ? 0 : ReadUInt16(*readData, pos + 0x22);
@@ -854,6 +860,9 @@ void CAMIO::ReadLinesBlock(size_t pos, uint16_t records) {
854860

855861
// read the nuclides block
856862
void CAMIO::ReadNuclidesBlock(size_t pos, uint16_t records) {
863+
if( (pos + 0x22 + 2) > readData->size() )
864+
throw std::runtime_error( "Data smaller than nuclides block" );
865+
857866
// Get record offset
858867
uint16_t commonFlag = ReadUInt16(*readData, pos + 0x04);
859868
uint16_t recOffset = commonFlag == 0x700 ? 0 : ReadUInt16(*readData, pos + 0x22);
@@ -873,6 +882,9 @@ void CAMIO::ReadNuclidesBlock(size_t pos, uint16_t records) {
873882
// Validate we can read the size field
874883
validate_bounds( *readData, loc, 2, "ReadNuclidesBlock: reading numLines size field" );
875884

885+
if( (loc + 2) > readData->size() )
886+
throw std::runtime_error( "Data smaller than nuclide record" );
887+
876888
// Calculate the size of this nuclide record including its lines
877889
// Validate that the size field is reasonable before subtracting
878890
const uint16_t sizeField = ReadUInt16(*readData, loc);
@@ -913,6 +925,9 @@ void CAMIO::ReadNuclidesBlock(size_t pos, uint16_t records) {
913925

914926
// read the peaks block
915927
void CAMIO::ReadPeaksBlock(size_t pos, uint16_t records) {
928+
if( (pos + 0x22 + 2) > readData->size() )
929+
throw std::runtime_error( "Data smaller than peaks block" );
930+
916931
// Get record offset and size
917932
uint16_t commonFlag = ReadUInt16(*readData, pos + 0x04);
918933
uint16_t recOffset = commonFlag == 0x700 ? 0 : ReadUInt16(*readData, pos + 0x22);
@@ -949,6 +964,9 @@ void CAMIO::ReadPeaksBlock(size_t pos, uint16_t records) {
949964
});
950965
validate_bounds( *readData, loc, maxOffset, "ReadPeaksBlock: reading peak record" );
951966

967+
if( (pos + static_cast<uint32_t>(PeakParameterLocation::CriticalLevel) + 4) > readData->size() )
968+
throw std::runtime_error( "Data smaller than peaks record" );
969+
952970
Peak peak{};
953971
peak.Energy = convert_from_CAM_float(*readData, loc + static_cast<uint32_t>(PeakParameterLocation::Energy));
954972
peak.Centroid = convert_from_CAM_float(*readData, loc + static_cast<uint32_t>(PeakParameterLocation::Centroid));
@@ -981,6 +999,9 @@ std::vector<Line>& CAMIO::GetLines() {
981999
for (auto& it = range.first; it != range.second; ++it) {
9821000
size_t pos = it->second;
9831001

1002+
if( (pos + 0x22 + 2) > readData->size() )
1003+
throw std::runtime_error( "Data smaller than lines pos" );
1004+
9841005
// Get record offset and size
9851006
uint16_t commonFlag = ReadUInt16(*readData, pos + 0x04);
9861007
uint16_t recOffset = (commonFlag == 0x700 || commonFlag == 0x300) ? 0 : ReadUInt16(*readData, pos + 0x22);
@@ -1050,6 +1071,9 @@ std::vector<Nuclide>& CAMIO::GetNuclides() {
10501071
for (auto& it = range.first; it != range.second; ++it) {
10511072
size_t pos = it->second;
10521073

1074+
if( (pos + 0x22 + 2) > readData->size() )
1075+
throw std::runtime_error( "Data smaller than nuclides pos" );
1076+
10531077
uint16_t recOffset = ReadUInt16(*readData, pos + 0x04) == 0x700 ? 0 : ReadUInt16(*readData, pos + 0x22);
10541078
uint16_t recSize = ReadUInt16(*readData, pos + 0x20);
10551079
uint16_t numRec = ReadUInt16(*readData, pos + 0x1E);
@@ -1092,7 +1116,7 @@ std::vector<Nuclide>& CAMIO::GetNuclides() {
10921116

10931117
Nuclide nuc;
10941118
nuc.HalfLife = convert_from_CAM_duration(*readData, loc + 0x1b);
1095-
nuc.HalfLifeUncertainty = convert_from_CAM_duration(*readData, loc + 0x89);
1119+
nuc.HalfLifeUncertainty = convert_from_CAM_duration(*readData, loc + static_cast<uint32_t>(NuclideParameterLocation::HalfLifeUncertainty) );
10961120

10971121
// Read name (8 characters)
10981122
char nameBuf[9] = {0};
@@ -1154,7 +1178,10 @@ std::vector<Peak>& CAMIO::GetPeaks() {
11541178
for (auto& it = range.first; it != range.second; ++it) {
11551179
size_t pos = it->second;
11561180

1157-
uint16_t recOffset = ReadUInt16(*readData, pos + 0x04) == 0x700 || secondBlock ?
1181+
if( (pos + 0x22 + 2) > readData->size() )
1182+
throw std::runtime_error( "Data smaller than peaks pos" );
1183+
1184+
uint16_t recOffset = ReadUInt16(*readData, pos + 0x04) == 0x700 || secondBlock ?
11581185
0 : ReadUInt16(*readData, pos + 0x22);
11591186
uint16_t recSize = ReadUInt16(*readData, pos + 0x20);
11601187
uint16_t numRec = ReadUInt16(*readData, pos + 0x1E);
@@ -1187,6 +1214,9 @@ std::vector<Peak>& CAMIO::GetPeaks() {
11871214
});
11881215
validate_bounds( *readData, loc, maxOffset, "GetPeaks: reading peak record" );
11891216

1217+
if( (pos + static_cast<uint32_t>(PeakParameterLocation::CriticalLevel) + 4) > readData->size() )
1218+
throw std::runtime_error( "Data smaller than peaks record" );
1219+
11901220
Peak peak{};
11911221
peak.Energy = convert_from_CAM_float(*readData, loc + static_cast<uint32_t>(PeakParameterLocation::Energy));
11921222
peak.Centroid = convert_from_CAM_float(*readData, loc + static_cast<uint32_t>(PeakParameterLocation::Centroid));
@@ -1220,6 +1250,9 @@ std::vector<uint32_t>& CAMIO::GetSpectrum() {
12201250
for (auto& it = range.first; it != range.second; ++it) {
12211251
size_t pos = it->second;
12221252

1253+
if( (pos + 0x2A + 2) > readData->size() )
1254+
throw std::runtime_error( "Data smaller than spectrum pos" );
1255+
12231256
// Get number of channels
12241257
uint16_t channels = ReadUInt16(*readData, pos + 0x2A);
12251258
uint16_t headerOffset = ReadUInt16(*readData, pos + 0x10);
@@ -1234,6 +1267,9 @@ std::vector<uint32_t>& CAMIO::GetSpectrum() {
12341267
// Resize spectrum vector to accommodate all channels
12351268
fileSpectrum.resize(channels);
12361269

1270+
if( (pos + dataOffset + headerOffset + channels*4) > readData->size() )
1271+
throw std::runtime_error( "Data smaller than spectrum data" );
1272+
12371273
// Read channel data
12381274
for (size_t i = 0; i < channels; i++) {
12391275
uint32_t value;
@@ -1254,6 +1290,7 @@ std::string CAMIO::GetSampleTitle()
12541290

12551291
for (auto& it = range.first; it != range.second; ++it) {
12561292
size_t pos = it->second;
1293+
12571294
uint16_t headSize = ReadUInt16(*readData, pos + 0x10);
12581295

12591296
// Validate we can read the sample title (64 bytes)
@@ -1363,6 +1400,7 @@ SpecUtils::time_point_t CAMIO::GetAquisitionTime() {
13631400

13641401
for (auto& it = range.first; it != range.second; ++it) {
13651402
size_t pos = it->second;
1403+
13661404
uint16_t headSize = ReadUInt16(*readData, pos + 0x10);
13671405
uint16_t timeOffset = ReadUInt16(*readData, pos + 0x24);
13681406

@@ -1731,7 +1769,7 @@ void CAMIO::AddLineAndNuclide(const float energy, const float yield,
17311769
float t12Unc = (halfLifeUnc < size_t(0)) ? ComputeUncertainty(halfLife) : halfLifeUnc;
17321770

17331771

1734-
int nucNo = writeNuclides.size() + 1;
1772+
int nucNo = static_cast<int>( writeNuclides.size() + 1 );
17351773
// TODO try this out without this helper vector
17361774
Nuclide nuc(name, halfLife, t12Unc, halfLifeUnit, nucNo );
17371775

@@ -2205,11 +2243,18 @@ std::vector<byte_type> CAMIO::GenerateBlockHeader(CAMBlock block, size_t loc, ui
22052243
0x03E6, // 0x28 16 Addresss of entries in block
22062244
0x0009, // 0x2A 17 Always 9
22072245
0x0000, // 0x2C 18
2208-
static_cast<uint16_t>(values[4] + values[11] * values[12] + values[13]) // 0x2E 19 Computed size of block
2209-
};
2246+
static_cast<uint16_t>(sec_header_length + numRec * static_cast<uint16_t>(RecordSize::ACQP) + 0x02EA) // 0x2E 19 Computed size of block
2247+
};
22102248
std::vector<uint16_t> temp = { values[4] , values[11] , values[12] , values[13] , values[17]};
22112249
// Modify values based on block type
22122250
switch (block) {
2251+
case CAMBlock::ACQP:
2252+
case CAMBlock::GEOM:
2253+
case CAMBlock::DISP:
2254+
case CAMBlock::PEAK:
2255+
// No action
2256+
break;
2257+
22132258
case CAMBlock::PROC:
22142259
values[0] = 0x0100;
22152260
values[1] = static_cast<uint16_t>(BlockSize::PROC);
@@ -2331,7 +2376,7 @@ std::vector<byte_type> CAMIO::GenerateBlockHeader(CAMBlock block, size_t loc, ui
23312376
}
23322377
break;
23332378

2334-
2379+
23352380
}
23362381

23372382
// Copy in the block code

0 commit comments

Comments
 (0)