- Affected version
- 2.2.5
In
This results in the strace;
There are additional kernel transitions over the stats calls required by
Something like this, where the file is loaded and then handle if any exception being thrown;
Results in this strace;
\XF\Language::loadPhraseGroup
, there are redundant IO/kernel transitions;
PHP:
$file = $this->groupPath . "/l$this->id/$group.php";
if ($this->groupPath && file_exists($file) && is_readable($file))
{
$this->phraseCache = array_merge($this->phraseCache, include($file));
$this->groupsCached[$group] = true;
}
else
{
$this->groupsCached[$group] = false;
}
Code:
access("/var/www/html/internal_data/code_cache/phrase_groups/l0/inline_moderation.php", F_OK) = 0
access("/var/www/html/internal_data/code_cache/phrase_groups/l0/inline_moderation.php", R_OK) = 0
lstat("/var/www/html/internal_data/code_cache/phrase_groups/l0/inline_moderation.php", {st_mode=S_IFREG|0644, st_size=177, ...}) = 0
lstat("/var/www/html/internal_data/code_cache/phrase_groups/l0", {st_mode=S_IFDIR|S_ISGID|0775, st_size=12288, ...}) = 0
lstat("/var/www/html/internal_data/code_cache/phrase_groups", {st_mode=S_IFDIR|S_ISGID|0775, st_size=4096, ...}) = 0
lstat("/var/www/html/internal_data/code_cache", {st_mode=S_IFDIR|S_ISGID|0775, st_size=4096, ...}) = 0
lstat("/var/www/html/internal_data", {st_mode=S_IFDIR|S_ISGID|0775, st_size=4096, ...}) = 0
open("/var/www/html/internal_data/code_cache/phrase_groups/l0/inline_moderation.php", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=177, ...}) = 0
read(3, "<?php\nreturn array (\n 'inline_m"..., 177) = 177
close(3) = 0
There are additional kernel transitions over the stats calls required by
include
. There is a race condition between file_exists
and is_readable
and the include
call, so this can throw anyway.Something like this, where the file is loaded and then handle if any exception being thrown;
PHP:
$file = $this->groupPath . "/l$this->id/$group.php";
try
{
$phrases = include($file);
}
catch (\Throwable $e)
{
$phrases = false;
}
if (\is_array($phrases))
{
$this->phraseCache = \array_merge($this->phraseCache, $phrases);
$this->groupsCached[$group] = true;
}
else
{
$this->groupsCached[$group] = false;
}
Results in this strace;
Code:
lstat("/var/www/html/internal_data/code_cache/phrase_groups/l0/inline_moderation.php", {st_mode=S_IFREG|0644, st_size=177, ...}) = 0
lstat("/var/www/html/internal_data/code_cache/phrase_groups/l0", {st_mode=S_IFDIR|S_ISGID|0775, st_size=12288, ...}) = 0
lstat("/var/www/html/internal_data/code_cache/phrase_groups", {st_mode=S_IFDIR|S_ISGID|0775, st_size=4096, ...}) = 0
lstat("/var/www/html/internal_data/code_cache", {st_mode=S_IFDIR|S_ISGID|0775, st_size=4096, ...}) = 0
lstat("/var/www/html/internal_data", {st_mode=S_IFDIR|S_ISGID|0775, st_size=4096, ...}) = 0
open("/var/www/html/internal_data/code_cache/phrase_groups/l0/inline_moderation.php", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=177, ...}) = 0
read(3, "<?php\nreturn array (\n 'inline_m"..., 177) = 177
close(3) = 0
# cat a.php
<?php
$file = '/var/www/html/internal_data/code_cache/phrase_groups/l0/inline_moderation.php';
try
{
$a = include($file);
}
catch (Throwable $e)
{
$a = false;
}
var_dump(is_array($a));
# strace php a.php
....
# cat b.php
<?php
$file = '/var/www/html/internal_data/code_cache/phrase_groups/l0/inline_moderation.php';
if (file_exists($file) && is_readable($file))
{
$a = include($file);
}
else
{
$a = false;
}
var_dump(is_array($a));
....
<?php
$file = '/var/www/html/internal_data/code_cache/phrase_groups/l0/inline_moderation.php';
try
{
$a = include($file);
}
catch (Throwable $e)
{
$a = false;
}
var_dump(is_array($a));
# strace php a.php
....
# cat b.php
<?php
$file = '/var/www/html/internal_data/code_cache/phrase_groups/l0/inline_moderation.php';
if (file_exists($file) && is_readable($file))
{
$a = include($file);
}
else
{
$a = false;
}
var_dump(is_array($a));
....
Last edited: