Skip to content

Commit

Permalink
ZP-1626 . SafeGetContents is now able to unserialize with opt param. …
Browse files Browse the repository at this point in the history
…Removed SafeGetContentsUnserialize not more needed. Released under the Affero GNU General Public License (AGPL) version 3.
  • Loading branch information
Michele Lunardi committed Jun 15, 2021
1 parent 5badeab commit 41c1aac
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 43 deletions.
12 changes: 6 additions & 6 deletions src/lib/default/filestatemachine.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public function GetState($devid, $type, $key = false, $counter = false, $cleanst
$filename = $this->getFullFilePath($devid, $type, $key, $counter);

if(file_exists($filename)) {
$contents = Utils::SafeGetContentsUnserialize($filename, __FUNCTION__, false);
$contents = Utils::SafeGetContents($filename, __FUNCTION__, false, true);
return $contents;
}
// throw an exception on all other states, but not FAILSAVE as it's most of the times not there by default
Expand Down Expand Up @@ -203,7 +203,7 @@ public function LinkUserDevice($username, $devid) {

// exclusive block
if ($mutex->Block()) {
$users = Utils::SafeGetContentsUnserialize($this->userfilename, __FUNCTION__, true);
$users = Utils::SafeGetContents($this->userfilename, __FUNCTION__, true, true);
if (!$users) {
$users = array();
}
Expand Down Expand Up @@ -244,7 +244,7 @@ public function UnLinkUserDevice($username, $devid) {

// exclusive block
if ($mutex->Block()) {
$users = Utils::SafeGetContentsUnserialize($this->userfilename, __FUNCTION__, true);
$users = Utils::SafeGetContents($this->userfilename, __FUNCTION__, true, true);
if (!$users) {
$users = array();
}
Expand Down Expand Up @@ -293,7 +293,7 @@ public function GetAllDevices($username = false) {
return $out;
}
else {
$users = Utils::SafeGetContentsUnserialize($this->userfilename, __FUNCTION__, false);
$users = Utils::SafeGetContents($this->userfilename, __FUNCTION__, false, true);
if (!$users) {
$users = array();
}
Expand All @@ -313,7 +313,7 @@ public function GetAllDevices($username = false) {
*/
public function GetStateVersion() {
if (file_exists($this->settingsfilename)) {
$settings = Utils::SafeGetContentsUnserialize($this->settingsfilename, __FUNCTION__, false);
$settings = Utils::SafeGetContents($this->settingsfilename, __FUNCTION__, false, true);
if (strtolower(gettype($settings) == "string") && strtolower($settings) == '2:1:{s:7:"version";s:1:"2";}') {
ZLog::Write(LOGLEVEL_INFO, "Broken state version file found. Attempt to autofix it. See https://jira.zarafa.com/browse/ZP-493 for more information.");
unlink($this->settingsfilename);
Expand Down Expand Up @@ -344,7 +344,7 @@ public function GetStateVersion() {
*/
public function SetStateVersion($version) {
if (file_exists($this->settingsfilename)){
$settings = Utils::SafeGetContentsUnserialize($this->settingsfilename, __FUNCTION__, false);
$settings = Utils::SafeGetContents($this->settingsfilename, __FUNCTION__, false, true);
}
else
$settings = array(self::VERSION => IStateMachine::STATEVERSION_01);
Expand Down
55 changes: 18 additions & 37 deletions src/lib/utils/utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,7 @@ public static function CheckAndFixEncodingInHeaders(&$mail, $message) {

/**
* Tries to load the content of a file from disk with retries in case of file system returns an empty file.
* If $unserialize set true, in case of non empty files it tries to unserialize them.
*
* @param $filename
* $filename is the name of the file to be opened
Expand All @@ -1416,67 +1417,47 @@ public static function CheckAndFixEncodingInHeaders(&$mail, $message) {
* @param $suppressWarnings
* $suppressWarnings boolean. True if file_get_contents function has to be called with suppress warnings enabled, False otherwise
*
* @access private
* @return string
*/
public static function SafeGetContents($filename, $functName, $suppressWarnings) {
$attempts = (defined('FILE_STATE_ATTEMPTS') ? FILE_STATE_ATTEMPTS : 3);
$sleep_time = (defined('FILE_STATE_SLEEP') ? FILE_STATE_SLEEP : 100);
$i = 1;
while (($i <= $attempts) && (($filecontents = ($suppressWarnings ? @file_get_contents($filename) : file_get_contents($filename))) === '')) {
ZLog::Write(LOGLEVEL_WARN, sprintf("FileStateMachine->%s(): Failed on reading filename '%s' - attempt: %d", $functName, $filename, $i));
$i++;
usleep($sleep_time * 1000);
}
if ($i > $attempts)
ZLog::Write(LOGLEVEL_FATAL, sprintf("FileStateMachine->%s(): Unable to read filename '%s' after %d retries",$functName, $filename, --$i));

return $filecontents;
}
/**
* Tries to load the content of a file from disk with retries in case of file system returns an empty file.
* In case of non empty files it tries to unserialize them.
*
* @param $filename
* $filename is the name of the file to be opened
*
* @param $functName
* $functName is the name of the caller function. Usefull to be printed into the log file
*
* @param $suppressWarnings
* $suppressWarnings boolean. True if file_get_contents function has to be called with suppress warnings enabled, False otherwise
* @param $unserialize
* $unserialize boolean. True to return unserialized read data, false otherwise.
*
* @access private
* @return string
*/
public static function SafeGetContentsUnserialize($filename, $functName, $suppressWarnings) {
public static function SafeGetContents($filename, $functName, $suppressWarnings, $unserialize = false) {
$attempts = (defined('FILE_STATE_ATTEMPTS') ? FILE_STATE_ATTEMPTS : 3);
$sleep_time = (defined('FILE_STATE_SLEEP') ? FILE_STATE_SLEEP : 100);

$unserialize_attempts_max = (defined('FILE_STATE_UNSERIALIZE_ATTEMPTS') ? FILE_STATE_UNSERIALIZE_ATTEMPTS : 1);
$unserialize_attempt = 0;
$contents = false;
do {
if ($unserialize_attempt > 0) {
ZLog::Write(LOGLEVEL_WARN, sprintf("FileStateMachine->%s(): Failed on unserializing filename '%s' - attempt: %d", $functName, $filename, $unserialize_attempt));
}
if ($unserialize_attempt === $unserialize_attempts_max) {
break;
}
$i = 1;
while (($i <= $attempts) && (($filecontents = ($suppressWarnings ? @file_get_contents($filename) : file_get_contents($filename))) === '')) {
ZLog::Write(LOGLEVEL_WARN, sprintf("FileStateMachine->%s(): Failed on reading filename '%s' - attempt: %d", $functName, $filename, $i));
$i++;
usleep($sleep_time * 1000);
}
if ($i > $attempts) {
ZLog::Write(LOGLEVEL_FATAL, sprintf("FileStateMachine->%s(): Unable to read filename '%s' after %d retries",$functName, $filename, --$i));
ZLog::Write(LOGLEVEL_FATAL, sprintf("FileStateMachine->%s(): Unable to read filename '%s' after %d attempts",$functName, $filename, --$i));
if ($unserialize !== true ) {
return $filecontents;
}
break;
} else {
if ($unserialize_attempt > 0) {
ZLog::Write(LOGLEVEL_WARN, sprintf("FileStateMachine->%s(): Failed on unserializing filename '%s' - attempt: %d", $functName, $filename, $unserialize_attempt));
if ($unserialize !== true ) {
return $filecontents;
}
$unserialize_attempt ++;
}
//loop until unserialize succed or n° tries excedes
} while ( ($filecontents !== false) && (($contents = unserialize($filecontents)) === false) && $unserialize_attempt <= $unserialize_attempts_max);
} while ( ($filecontents !== false) && (($contents = unserialize($filecontents)) === false));

if ($contents === false && $filecontents !== '' && $filecontents !== false) {
ZLog::Write(LOGLEVEL_FATAL, sprintf("FileStateMachine->%s():Unable to unserialize filename '%s' after %d retries", $functName, $filename, --$unserialize_attempt));
ZLog::Write(LOGLEVEL_FATAL, sprintf("FileStateMachine->%s():Unable to unserialize filename '%s' after %d attempts", $functName, $filename, $unserialize_attempt));
}

return $contents;
Expand Down

0 comments on commit 41c1aac

Please sign in to comment.