From 80dd0b941851c0be1c114cf7a7ce7b66f977bfcb Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Fri, 25 Jun 2021 08:25:37 +0200 Subject: [PATCH] Harden bootstrap context registrations when apps are missing It's not expected that an app would be unavailable when the app container is created but when services are registered, but Sentry tells me on Nextcloud 21 there is an edge case where this can happen. Therefore this patch hardens the code a bit to log a meaningful error message and skipping the next code instead of logging a php notice for the undefined index and an exception for calling a method on null. Signed-off-by: Christoph Wurst --- .../Bootstrap/RegistrationContext.php | 62 +++++++++++++++---- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/lib/private/AppFramework/Bootstrap/RegistrationContext.php b/lib/private/AppFramework/Bootstrap/RegistrationContext.php index dacba0aba93..30ac63281d1 100644 --- a/lib/private/AppFramework/Bootstrap/RegistrationContext.php +++ b/lib/private/AppFramework/Bootstrap/RegistrationContext.php @@ -305,12 +305,20 @@ class RegistrationContext { */ public function delegateCapabilityRegistrations(array $apps): void { while (($registration = array_shift($this->capabilities)) !== null) { + $appId = $registration->getAppId(); + if (!isset($apps[$appId])) { + // If we land here something really isn't right. But at least we caught the + // notice that is otherwise emitted for the undefined index + $this->logger->error("App $appId not loaded for the capability registration"); + + continue; + } + try { - $apps[$registration->getAppId()] + $apps[$appId] ->getContainer() ->registerCapability($registration->getService()); } catch (Throwable $e) { - $appId = $registration->getAppId(); $this->logger->error("Error during capability registration of $appId: " . $e->getMessage(), [ 'exception' => $e, ]); @@ -372,11 +380,20 @@ class RegistrationContext { */ public function delegateContainerRegistrations(array $apps): void { while (($registration = array_shift($this->services)) !== null) { + $appId = $registration->getAppId(); + if (!isset($apps[$appId])) { + // If we land here something really isn't right. But at least we caught the + // notice that is otherwise emitted for the undefined index + $this->logger->error("App $appId not loaded for the container service registration"); + + continue; + } + try { /** * Register the service and convert the callable into a \Closure if necessary */ - $apps[$registration->getAppId()] + $apps[$appId] ->getContainer() ->registerService( $registration->getName(), @@ -384,7 +401,6 @@ class RegistrationContext { $registration->isShared() ); } catch (Throwable $e) { - $appId = $registration->getAppId(); $this->logger->error("Error during service registration of $appId: " . $e->getMessage(), [ 'exception' => $e, ]); @@ -392,15 +408,23 @@ class RegistrationContext { } while (($registration = array_shift($this->aliases)) !== null) { + $appId = $registration->getAppId(); + if (!isset($apps[$appId])) { + // If we land here something really isn't right. But at least we caught the + // notice that is otherwise emitted for the undefined index + $this->logger->error("App $appId not loaded for the container alias registration"); + + continue; + } + try { - $apps[$registration->getAppId()] + $apps[$appId] ->getContainer() ->registerAlias( $registration->getAlias(), $registration->getTarget() ); } catch (Throwable $e) { - $appId = $registration->getAppId(); $this->logger->error("Error during service alias registration of $appId: " . $e->getMessage(), [ 'exception' => $e, ]); @@ -408,16 +432,24 @@ class RegistrationContext { } while (($registration = array_shift($this->parameters)) !== null) { + $appId = $registration->getAppId(); + if (!isset($apps[$appId])) { + // If we land here something really isn't right. But at least we caught the + // notice that is otherwise emitted for the undefined index + $this->logger->error("App $appId not loaded for the container parameter registration"); + + continue; + } + try { - $apps[$registration->getAppId()] + $apps[$appId] ->getContainer() ->registerParameter( $registration->getName(), $registration->getValue() ); } catch (Throwable $e) { - $appId = $registration->getAppId(); - $this->logger->error("Error during service alias registration of $appId: " . $e->getMessage(), [ + $this->logger->error("Error during service parameter registration of $appId: " . $e->getMessage(), [ 'exception' => $e, ]); } @@ -429,12 +461,20 @@ class RegistrationContext { */ public function delegateMiddlewareRegistrations(array $apps): void { while (($middleware = array_shift($this->middlewares)) !== null) { + $appId = $middleware->getAppId(); + if (!isset($apps[$appId])) { + // If we land here something really isn't right. But at least we caught the + // notice that is otherwise emitted for the undefined index + $this->logger->error("App $appId not loaded for the container middleware registration"); + + continue; + } + try { - $apps[$middleware->getAppId()] + $apps[$appId] ->getContainer() ->registerMiddleWare($middleware->getService()); } catch (Throwable $e) { - $appId = $middleware->getAppId(); $this->logger->error("Error during capability registration of $appId: " . $e->getMessage(), [ 'exception' => $e, ]);