From cc5200c00aa82894a97ac0a89efe19fcb9db5260 Mon Sep 17 00:00:00 2001 From: Sergey Bugaev Date: Sat, 1 May 2021 14:23:33 +0300 Subject: [PATCH] Fix crash when changing the number of points std::rotate accepts an "end" iterator that points one after the last item. In plain C, it's possible to create a "one past end" pointer by using the following idiom: &arr[size], which is equivalent to arr + size. No actual pointer dereference happens in this case. In C++, vector[index] always causes a vector.operator[](index) invocation; it is undefined behavior to use this method with out-of-bounds indexes. Therefore, this idiom cannot be used in C++ to get a "one past end" iterator. Instead, C++ provides .begin() and .end() methods. Use those instead. Fixes https://gitlab.gnome.org/GNOME/gnome-system-monitor/-/issues/197 Fixes https://gitlab.gnome.org/GNOME/gnome-system-monitor/-/issues/181 --- src/load-graph.cpp | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/load-graph.cpp b/src/load-graph.cpp index b18bc61c..aa28589f 100644 --- a/src/load-graph.cpp +++ b/src/load-graph.cpp @@ -792,9 +792,9 @@ void load_graph_update_data (LoadGraph *graph) { // Rotate data one element down. - std::rotate(&graph->data[0], - &graph->data[graph->num_points - 2], - &graph->data[graph->num_points - 1]); + std::rotate(graph->data.begin(), + graph->data.end() - 1, + graph->data.end()); // Update rotation counter. graph->latest = (graph->latest + 1) % graph->num_points; @@ -1061,31 +1061,26 @@ void load_graph_change_num_points(LoadGraph *graph, guint new_num_points) { - //Don't do anything if the value didn't change. + // Don't do anything if the value didn't change. if (graph->num_points == new_num_points) return; // Sort the values in the data_block vector in the order they were accessed in by the pointers in data. - std::rotate(&graph->data_block[0], - &graph->data_block[(graph->num_points - graph->latest) * graph->n], - &graph->data_block[graph->num_points * graph->n]); + std::rotate(graph->data_block.begin(), + graph->data_block.begin() + (graph->num_points - graph->latest) * graph->n, + graph->data_block.end()); // Reset rotation counter. graph->latest = 0; // Resize the vectors to the new amount of data points. + // Fill the new values with -1. graph->data.resize(new_num_points); - graph->data_block.resize(graph->n * new_num_points); + graph->data_block.resize(graph->n * new_num_points, -1.0); if (graph->type == LOAD_GRAPH_NET) { graph->net.values.resize(new_num_points); } - // Fill the new values with -1 instead of 0 if the vectors got bigger. - if (new_num_points > graph->num_points) { - std::fill(&graph->data_block[graph->n * graph->num_points], - &graph->data_block[graph->n * new_num_points], -1.0); - } - // Replace the pointers in data, to match the new data_block values. for (guint i = 0; i < new_num_points; ++i) { graph->data[i] = &graph->data_block[0] + i * graph->n; -- 2.36.1