mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
FIX Prevent infinite loops in Deprecation::notice()
This commit is contained in:
parent
906cd0e76d
commit
1ee0aff1d1
@ -67,6 +67,8 @@ class Deprecation
|
|||||||
*/
|
*/
|
||||||
protected static $module_version_overrides = [];
|
protected static $module_version_overrides = [];
|
||||||
|
|
||||||
|
protected static bool $inside_notice = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int - the notice level to raise on a deprecation notice. Defaults to E_USER_DEPRECATED if that exists,
|
* @var int - the notice level to raise on a deprecation notice. Defaults to E_USER_DEPRECATED if that exists,
|
||||||
* E_USER_NOTICE if not
|
* E_USER_NOTICE if not
|
||||||
@ -171,72 +173,81 @@ class Deprecation
|
|||||||
*/
|
*/
|
||||||
public static function notice($atVersion, $string = '', $scope = Deprecation::SCOPE_METHOD)
|
public static function notice($atVersion, $string = '', $scope = Deprecation::SCOPE_METHOD)
|
||||||
{
|
{
|
||||||
if (!static::get_enabled()) {
|
if (static::$inside_notice) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
static::$inside_notice = true;
|
||||||
|
// try block needs to wrap all code in case anything inside the try block
|
||||||
|
// calls something else that calls Deprecation::notice()
|
||||||
|
try {
|
||||||
|
if (!static::get_enabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$checkVersion = self::$version;
|
||||||
|
// Getting a backtrace is slow, so we only do it if we need it
|
||||||
|
$backtrace = null;
|
||||||
|
|
||||||
$checkVersion = self::$version;
|
// If you pass #.#, assume #.#.0
|
||||||
// Getting a backtrace is slow, so we only do it if we need it
|
if (preg_match('/^[0-9]+\.[0-9]+$/', $atVersion ?? '')) {
|
||||||
$backtrace = null;
|
$atVersion .= '.0';
|
||||||
|
}
|
||||||
|
if (preg_match('/^[0-9]+\.[0-9]+$/', $checkVersion ?? '')) {
|
||||||
|
$checkVersion .= '.0';
|
||||||
|
}
|
||||||
|
|
||||||
// If you pass #.#, assume #.#.0
|
if (self::$module_version_overrides) {
|
||||||
if (preg_match('/^[0-9]+\.[0-9]+$/', $atVersion ?? '')) {
|
$module = self::get_calling_module_from_trace($backtrace = debug_backtrace(0));
|
||||||
$atVersion .= '.0';
|
if ($module) {
|
||||||
}
|
if (($name = $module->getComposerName())
|
||||||
if (preg_match('/^[0-9]+\.[0-9]+$/', $checkVersion ?? '')) {
|
&& isset(self::$module_version_overrides[$name])
|
||||||
$checkVersion .= '.0';
|
) {
|
||||||
}
|
$checkVersion = self::$module_version_overrides[$name];
|
||||||
|
} elseif (($name = $module->getShortName())
|
||||||
if (self::$module_version_overrides) {
|
&& isset(self::$module_version_overrides[$name])
|
||||||
$module = self::get_calling_module_from_trace($backtrace = debug_backtrace(0));
|
) {
|
||||||
if ($module) {
|
$checkVersion = self::$module_version_overrides[$name];
|
||||||
if (($name = $module->getComposerName())
|
}
|
||||||
&& isset(self::$module_version_overrides[$name])
|
|
||||||
) {
|
|
||||||
$checkVersion = self::$module_version_overrides[$name];
|
|
||||||
} elseif (($name = $module->getShortName())
|
|
||||||
&& isset(self::$module_version_overrides[$name])
|
|
||||||
) {
|
|
||||||
$checkVersion = self::$module_version_overrides[$name];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Check the version against the notice version
|
// Check the version against the notice version
|
||||||
if ($checkVersion && version_compare($checkVersion ?? '', $atVersion ?? '', '>=')) {
|
if ($checkVersion && version_compare($checkVersion ?? '', $atVersion ?? '', '>=')) {
|
||||||
// Get the calling scope
|
// Get the calling scope
|
||||||
if ($scope == Deprecation::SCOPE_METHOD) {
|
if ($scope == Deprecation::SCOPE_METHOD) {
|
||||||
if (!$backtrace) {
|
if (!$backtrace) {
|
||||||
$backtrace = debug_backtrace(0);
|
$backtrace = debug_backtrace(0);
|
||||||
|
}
|
||||||
|
$caller = self::get_called_method_from_trace($backtrace);
|
||||||
|
} elseif ($scope == Deprecation::SCOPE_CLASS) {
|
||||||
|
if (!$backtrace) {
|
||||||
|
$backtrace = debug_backtrace(0);
|
||||||
|
}
|
||||||
|
$caller = isset($backtrace[1]['class']) ? $backtrace[1]['class'] : '(unknown)';
|
||||||
|
} else {
|
||||||
|
$caller = false;
|
||||||
}
|
}
|
||||||
$caller = self::get_called_method_from_trace($backtrace);
|
|
||||||
} elseif ($scope == Deprecation::SCOPE_CLASS) {
|
// Get the level to raise the notice as
|
||||||
if (!$backtrace) {
|
$level = self::$notice_level;
|
||||||
$backtrace = debug_backtrace(0);
|
if (!$level) {
|
||||||
|
$level = E_USER_DEPRECATED;
|
||||||
}
|
}
|
||||||
$caller = isset($backtrace[1]['class']) ? $backtrace[1]['class'] : '(unknown)';
|
|
||||||
} else {
|
|
||||||
$caller = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the level to raise the notice as
|
// Then raise the notice
|
||||||
$level = self::$notice_level;
|
if (substr($string ?? '', -1) != '.') {
|
||||||
if (!$level) {
|
$string .= ".";
|
||||||
$level = E_USER_DEPRECATED;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Then raise the notice
|
$string .= " Called from " . self::get_called_method_from_trace($backtrace, 2) . '.';
|
||||||
if (substr($string ?? '', -1) != '.') {
|
|
||||||
$string .= ".";
|
|
||||||
}
|
|
||||||
|
|
||||||
$string .= " Called from " . self::get_called_method_from_trace($backtrace, 2) . '.';
|
if ($caller) {
|
||||||
|
user_error($caller . ' is deprecated.' . ($string ? ' ' . $string : ''), $level ?? 0);
|
||||||
if ($caller) {
|
} else {
|
||||||
user_error($caller . ' is deprecated.' . ($string ? ' ' . $string : ''), $level ?? 0);
|
user_error($string ?? '', $level ?? 0);
|
||||||
} else {
|
}
|
||||||
user_error($string ?? '', $level ?? 0);
|
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
static::$inside_notice = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user