From 6ffff7342b7b1f22692936c933a1efac8269e01a Mon Sep 17 00:00:00 2001
From: Claus-Justus Heine <Claus-Justus.Heine@IANS.Uni-Stuttgart.DE>
Date: Fri, 22 Jul 2016 10:08:35 +0000
Subject: [PATCH] Fix a very old (present in Alberta 1.2!!!!) buffer overflow
 bug during coarsening.

---
 alberta/src/3d/coarsen_3d.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/alberta/src/3d/coarsen_3d.c b/alberta/src/3d/coarsen_3d.c
index b8227d3..44a2d2b 100644
--- a/alberta/src/3d/coarsen_3d.c
+++ b/alberta/src/3d/coarsen_3d.c
@@ -163,14 +163,15 @@ static bool get_coarse_patch_3d(const EL_INFO *el_info, DOF *edge[2], int dir,
   DEBUG_TEST_EXIT(neigh == neigh_info->el,
 	      "neigh %d and neigh_info->el %d are not identical\n", 
 	      INDEX(neigh), INDEX(neigh_info->el));
+
+  while (neigh != el) {
+
 /****************************************************************************/
 /*  we have to go back to the starting element via opp_v values             */
 /*  correct information is produce by AI_set_neighs_on_patch()              */
 /****************************************************************************/
-  coarse_list[*n_neigh].opp_vertex[0] = opp_v;  
-  coarse_list[*n_neigh].el_info       = *neigh_info;
-
-  while (neigh != el) {
+    coarse_list[*n_neigh].opp_vertex[0] = opp_v;  
+    coarse_list[*n_neigh].el_info       = *neigh_info;
 
     for (j = 0; j < N_VERTICES_3D; j++)
       if (neigh->dof[j][0] == edge[0][0])  break;
@@ -189,6 +190,14 @@ static bool get_coarse_patch_3d(const EL_INFO *el_info, DOF *edge[2], int dir,
     coarse_list[*n_neigh].flags =
       (edge_no == 0) ? RCLE_COARSE_EDGE_COMPAT : RCLE_NONE;
 
+    ++*n_neigh;
+
+    /***************************************************************
+     *
+     * finished with current neighbour, now look out for the next.
+     *
+     **************************************************************/
+
 /****************************************************************************/
 /*  get the direction of the next neighbour				    */
 /****************************************************************************/
@@ -198,8 +207,6 @@ static bool get_coarse_patch_3d(const EL_INFO *el_info, DOF *edge[2], int dir,
     else
       i = next_el[edge_no][1];
 
-    ++*n_neigh;
-
     opp_v = neigh_info->opp_vertex[i];
     if ((neigh = neigh_info->neigh[i]))
     {
@@ -207,12 +214,6 @@ static bool get_coarse_patch_3d(const EL_INFO *el_info, DOF *edge[2], int dir,
       DEBUG_TEST_EXIT(neigh == neigh_info->el,
 	"neigh %d and neigh_info->el %d are not identical\n", 
 		  INDEX(neigh), INDEX(neigh_info->el));
-/****************************************************************************/
-/*  we have to go back to the starting element via opp_v values             */
-/*  correct information is produced by AI_set_neighs_on_patch()             */
-/****************************************************************************/
-      coarse_list[*n_neigh].opp_vertex[0] = opp_v;  
-      coarse_list[*n_neigh].el_info = *neigh_info;
     }
     else
       break;
-- 
GitLab