Skip to content

Commit

Permalink
Fix writeFile() concurrent behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
fixpunkt committed Jul 25, 2017
1 parent b562e95 commit 1ae6b5d
Showing 1 changed file with 24 additions and 2 deletions.
26 changes: 24 additions & 2 deletions libs/sysplugins/smarty_internal_runtime_writefile.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ public function writeFile($_filepath, $_contents, Smarty $smarty)

$_dirpath = dirname($_filepath);

// if subdirs, create dir structure
if ($_dirpath !== '.' && !@mkdir($_dirpath, $_dir_perms, true) && !is_dir($_dirpath)) {
// if subdirs, create dir structure
if ($_dirpath !== '.' && !@self::ensureDirectoryExists($_dirpath, $_dir_perms)) {
error_reporting($_error_reporting);
throw new SmartyException("unable to create directory {$_dirpath}");
}
Expand Down Expand Up @@ -90,4 +90,26 @@ public function writeFile($_filepath, $_contents, Smarty $smarty)

return true;
}

/**
* Recursively creates the missing parts of a directory path in a manner that is concurrency-safe.
*
* @see https://bugs.php.net/bug.php?id=35326
*
* @param string $pathname a (nested) directory path to create
* @param integer $mode the permission to use
* @return bool true iff the directory path was successfully created
*/
private static function ensureDirectoryExists($pathname, $mode)
{
$path_segments = explode(DIRECTORY_SEPARATOR, $pathname);

$current_pathname = '';
foreach ($path_segments as $path_segment) {
$current_pathname = $current_pathname . $path_segment . DIRECTORY_SEPARATOR;
@mkdir($current_pathname, $mode);
}

return is_dir($pathname);
}
}

0 comments on commit 1ae6b5d

Please sign in to comment.