From 2ac6e52c9fe4b77ed3852f663a3daec34236afdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Bocahu?= Date: Fri, 26 Apr 2013 14:28:01 +0200 Subject: [PATCH] [-] Fixes a race condition Fixes a race condition leading to file coruption and PHP crashes when writing the cache index file. Handles concurrency properly by using a temporary file and an atomic rename() instead of file_put_contents(), which is not atomic, on a file which is potentially accessed by many processes at the same time --- classes/Autoload.php | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/classes/Autoload.php b/classes/Autoload.php index 8faf7fc26..a873de2c5 100644 --- a/classes/Autoload.php +++ b/classes/Autoload.php @@ -136,27 +136,13 @@ class Autoload } else { - // Let's write index content in cache file - // In order to be sure that this file is correctly written, a check is done on the file content - $loop_protection = 0; - do - { - $integrity_is_ok = false; - file_put_contents($filename, $content, LOCK_EX); - if ($loop_protection++ > 10) - break; - - // If the file content end with PHP tag, integrity of the file is ok - if (preg_match('#\?>\s*$#', file_get_contents($filename))) - $integrity_is_ok = true; - } - while (!$integrity_is_ok); - - if (!$integrity_is_ok) - { - file_put_contents($filename, '', LOCK_EX); - // Cannot use PrestaShopException in this context - die('Your file '.$filename.' is corrupted. Please remove this file, a new one will be regenerated automatically'); + $filename_tmp = tempnam(dirname($filename), basename($filename.'.')); + if($filename_tmp !== FALSE and file_put_contents($filename_tmp, $content, LOCK_EX) !== FALSE) { + rename($filename_tmp, $filename); + } else { + // $filename_tmp couldn't be written. $filename should be there anyway (even if outdated), + // no need to die. + error_log('Cannot write temporary file '.$filename_tmp); } }