Skip to content

Commit

Permalink
FIX Prevent infinite loops in Deprecation::notice()
Browse files Browse the repository at this point in the history
  • Loading branch information
emteknetnz committed Oct 10, 2022
1 parent 906cd0e commit 60aba3b
Showing 1 changed file with 59 additions and 53 deletions.
112 changes: 59 additions & 53 deletions src/Dev/Deprecation.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ class Deprecation
*/
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,
* E_USER_NOTICE if not
Expand Down Expand Up @@ -171,72 +173,76 @@ public static function set_enabled($enabled)
*/
public static function notice($atVersion, $string = '', $scope = Deprecation::SCOPE_METHOD)
{
if (!static::get_enabled()) {
if (!static::get_enabled() || static::$inside_notice) {
return;
}
static::$inside_notice = true;
try {
$checkVersion = self::$version;
// Getting a backtrace is slow, so we only do it if we need it
$backtrace = null;

$checkVersion = self::$version;
// Getting a backtrace is slow, so we only do it if we need it
$backtrace = null;

// If you pass #.#, assume #.#.0
if (preg_match('/^[0-9]+\.[0-9]+$/', $atVersion ?? '')) {
$atVersion .= '.0';
}
if (preg_match('/^[0-9]+\.[0-9]+$/', $checkVersion ?? '')) {
$checkVersion .= '.0';
}
// If you pass #.#, assume #.#.0
if (preg_match('/^[0-9]+\.[0-9]+$/', $atVersion ?? '')) {
$atVersion .= '.0';
}
if (preg_match('/^[0-9]+\.[0-9]+$/', $checkVersion ?? '')) {
$checkVersion .= '.0';
}

if (self::$module_version_overrides) {
$module = self::get_calling_module_from_trace($backtrace = debug_backtrace(0));
if ($module) {
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];
if (self::$module_version_overrides) {
$module = self::get_calling_module_from_trace($backtrace = debug_backtrace(0));
if ($module) {
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
if ($checkVersion && version_compare($checkVersion ?? '', $atVersion ?? '', '>=')) {
// Get the calling scope
if ($scope == Deprecation::SCOPE_METHOD) {
if (!$backtrace) {
$backtrace = debug_backtrace(0);
// Check the version against the notice version
if ($checkVersion && version_compare($checkVersion ?? '', $atVersion ?? '', '>=')) {
// Get the calling scope
if ($scope == Deprecation::SCOPE_METHOD) {
if (!$backtrace) {
$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) {
if (!$backtrace) {
$backtrace = debug_backtrace(0);
}
$caller = isset($backtrace[1]['class']) ? $backtrace[1]['class'] : '(unknown)';
} else {
$caller = false;
}

// Get the level to raise the notice as
$level = self::$notice_level;
if (!$level) {
$level = E_USER_DEPRECATED;
}
// Get the level to raise the notice as
$level = self::$notice_level;
if (!$level) {
$level = E_USER_DEPRECATED;
}

// Then raise the notice
if (substr($string ?? '', -1) != '.') {
$string .= ".";
}
// Then raise the notice
if (substr($string ?? '', -1) != '.') {
$string .= ".";
}

$string .= " Called from " . self::get_called_method_from_trace($backtrace, 2) . '.';
$string .= " Called from " . self::get_called_method_from_trace($backtrace, 2) . '.';

if ($caller) {
user_error($caller . ' is deprecated.' . ($string ? ' ' . $string : ''), $level ?? 0);
} else {
user_error($string ?? '', $level ?? 0);
if ($caller) {
user_error($caller . ' is deprecated.' . ($string ? ' ' . $string : ''), $level ?? 0);
} else {
user_error($string ?? '', $level ?? 0);
}
}
} finally {
static::$inside_notice = false;
}
}

Expand Down

0 comments on commit 60aba3b

Please sign in to comment.