Prevent infinite loop for nested language items (#3299)
authorMatthias Schmidt <gravatronics@live.com>
Fri, 22 May 2020 11:34:43 +0000 (13:34 +0200)
committerGitHub <noreply@github.com>
Fri, 22 May 2020 11:34:43 +0000 (13:34 +0200)
* Prevent infinite loop for nested language items

Close #3163

* Improve exception message in Language::loadCategory()

Co-authored-by: Alexander Ebert <ebert@woltlab.com>
Co-authored-by: Alexander Ebert <ebert@woltlab.com>
wcfsetup/install/files/lib/data/language/Language.class.php

index 448bac6df079523ef5702a77674503244b479f4a..ec8d2ea38ae2b8199ee7a5e7bc87578c0c336280 100644 (file)
@@ -46,6 +46,12 @@ class Language extends DatabaseObject {
         */
        public $packageID = PACKAGE_ID;
        
+       /**
+        * contains categories currently being loaded as array keys
+        * @var bool[]
+        */
+       protected $categoriesBeingLoaded = [];
+       
        /**
         * Returns the name of this language.
         * 
@@ -210,6 +216,10 @@ class Language extends DatabaseObject {
                // search language file
                $filename = WCF_DIR.'language/'.$this->languageID.'_'.$category.'.php';
                if (!@file_exists($filename)) {
+                       if (isset($this->categoriesBeingLoaded[$category])) {
+                               throw new \LogicException("Circular dependency detected! Cannot load category '{$category}' while it is already being loaded.");
+                       }
+                       
                        if ($this->editor === null) {
                                $this->editor = new LanguageEditor($this);
                        }
@@ -220,7 +230,11 @@ class Language extends DatabaseObject {
                                return false;
                        }
                        
+                       $this->categoriesBeingLoaded[$category] = true;
+                       
                        $this->editor->updateCategory($languageCategory);
+                       
+                       unset($this->categoriesBeingLoaded[$category]);
                }
                
                // include language file