From cf59fbc036e284c99f8f936045271682284f4722 Mon Sep 17 00:00:00 2001
From: stronk7 <stronk7>
Date: Mon, 5 Oct 2009 17:23:31 +0000
Subject: [PATCH] MDL-18469 checksum restore in-session objects - both in
 manual restore and import, create checksums of the critical in-session
 objects (info, course_header and restore) to be able to check in
 restore_execute.html that all the information has arrived properly without
 any trim/error. Merged from 19_STABLE

---
 backup/restore_check.html   |  5 +++++
 backup/restore_execute.html | 15 +++++++++++++++
 backup/restorelib.php       | 20 ++++++++++++++++++++
 3 files changed, 40 insertions(+)

diff --git a/backup/restore_check.html b/backup/restore_check.html
index 8e00ab2bfd2..f2ac3785432 100644
--- a/backup/restore_check.html
+++ b/backup/restore_check.html
@@ -322,6 +322,11 @@
         //Save the restore session object
         $SESSION->restore = $restore;
 
+        // Calculate all session objects checksum and store them in session too
+        // so restore_execute.html (used by manual restore and import) will be
+        // able to detect any problem in session info.
+        restore_save_session_object_checksums($restore, $info, $course_header);
+
         echo "<div style='text-align:center'>";
 
     /// Printout messages
diff --git a/backup/restore_execute.html b/backup/restore_execute.html
index 6fd307e369a..083cd45bc48 100644
--- a/backup/restore_execute.html
+++ b/backup/restore_execute.html
@@ -8,6 +8,21 @@
         $info = $SESSION->info;
         $course_header = $SESSION->course_header;
         $restore = $SESSION->restore;
+
+        // Validate objects from session by checking their checksums
+        $status = false;
+        if (isset($SESSION->restore_checksums)) {
+            $checksums = $SESSION->restore_checksums;
+            if (isset($checksums['info']) && $checksums['info'] == md5(serialize($info)) &&
+                isset($checksums['course_header']) && $checksums['course_header'] == md5(serialize($course_header)) &&
+                isset($checksums['restore']) && $checksums['restore'] == md5(serialize($restore))) {
+
+                $status = true; // All session checksums were or, we can rely on that to continue restoring
+            }
+        }
+        if(!$status) { // Something was wrong checking objects from session, abort with error
+            print_error('restorechecksumfailed');
+        }
     }
 
     //Add info->original_wwwroot to $restore to be able to use it in all the restore process
diff --git a/backup/restorelib.php b/backup/restorelib.php
index 47e0f9654dd..275d74a336e 100644
--- a/backup/restorelib.php
+++ b/backup/restorelib.php
@@ -8016,9 +8016,29 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
                 }
             }
         }
+        // Calculate all session objects checksum and store them in session too
+        // so restore_execute.html (used by manual restore and import) will be
+        // able to detect any problem in session info.
+        restore_save_session_object_checksums($restore, $SESSION->info, $SESSION->course_header);
+
         return true;
     }
 
+    /**
+     * Save the checksum of the 3 main in-session restore objects (restore, info, course_header)
+     * so restore_execute.html will be able to check that all them have arrived correctly, without
+     * losing data for any type of session size limit/error. MDL-18469. Used both by manual restore
+     * and import
+     */
+    function restore_save_session_object_checksums($restore, $info, $course_header) {
+        global $SESSION;
+        $restore_checksums = array();
+        $restore_checksums['info']          = md5(serialize($info));
+        $restore_checksums['course_header'] = md5(serialize($course_header));
+        $restore_checksums['restore']       = md5(serialize($restore));
+        $SESSION->restore_checksums = $restore_checksums;
+    }
+
     function backup_to_restore_array($backup,$k=0) {
         if (is_array($backup) ) {
             $restore = array();