]> source.dussan.org Git - nextcloud-server.git/commitdiff
Harden bootstrap context registrations when apps are missing 27681/head
authorChristoph Wurst <christoph@winzerhof-wurst.at>
Fri, 25 Jun 2021 06:25:37 +0000 (08:25 +0200)
committerChristoph Wurst <christoph@winzerhof-wurst.at>
Tue, 31 Aug 2021 07:57:27 +0000 (09:57 +0200)
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 <christoph@winzerhof-wurst.at>
lib/private/AppFramework/Bootstrap/RegistrationContext.php

index 988313f20e82fd351ab992de9e1ac39d783a2ba5..72834ebbf38af1bae3c4bcc0ced4092433bf03b9 100644 (file)
@@ -302,12 +302,20 @@ class RegistrationContext {
         */
        public function delegateCapabilityRegistrations(array $apps): void {
                while (($registration = array_shift($this->capabilities)) !== null) {
+                       $appId = $registration['appId'];
+                       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['appId']]
+                               $apps[$appId]
                                        ->getContainer()
                                        ->registerCapability($registration['capability']);
                        } catch (Throwable $e) {
-                               $appId = $registration['appId'];
                                $this->logger->logException($e, [
                                        'message' => "Error during capability registration of $appId: " . $e->getMessage(),
                                        'level' => ILogger::ERROR,
@@ -380,11 +388,20 @@ class RegistrationContext {
         */
        public function delegateContainerRegistrations(array $apps): void {
                while (($registration = array_shift($this->services)) !== null) {
+                       $appId = $registration['appId'];
+                       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['appId']]
+                               $apps[$appId]
                                        ->getContainer()
                                        ->registerService(
                                                $registration['name'],
@@ -392,7 +409,6 @@ class RegistrationContext {
                                                $registration['shared'] ?? true
                                        );
                        } catch (Throwable $e) {
-                               $appId = $registration['appId'];
                                $this->logger->logException($e, [
                                        'message' => "Error during service registration of $appId: " . $e->getMessage(),
                                        'level' => ILogger::ERROR,
@@ -401,15 +417,23 @@ class RegistrationContext {
                }
 
                while (($registration = array_shift($this->aliases)) !== null) {
+                       $appId = $registration['appId'];
+                       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['appId']]
+                               $apps[$appId]
                                        ->getContainer()
                                        ->registerAlias(
                                                $registration['alias'],
                                                $registration['target']
                                        );
                        } catch (Throwable $e) {
-                               $appId = $registration['appId'];
                                $this->logger->logException($e, [
                                        'message' => "Error during service alias registration of $appId: " . $e->getMessage(),
                                        'level' => ILogger::ERROR,
@@ -418,17 +442,25 @@ class RegistrationContext {
                }
 
                while (($registration = array_shift($this->parameters)) !== null) {
+                       $appId = $registration['appId'];
+                       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['appId']]
+                               $apps[$appId]
                                        ->getContainer()
                                        ->registerParameter(
                                                $registration['name'],
                                                $registration['value']
                                        );
                        } catch (Throwable $e) {
-                               $appId = $registration['appId'];
                                $this->logger->logException($e, [
-                                       'message' => "Error during service alias registration of $appId: " . $e->getMessage(),
+                                       'message' => "Error during service parameter registration of $appId: " . $e->getMessage(),
                                        'level' => ILogger::ERROR,
                                ]);
                        }
@@ -440,12 +472,20 @@ class RegistrationContext {
         */
        public function delegateMiddlewareRegistrations(array $apps): void {
                while (($middleware = array_shift($this->middlewares)) !== null) {
+                       $appId = $middleware['appId'];
+                       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['appId']]
+                               $apps[$appId]
                                        ->getContainer()
                                        ->registerMiddleWare($middleware['class']);
                        } catch (Throwable $e) {
-                               $appId = $middleware['appId'];
                                $this->logger->logException($e, [
                                        'message' => "Error during capability registration of $appId: " . $e->getMessage(),
                                        'level' => ILogger::ERROR,