From 3b572243a52ce2c5e4fc46e6b366b8d8f02eefdf Mon Sep 17 00:00:00 2001 From: rndx21033 <90053840+rndx21033@users.noreply.github.com> Date: Sat, 21 Sep 2024 13:37:28 -0600 Subject: [PATCH] Fix crash with parseuntil when top layer is more than the chosen parseuntil OSI layer. (#1580) * Fix crash with parseuntil when top layer is more than the chosen parseuntil OSI layer. * fix format --- Packet++/src/Packet.cpp | 14 +++++++++++--- Tests/Packet++Test/TestDefinition.h | 1 + Tests/Packet++Test/Tests/PacketTests.cpp | 14 ++++++++++++++ Tests/Packet++Test/main.cpp | 1 + 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/Packet++/src/Packet.cpp b/Packet++/src/Packet.cpp index 30a2790fa9..7a7cc82c49 100644 --- a/Packet++/src/Packet.cpp +++ b/Packet++/src/Packet.cpp @@ -84,9 +84,17 @@ namespace pcpp if (curLayer != nullptr && curLayer->getOsiModelLayer() > parseUntilLayer) { - m_LastLayer = curLayer->getPrevLayer(); - delete curLayer; - m_LastLayer->m_NextLayer = nullptr; + // don't delete the first layer. If already past the target layer, treat the same as if the layer was found. + if (curLayer == m_FirstLayer) + { + curLayer->m_IsAllocatedInPacket = true; + } + else + { + m_LastLayer = curLayer->getPrevLayer(); + delete curLayer; + m_LastLayer->m_NextLayer = nullptr; + } } if (m_LastLayer != nullptr && parseUntil == UnknownProtocol && parseUntilLayer == OsiModelLayerUnknown) diff --git a/Tests/Packet++Test/TestDefinition.h b/Tests/Packet++Test/TestDefinition.h index b628c34f56..32be87090a 100644 --- a/Tests/Packet++Test/TestDefinition.h +++ b/Tests/Packet++Test/TestDefinition.h @@ -58,6 +58,7 @@ PTF_TEST_CASE(PacketTrailerTest); PTF_TEST_CASE(ResizeLayerTest); PTF_TEST_CASE(PrintPacketAndLayersTest); PTF_TEST_CASE(ProtocolFamilyMembershipTest); +PTF_TEST_CASE(PacketParseLayerLimitTest); // Implemented in HttpTests.cpp PTF_TEST_CASE(HttpRequestParseMethodTest); diff --git a/Tests/Packet++Test/Tests/PacketTests.cpp b/Tests/Packet++Test/Tests/PacketTests.cpp index ee1fc217ef..12bce597fd 100644 --- a/Tests/Packet++Test/Tests/PacketTests.cpp +++ b/Tests/Packet++Test/Tests/PacketTests.cpp @@ -1068,3 +1068,17 @@ PTF_TEST_CASE(ProtocolFamilyMembershipTest) PTF_ASSERT_FALSE(httpLayer->isMemberOfProtocolFamily(pcpp::HTTPResponse)); PTF_ASSERT_FALSE(httpLayer->isMemberOfProtocolFamily(pcpp::IP)); } + +PTF_TEST_CASE(PacketParseLayerLimitTest) +{ + timeval time; + gettimeofday(&time, nullptr); + + READ_FILE_AND_CREATE_PACKET(0, "PacketExamples/TcpPacketWithOptions3.dat"); + pcpp::Packet packet0(&rawPacket0, pcpp::OsiModelPhysicalLayer); + PTF_ASSERT_EQUAL(packet0.getLastLayer(), packet0.getFirstLayer()); + + READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/TcpPacketWithOptions3.dat"); + pcpp::Packet packet1(&rawPacket1, pcpp::OsiModelTransportLayer); + PTF_ASSERT_EQUAL(packet1.getLastLayer()->getOsiModelLayer(), pcpp::OsiModelTransportLayer); +} diff --git a/Tests/Packet++Test/main.cpp b/Tests/Packet++Test/main.cpp index d235f69f41..b5fdf00748 100644 --- a/Tests/Packet++Test/main.cpp +++ b/Tests/Packet++Test/main.cpp @@ -161,6 +161,7 @@ int main(int argc, char* argv[]) PTF_RUN_TEST(ResizeLayerTest, "packet;resize"); PTF_RUN_TEST(PrintPacketAndLayersTest, "packet;print"); PTF_RUN_TEST(ProtocolFamilyMembershipTest, "packet"); + PTF_RUN_TEST(PacketParseLayerLimitTest, "packet"); PTF_RUN_TEST(HttpRequestParseMethodTest, "http"); PTF_RUN_TEST(HttpRequestLayerParsingTest, "http");