Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

raster: Handle realloc errors in unionFind.h #3970

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

ShubhamDesai
Copy link
Contributor

Description
This pull request addresses two issues in r.terraflow/unionFind.h related to the use of realloc for memory reallocation. The changes ensure that memory is properly handled when realloc fails.

Issues
raster/r.terraflow/unionFind.h:129:9: error: Common realloc mistake: 'parent' nulled but not freed upon failure [memleakOnRealloc]
parent = (T *)realloc(parent, 2 * maxsize * sizeof(T));
^
raster/r.terraflow/unionFind.h:133:9: error: Common realloc mistake: 'rank' nulled but not freed upon failure [memleakOnRealloc]
rank = (T *)realloc(rank, 2 * maxsize * sizeof(T));

Changes Made

  • Added temporary variables to store the results of realloc for parent and rank.
  • Included checks to ensure that realloc succeeded before updating the original pointers.
  • Implemented error handling to free the original memory if realloc fails.
@github-actions github-actions bot added raster Related to raster data processing module labels Jul 1, 2024
raster/r.terraflow/unionFind.h Outdated Show resolved Hide resolved
raster/r.terraflow/unionFind.h Outdated Show resolved Hide resolved
ShubhamDesai and others added 2 commits July 1, 2024 18:24
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@nilason nilason self-assigned this Jul 2, 2024
@nilason
Copy link
Contributor

nilason commented Jul 2, 2024

Bear in mind this header file unionFind.h is a C++ file. This is how I would implement this (diff against main):

diff --git a/raster/r.terraflow/unionFind.h b/raster/r.terraflow/unionFind.h
index 698dcfc0c9..fdd084b4ae 100644
--- a/raster/r.terraflow/unionFind.h
+++ b/raster/r.terraflow/unionFind.h
@@ -20,10 +20,14 @@
 #define __UNION_FIND
 
 #include <assert.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
 #include <iostream>
 
+extern "C" {
+#include <grass/glocale.h>
+}
+
 /* initial range guesstimate */
 #define UNION_INITIAL_SIZE 2000
 
@@ -126,13 +130,21 @@ inline void unionFind<T>::makeSet(T x)
     if (x >= maxsize) {
         /* reallocate parent */
         cout << "UnionFind::makeSet: reallocate double " << maxsize << "\n";
-        parent = (T *)realloc(parent, 2 * maxsize * sizeof(T));
-        assert(parent);
-        memset(parent + maxsize, 0, maxsize * sizeof(T));
-        /*reallocate rank */
-        rank = (T *)realloc(rank, 2 * maxsize * sizeof(T));
-        assert(rank);
-        memset(rank + maxsize, 0, maxsize * sizeof(T));
+        if (void *new_parent = std::realloc(parent, 2 * maxsize * sizeof(T))) {
+            parent = static_cast<T *>(new_parent);
+            std::memset(parent + maxsize, 0, maxsize * sizeof(T));
+        }
+        else {
+            G_fatal_error(_("Not enough memory for %s"), "parent");
+        }
+        /* reallocate rank */
+        if (void *new_rank = std::realloc(rank, 2 * maxsize * sizeof(T))) {
+            rank = static_cast<T *>(new_rank);
+            std::memset(rank + maxsize, 0, maxsize * sizeof(T));
+        }
+        else {
+            G_fatal_error(_("Not enough memory for %s"), "rank");
+        }
         /*update maxsize */
         maxsize *= 2;
     }

Some notes why:

  • #include <cstdlib> style include is preferred to#include <stdlib.h>
  • C-style casting should be avoided, hence the static_cast
  • G_fatal_error() is the GRASS way to "exit(EXIT_FAILURE)" with a message
  • a string surrounded with _() will produce a localised string (with gettext)
@marisn
Copy link
Contributor

marisn commented Jul 6, 2024

a string surrounded with _() will produce a localised string (with gettext)

With the latest change to Weblate, I do not know how string extraction is done, but at least in our Make file strings from headers are not extracted

LIB_POTFILES = find ../lib \( -name "*.c" -o -name "*.py" \) | xargs grep -l "_(\"\|n_(\""

@nilason
Copy link
Contributor

nilason commented Jul 6, 2024

a string surrounded with _() will produce a localised string (with gettext)

With the latest change to Weblate, I do not know how string extraction is done, but at least in our Make file strings from headers are not extracted

LIB_POTFILES = find ../lib \( -name "*.c" -o -name "*.py" \) | xargs grep -l "_(\"\|n_(\""

Good point, but that is a completely separate issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
module raster Related to raster data processing
4 participants