diff --git a/src/Illuminate/View/Compilers/ComponentTagCompiler.php b/src/Illuminate/View/Compilers/ComponentTagCompiler.php index 9e079ac8a07c..d2f964a88c15 100644 --- a/src/Illuminate/View/Compilers/ComponentTagCompiler.php +++ b/src/Illuminate/View/Compilers/ComponentTagCompiler.php @@ -460,6 +460,10 @@ protected function getAttributesFromAttributeString(string $attributeString) $value = "'".$this->compileAttributeEchos($value)."'"; } + if (Str::startsWith($attribute, '::')) { + $attribute = substr($attribute, 1); + } + return [$attribute => $value]; })->toArray(); } @@ -490,7 +494,7 @@ protected function parseBindAttributes(string $attributeString) { $pattern = "/ (?:^|\s+) # start of the string or whitespace between attributes - : # attribute needs to start with a semicolon + :(?!:) # attribute needs to start with a single colon ([\w\-:.@]+) # match the actual attribute name = # only match attributes that have a value /xm"; diff --git a/tests/View/Blade/BladeComponentTagCompilerTest.php b/tests/View/Blade/BladeComponentTagCompilerTest.php index c9b89df6096e..a00744859d45 100644 --- a/tests/View/Blade/BladeComponentTagCompilerTest.php +++ b/tests/View/Blade/BladeComponentTagCompilerTest.php @@ -72,6 +72,14 @@ public function testColonData() withAttributes([]); ?> @endComponentClass##END-COMPONENT-CLASS##", trim($result)); } + public function testEscapedColonAttribute() + { + $result = $this->compiler(['profile' => TestProfileComponent::class])->compileTags(''); + + $this->assertSame("##BEGIN-COMPONENT-CLASS##@component('Illuminate\Tests\View\Blade\TestProfileComponent', 'profile', ['userId' => 1]) +withAttributes([':title' => 'user.name']); ?> @endComponentClass##END-COMPONENT-CLASS##", trim($result)); + } + public function testColonAttributesIsEscapedIfStrings() { $result = $this->compiler(['profile' => TestProfileComponent::class])->compileTags('');