Closed g0ku704 closed 4 months ago
Thanks for finding a bug. There are some issues with the file (crashfile.mf4) but at the same time, the file includes all evil MDF types and conversions. I have checked it with the Vectors MDF Validator and my MDF File Viewer. None of them crash so I need to test your exact code. I assume it is the basic example code. I'm running Windows also so it may take some day(s) to figure out the problem.
Preliminary, the file have some issue in the second DG block with the composite CN block (struct_channel_0..7) and the nested structure CN block. It's the last 2 channels.
The Vector MDF Validator detects 13 errors and 64 warnings in the file.
Sure, yes I had to slightly modify the example code. Here it is:
#include <iostream>
#include <mdf/mdfreader.h>
#include <mdf/ichannelgroup.h>
#include <mdf/idatagroup.h>
using namespace mdf;
int main(int argc, char* argv[]) {
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " <path_to_mdf_file>" << std::endl;
return 1;
}
const char* file_path = argv[1];
MdfReader reader(file_path); // Open the specified file
// Read all blocks but not the raw data and attachments.
// This reads in the block information into memory.
reader.ReadEverythingButData();
const auto* mdf_file = reader.GetFile(); // Get the file interface.
DataGroupList dg_list; // Get all measurements.
mdf_file->DataGroups(dg_list);
// In this example, we read in all sample data and fetch all values.
for (auto* dg4 : dg_list) {
// Subscribers holds the sample data for a channel.
// You should normally only subscribe on some channels.
// We need a list to hold them.
ChannelObserverList subscriber_list;
const auto cg_list = dg4->ChannelGroups();
for (const auto* cg4 : cg_list ) {
const auto cn_list = cg4->Channels();
for (const auto* cn4 : cn_list) {
// Create a subscriber and add it to the temporary list
auto sub = CreateChannelObserver(*dg4, *cg4, *cn4);
subscriber_list.push_back(std::move(sub));
}
}
// Now it is time to read in all samples
reader.ReadData(*dg4); // Read raw data from file
double channel_value = 0.0; // Channel value (no scaling)
double eng_value = 0.0; // Engineering value
for (auto& obs : subscriber_list) {
for (size_t sample = 0; sample < obs->NofSamples(); ++sample) {
const auto channel_valid = obs->GetChannelValue(sample, channel_value);
const auto eng_valid = obs->GetEngValue(sample, eng_value);
// You should do something with data here
}
}
// Not needed in this example as we delete the subscribers,
// but it is good practise to remove samples data from memory
// when it is no longer needed.
//dg4->ResetSample();
}
reader.Close(); // Close the file
return 0;
}
I might have found the error. The level22 channel have invalid offsets causing overrun when reading. I have added some range test to harden the code so it's now returning non-valid values which is a fair result.
I cannot reproduce your error in my environment but if you filter out the level22 channel subscription from your test code, the error should disappear.
The algebraic (formula) conversion is currently not supported. If you need support for that conversion method, please let me know.
I just need to check if the value range to value conversion is correct. It should work so I need to check this. It's currently returning invalid values.
Thanks, in case if you need to reproduce the AddressSanitizer crash above, you can try compile the sample code above with -fsanitize=address
, that should give the same error in the issue description. If, not then it means they are fixed.
I have made some changes regarding the buffer overrun. Tested on Windows.
I have added a fuzzytest.sln and verified that the heap buffer overflow problem is fixed. The file have an invalid index causing the problem. The fix is to set all values invalid for that channel but OK for the remaining channels.
Hi,
The
GetByteArrayValue
function https://github.com/ihedvall/mdflib/blob/adee6fc499d2c1357fa55d798cdbad92c06317be/mdflib/src/cn4block.cpp#L692 does not check maximum allocation and caused heap buffer overflow.The sample code tested: https://ihedvall.github.io/mdflib/mdfreader.html
Address sanitizer output:
Proof of concept input: crashfile.zip