Right-trim empty and optional attributes
authorAlexander Ebert <ebert@woltlab.com>
Wed, 21 Feb 2018 11:18:38 +0000 (12:18 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Wed, 21 Feb 2018 11:18:44 +0000 (12:18 +0100)
wcfsetup/install/files/lib/system/bbcode/BBCodeParser.class.php

index 3457de3fc588b43254fa9b5e7975edb706df0f74..1820ef5dda3979b3912cf1c4a4d8b22d8ae78011 100644 (file)
@@ -215,8 +215,29 @@ class BBCodeParser extends SingletonFactory {
                        return false;
                }
                
+               $tagAttributes = (isset($tag['attributes']) ? $tag['attributes'] : []);
+               
+               // right trim any attributes that are truly empty (= zero-length string) and are defined to be optional
+               $bbcodeAttributes = $this->bbcodes[$tag['name']]->getAttributes();
+               // reverse sort the bbcode attributes to start with the last attribute
+               usort($bbcodeAttributes, function(BBCodeAttribute $a, BBCodeAttribute $b) {
+                       if ($a->attributeNo == $b->attributeNo) return 0;
+                       return ($a->attributeNo < $b->attributeNo) ? 1 : -1;
+               });
+               foreach ($bbcodeAttributes as $attribute) {
+                       if ($attribute->required) break;
+                       
+                       $i = $attribute->attributeNo;
+                       if (isset($tagAttributes[$i]) && $tagAttributes[$i] === '' && !isset($tagAttributes[$i + 1])) {
+                               unset($tagAttributes[$i]);
+                       }
+                       else {
+                               break;
+                       }
+               }
+               
                foreach ($this->bbcodes[$tag['name']]->getAttributes() as $attribute) {
-                       if (!$this->isValidTagAttribute((isset($tag['attributes']) ? $tag['attributes'] : []), $attribute)) {
+                       if (!$this->isValidTagAttribute($tagAttributes, $attribute)) {
                                return false;
                        }
                }