added check to prevent segfault on missing subfile

This commit is contained in:
Erik Fröjdh 2024-10-31 09:43:41 +01:00
parent 19c6a4091f
commit cee0d71b9c
3 changed files with 45 additions and 7 deletions

View File

@ -19,7 +19,7 @@ TEST_CASE("Construct a frame") {
// data should be initialized to 0 // data should be initialized to 0
for (size_t i = 0; i < rows; i++) { for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) { for (size_t j = 0; j < cols; j++) {
uint8_t *data = (uint8_t *)frame.get(i, j); uint8_t *data = (uint8_t *)frame.pixel_ptr(i, j);
REQUIRE(data != nullptr); REQUIRE(data != nullptr);
REQUIRE(*data == 0); REQUIRE(*data == 0);
} }
@ -40,7 +40,7 @@ TEST_CASE("Set a value in a 8 bit frame") {
// only the value we did set should be non-zero // only the value we did set should be non-zero
for (size_t i = 0; i < rows; i++) { for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) { for (size_t j = 0; j < cols; j++) {
uint8_t *data = (uint8_t *)frame.get(i, j); uint8_t *data = (uint8_t *)frame.pixel_ptr(i, j);
REQUIRE(data != nullptr); REQUIRE(data != nullptr);
if (i == 5 && j == 7) { if (i == 5 && j == 7) {
REQUIRE(*data == value); REQUIRE(*data == value);
@ -65,7 +65,7 @@ TEST_CASE("Set a value in a 64 bit frame") {
// only the value we did set should be non-zero // only the value we did set should be non-zero
for (size_t i = 0; i < rows; i++) { for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) { for (size_t j = 0; j < cols; j++) {
uint64_t *data = (uint64_t *)frame.get(i, j); uint64_t *data = (uint64_t *)frame.pixel_ptr(i, j);
REQUIRE(data != nullptr); REQUIRE(data != nullptr);
if (i == 5 && j == 7) { if (i == 5 && j == 7) {
REQUIRE(*data == value); REQUIRE(*data == value);
@ -134,7 +134,7 @@ TEST_CASE("test explicit copy constructor") {
Frame frame(rows, cols, Dtype::from_bitdepth(bitdepth)); Frame frame(rows, cols, Dtype::from_bitdepth(bitdepth));
std::byte *data = frame.data(); std::byte *data = frame.data();
Frame frame2 = frame.copy(); Frame frame2 = frame.clone();
// state of the original object // state of the original object
REQUIRE(frame.rows() == rows); REQUIRE(frame.rows() == rows);

View File

@ -400,10 +400,13 @@ void RawFile::read_into(std::byte *image_buf, size_t n_frames) {
} }
size_t RawFile::frame_number(size_t frame_index) { size_t RawFile::frame_number(size_t frame_index) {
if (frame_index > this->m_total_frames) { if (frame_index >= this->m_total_frames) {
throw std::runtime_error(LOCATION + "Frame number out of range"); throw std::runtime_error(LOCATION + " Frame number out of range");
}
size_t subfile_id = frame_index / this->max_frames_per_file;
if(subfile_id >= this->subfiles.size()){
throw std::runtime_error(LOCATION + " Subfile out of range. Possible missing data.");
} }
size_t const subfile_id = frame_index / this->max_frames_per_file;
return this->subfiles[subfile_id][0]->frame_number(frame_index % this->max_frames_per_file); return this->subfiles[subfile_id][0]->frame_number(frame_index % this->max_frames_per_file);
} }

View File

@ -32,6 +32,41 @@ TEST_CASE("Read frame numbers from a jungfrau raw file") {
} }
} }
TEST_CASE("Read a frame number too high throws") {
auto fpath = test_data_path() / "jungfrau" / "jungfrau_single_master_0.json";
REQUIRE(std::filesystem::exists(fpath));
File f(fpath, "r");
// we know this file has 10 frames with frame numbers 1 to 10
// f0 1,2,3
// f1 4,5,6
// f2 7,8,9
// f3 10
REQUIRE_THROWS(f.frame_number(10));
}
TEST_CASE("Read a frame numbers where the subfile is missing throws") {
auto fpath = test_data_path() / "jungfrau" / "jungfrau_missing_subfile_master_0.json";
REQUIRE(std::filesystem::exists(fpath));
File f(fpath, "r");
// we know this file has 10 frames with frame numbers 1 to 10
// f0 1,2,3
// f1 4,5,6 - but files f1-f3 are missing
// f2 7,8,9 - gone
// f3 10 - gone
REQUIRE(f.frame_number(0) == 1);
REQUIRE(f.frame_number(1) == 2);
REQUIRE(f.frame_number(2) == 3);
REQUIRE_THROWS(f.frame_number(4));
REQUIRE_THROWS(f.frame_number(7));
REQUIRE_THROWS(f.frame_number(937));
// REQUIRE_THROWS(f.frame_number(10));
}
TEST_CASE("Read data from a jungfrau 500k single port raw file") { TEST_CASE("Read data from a jungfrau 500k single port raw file") {
auto fpath = test_data_path() / "jungfrau" / "jungfrau_single_master_0.json"; auto fpath = test_data_path() / "jungfrau" / "jungfrau_single_master_0.json";
REQUIRE(std::filesystem::exists(fpath)); REQUIRE(std::filesystem::exists(fpath));