From 1036a6c78cbf00305a9e7b0bde0009931369a1f0 Mon Sep 17 00:00:00 2001 From: Uwe Seimet Date: Thu, 24 Oct 2024 23:42:36 +0200 Subject: [PATCH] Update error handling --- cpp/devices/tape.cpp | 14 +++++++++++++- cpp/test/tape_test.cpp | 11 ++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/cpp/devices/tape.cpp b/cpp/devices/tape.cpp index 78b9bf92..b9307ab7 100644 --- a/cpp/devices/tape.cpp +++ b/cpp/devices/tape.cpp @@ -178,6 +178,10 @@ int Tape::ReadData(span buf) const int length = tar_mode ? GetBlockSize() : GetVariableBlockSize(); + if (static_cast(position + length) > GetFileSize()) { + throw scsi_exception(sense_key::blank_check); + } + file.seekg(position, ios::beg); file.read((char*)buf.data(), length); if (file.fail()) { @@ -198,6 +202,10 @@ int Tape::WriteData(span buf, scsi_command) const int length = GetController()->GetChunkSize(); + if (static_cast(position + length) > GetFileSize()) { + throw scsi_exception(sense_key::blank_check); + } + if (!tar_mode) { WriteMetaData(object_type::BLOCK, length); } @@ -551,6 +559,10 @@ void Tape::WriteMetaData(Tape::object_type type, uint32_t size) { assert(size < 65536); + if (static_cast(position + sizeof(meta_data_t)) > GetFileSize()) { + throw scsi_exception(sense_key::blank_check); + } + meta_data_t meta_data; memcpy(meta_data.magic.data(), MAGIC, 4); meta_data.type = type; @@ -644,7 +656,7 @@ uint32_t Tape::GetByteCount() const GetSignedInt24(GetController()->GetCdb(), 2); // The non-fixed block size must be a multiple of 4 (see SSC-5) - if ((!fixed && count % 4) || static_cast(position + count) > filesize) { + if (!fixed && count % 4) { throw scsi_exception(sense_key::illegal_request, asc::invalid_field_in_cdb); } diff --git a/cpp/test/tape_test.cpp b/cpp/test/tape_test.cpp index 229df72b..daeb73f6 100644 --- a/cpp/test/tape_test.cpp +++ b/cpp/test/tape_test.cpp @@ -188,13 +188,12 @@ TEST(TapeTest, Erase6) { auto [controller, tape] = CreateTape(); + CreateTapeFile(*tape, 4567); + tape->SetProtected(true); TestShared::Dispatch(*tape, scsi_command::erase6, sense_key::data_protect, asc::write_protected); tape->SetProtected(false); - TestShared::Dispatch(*tape, scsi_command::erase6, sense_key::medium_error, asc::write_error); - - CreateTapeFile(*tape, 4567); EXPECT_NO_THROW(tape->Dispatch(scsi_command::erase6)); CheckPosition(*controller, *tape, 0); EXPECT_EQ(0b10000000, controller->GetBuffer()[0]) << "EOP must be set"; @@ -275,12 +274,14 @@ TEST(TapeTest, WriteFileMarks6) controller->SetCdbByte(1, 0b001); EXPECT_NO_THROW(tape->Dispatch(scsi_command::write_filemarks6)); + CreateTapeFile(*tape); + // Count > 0 controller->SetCdbByte(2, 1); - TestShared::Dispatch(*tape, scsi_command::write_filemarks6, sense_key::medium_error, asc::write_error); + TestShared::Dispatch(*tape, scsi_command::write_filemarks6, sense_key::blank_check, + asc::no_additional_sense_information); tape->SetProtected(true); - controller->SetCdbByte(1, 0b001); TestShared::Dispatch(*tape, scsi_command::write_filemarks6, sense_key::data_protect, asc::write_protected); }