diff --git a/CHANGELOG.md b/CHANGELOG.md index fd79b14d084..dba7ec12246 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Unreleased - Changes from 6.0.0 - Routing: + - FIXED: Prevent MLD route queries from updating removed heap nodes, avoiding `osrm-routed` segfaults/asserts [#7203](https://github.com/Project-OSRM/osrm-backend/issues/7203) - FIXED: Crash when route starts or ends at `type=manoeuvre` relation via node [#7287](https://github.com/Project-OSRM/osrm-backend/issues/7287) - Extraction: - ADDED: Emit warning when ways reference nodes not present in input data [#1596](https://github.com/Project-OSRM/osrm-backend/issues/1596) diff --git a/include/engine/routing_algorithms/routing_base_mld.hpp b/include/engine/routing_algorithms/routing_base_mld.hpp index 2809790e408..06374ada0fd 100644 --- a/include/engine/routing_algorithms/routing_base_mld.hpp +++ b/include/engine/routing_algorithms/routing_base_mld.hpp @@ -282,7 +282,7 @@ void insertOrUpdate(Heap &heap, { heap.Insert(node, weight, data); } - else if (weight < heapNode->weight) + else if (!heapNode->WasRemoved() && weight < heapNode->weight) { heapNode->data = data; heapNode->weight = weight; diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index 72b9e4b8860..f7bf71049db 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -154,6 +154,8 @@ class QueryHeap NodeID node; Weight weight; Data data; + + bool WasRemoved() const { return handle == HeapContainer::INVALID_HANDLE; } }; template explicit QueryHeap(StorageArgs... args) : node_index(args...) diff --git a/unit_tests/engine/offline_facade.cpp b/unit_tests/engine/offline_facade.cpp index 41af0ad3217..4c3dfb6feed 100644 --- a/unit_tests/engine/offline_facade.cpp +++ b/unit_tests/engine/offline_facade.cpp @@ -398,4 +398,28 @@ BOOST_AUTO_TEST_CASE(facade_uncompressed_methods) BOOST_CHECK_EQUAL(facade.GetUncompressedReverseDatasources(0).size(), 0); } +BOOST_AUTO_TEST_CASE(insert_or_update_skips_removed_nodes) +{ + using QueryHeap = osrm::engine::SearchEngineData< + osrm::engine::routing_algorithms::offline::Algorithm>::QueryHeap; + + QueryHeap heap(4, 0); + const osrm::engine::MultiLayerDijkstraHeapData initial_data{SPECIAL_NODEID, false}; + const osrm::engine::MultiLayerDijkstraHeapData updated_data{1, true}; + + heap.Insert(1, {10}, initial_data); + BOOST_CHECK_EQUAL(heap.DeleteMin(), 1); + BOOST_CHECK(heap.WasRemoved(1)); + + osrm::engine::routing_algorithms::mld::insertOrUpdate(heap, 1, {5}, updated_data); + + BOOST_CHECK(heap.WasRemoved(1)); + BOOST_CHECK_EQUAL(from_alias(heap.GetKey(1)), 10); + + const auto heap_node = heap.GetHeapNodeIfWasInserted(1); + BOOST_REQUIRE(heap_node != nullptr); + BOOST_CHECK_EQUAL(heap_node->data.parent, SPECIAL_NODEID); + BOOST_CHECK_EQUAL(heap_node->data.from_clique_arc, false); +} + BOOST_AUTO_TEST_SUITE_END()