From 16eb35d2405c04cf0c5c6a36ad3d1dd2ad4f7551 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Tue, 22 Sep 2020 16:42:53 +0200
Subject: [PATCH] Bytecode + Block decomposition: fix crash with purely forward
 variables
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

After simulating a block containing purely forward variables (thus of type
“evaluate backward”), the it_ variable of the evaluator would be left in an
inconsistent state (typically 0, which means that taking the value of a lagged
variable would lead to an invalid read).

By the way, fix a symmetric problem for backward blocks (which could
potentially create a invalid read for purely backward models).

Ref. #1727

(cherry picked from commit 73253a0620527ad7f6d20000fa70ee8fd0f573f0)
---
 mex/sources/bytecode/Evaluate.cc | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/mex/sources/bytecode/Evaluate.cc b/mex/sources/bytecode/Evaluate.cc
index a488a03509..06164ba2b4 100644
--- a/mex/sources/bytecode/Evaluate.cc
+++ b/mex/sources/bytecode/Evaluate.cc
@@ -1513,6 +1513,7 @@ Evaluate::evaluate_over_periods(const bool forward)
               it_code = begining;
               compute_block_time(0, false, false);
             }
+          it_ = periods+y_kmin-1; // Do not leave it_ in inconsistent state
         }
       else
         {
@@ -1521,6 +1522,7 @@ Evaluate::evaluate_over_periods(const bool forward)
               it_code = begining;
               compute_block_time(0, false, false);
             }
+          it_ = y_kmin; // Do not leave it_ in inconsistent state (see #1727)
         }
     }
 }
@@ -1596,11 +1598,17 @@ Evaluate::solve_simple_over_periods(const bool forward)
   else
     {
       if (forward)
-        for (it_ = y_kmin; it_ < periods+y_kmin; it_++)
-          solve_simple_one_periods();
+        {
+          for (it_ = y_kmin; it_ < periods+y_kmin; it_++)
+            solve_simple_one_periods();
+          it_= periods+y_kmin-1; // Do not leave it_ in inconsistent state
+        }
       else
-        for (it_ = periods+y_kmin-1; it_ >= y_kmin; it_--)
-          solve_simple_one_periods();
+        {
+          for (it_ = periods+y_kmin-1; it_ >= y_kmin; it_--)
+            solve_simple_one_periods();
+          it_ = y_kmin; // Do not leave it_ in inconsistent state (see #1727)
+        }
     }
   mxFree(g1);
   mxFree(r);
@@ -1665,6 +1673,7 @@ Evaluate::compute_complete_2b(const bool no_derivatives, double *_res1, double *
       else
         return;
     }
+  it_ = periods+y_kmin-1; // Do not leave it_ in inconsistent state
   return;
 }
 
@@ -1757,6 +1766,7 @@ Evaluate::compute_complete(double lambda, double *crit)
           else
             return false;
         }
+      it_ = periods+y_kmin-1; // Do not leave it_ in inconsistent state
     }
   mexPrintf("  lambda=%e, res2=%e\n", lambda, res2_);
   *crit = res2_/2;
-- 
GitLab