Skip to content

Commit

Permalink
Infinite recursion protections
Browse files Browse the repository at this point in the history
Adds sanity checks to prevent unanticipated internal infinite recursions (now throws Exceptions with helpful messages; previously timed out or hit memory limits)
  • Loading branch information
nathanbrauer committed Oct 16, 2023
1 parent f315bfd commit 88676bf
Showing 1 changed file with 27 additions and 2 deletions.
29 changes: 27 additions & 2 deletions src/Controllers/ShareDraftController.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ class ShareDraftController extends Controller
*/
protected static $isViewingPreview = false;

/**
* @var array
*/
private $redirectRecursionIterations = [];

/**
* @return bool
*/
Expand Down Expand Up @@ -172,8 +177,8 @@ private function getRenderedPageByURL(string $url): HTTPResponse
$variables['_SERVER']['HTTP_USER_AGENT'] =
isset($variables['_SERVER']['HTTP_USER_AGENT']) &&
$variables['_SERVER']['HTTP_USER_AGENT']
? $variables['_SERVER']['HTTP_USER_AGENT']
: 'CLI';
? $variables['_SERVER']['HTTP_USER_AGENT']
: 'CLI';

Environment::setVariables($variables);

Expand All @@ -183,6 +188,15 @@ private function getRenderedPageByURL(string $url): HTTPResponse
$response = Director::singleton()->handleRequest($pageRequest);

if ($response->isRedirect()) {
if (in_array($url, $this->redirectRecursionIterations)) {
throw new \Exception("Infinite recursion detected.".$this->getRedirectRecursionIterationsLog($url));
}

$this->redirectRecursionIterations[] = $url;
if (count($this->redirectRecursionIterations) >= 30) {
throw new \Exception("Max redirect recursions reached.".$this->getRedirectRecursionIterationsLog());
}

// The redirect will probably be Absolute URL so just want the path
$newUrl = parse_url($response->getHeader('location') ?? '', PHP_URL_PATH);

Expand All @@ -192,6 +206,17 @@ private function getRenderedPageByURL(string $url): HTTPResponse
return $response;
}

/**
* @param string $append_url
* @return string
*/
protected function getRedirectRecursionIterationsLog(string $append_url=''): string
{
return "\n\nRedirected URLs stack: \n"
. implode("\n", $this->redirectRecursionIterations)
. ($append_url ? "\n$append_url" : '');
}

/**
* @return DBHTMLText
*/
Expand Down

0 comments on commit 88676bf

Please sign in to comment.