Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 142984d

Browse files
[Form] Always normalize CRLF and CR to LF in TextareaType
1 parent 32254a5 commit 142984d

6 files changed

Lines changed: 277 additions & 0 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\Extension\Core\EventListener;
13+
14+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15+
use Symfony\Component\Form\FormEvent;
16+
use Symfony\Component\Form\FormEvents;
17+
use Symfony\Component\Form\Util\StringUtil;
18+
19+
/**
20+
* @author Alexandre Daubois <[email protected]>
21+
*/
22+
class CrlfNormalizerListener implements EventSubscriberInterface
23+
{
24+
public function preSubmit(FormEvent $event): void
25+
{
26+
if (!\is_string($data = $event->getData())) {
27+
return;
28+
}
29+
30+
$event->setData(StringUtil::normalizeNewlines($data));
31+
}
32+
33+
public static function getSubscribedEvents(): array
34+
{
35+
return [FormEvents::PRE_SUBMIT => 'preSubmit'];
36+
}
37+
}

src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,21 @@
1212
namespace Symfony\Component\Form\Extension\Core\Type;
1313

1414
use Symfony\Component\Form\AbstractType;
15+
use Symfony\Component\Form\Extension\Core\EventListener\CrlfNormalizerListener;
16+
use Symfony\Component\Form\FormBuilderInterface;
1517
use Symfony\Component\Form\FormInterface;
1618
use Symfony\Component\Form\FormView;
1719

1820
class TextareaType extends AbstractType
1921
{
22+
/**
23+
* @return void
24+
*/
25+
public function buildForm(FormBuilderInterface $builder, array $options)
26+
{
27+
$builder->addEventSubscriber(new CrlfNormalizerListener());
28+
}
29+
2030
/**
2131
* @return void
2232
*/
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\Tests\Extension\Core\EventListener;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\EventDispatcher\EventDispatcher;
16+
use Symfony\Component\Form\Extension\Core\EventListener\CrlfNormalizerListener;
17+
use Symfony\Component\Form\Form;
18+
use Symfony\Component\Form\FormConfigBuilder;
19+
use Symfony\Component\Form\FormEvent;
20+
21+
class CrlfNormalizerListenerTest extends TestCase
22+
{
23+
public function testNormalizeCrlf()
24+
{
25+
$form = new Form(new FormConfigBuilder('name', null, new EventDispatcher()));
26+
$event = new FormEvent($form, "Line 1\r\nLine 2\r\nLine 3");
27+
28+
$listener = new CrlfNormalizerListener();
29+
$listener->preSubmit($event);
30+
31+
$this->assertSame("Line 1\nLine 2\nLine 3", $event->getData());
32+
}
33+
34+
public function testNormalizeCr()
35+
{
36+
$form = new Form(new FormConfigBuilder('name', null, new EventDispatcher()));
37+
$event = new FormEvent($form, "Line 1\rLine 2\rLine 3");
38+
39+
$listener = new CrlfNormalizerListener();
40+
$listener->preSubmit($event);
41+
42+
$this->assertSame("Line 1\nLine 2\nLine 3", $event->getData());
43+
}
44+
45+
public function testNormalizeMixedNewlines()
46+
{
47+
$form = new Form(new FormConfigBuilder('name', null, new EventDispatcher()));
48+
$event = new FormEvent($form, "Line 1\r\nLine 2\rLine 3\nLine 4");
49+
50+
$listener = new CrlfNormalizerListener();
51+
$listener->preSubmit($event);
52+
53+
$this->assertSame("Line 1\nLine 2\nLine 3\nLine 4", $event->getData());
54+
}
55+
56+
public function testPreserveLf()
57+
{
58+
$form = new Form(new FormConfigBuilder('name', null, new EventDispatcher()));
59+
$event = new FormEvent($form, "Line 1\nLine 2\nLine 3");
60+
61+
$listener = new CrlfNormalizerListener();
62+
$listener->preSubmit($event);
63+
64+
$this->assertSame("Line 1\nLine 2\nLine 3", $event->getData());
65+
}
66+
67+
public function testSkipNonStrings()
68+
{
69+
$form = new Form(new FormConfigBuilder('name', null, new EventDispatcher()));
70+
$event = new FormEvent($form, 1234);
71+
72+
$listener = new CrlfNormalizerListener();
73+
$listener->preSubmit($event);
74+
75+
$this->assertSame(1234, $event->getData());
76+
}
77+
78+
public function testEmptyString()
79+
{
80+
$form = new Form(new FormConfigBuilder('name', null, new EventDispatcher()));
81+
$event = new FormEvent($form, '');
82+
83+
$listener = new CrlfNormalizerListener();
84+
$listener->preSubmit($event);
85+
86+
$this->assertSame('', $event->getData());
87+
}
88+
89+
public function testNoNewlines()
90+
{
91+
$data = 'Single line text';
92+
$form = new Form(new FormConfigBuilder('name', null, new EventDispatcher()));
93+
$event = new FormEvent($form, $data);
94+
95+
$listener = new CrlfNormalizerListener();
96+
$listener->preSubmit($event);
97+
98+
$this->assertSame('Single line text', $event->getData());
99+
}
100+
101+
public function testMultipleConsecutiveNewlines()
102+
{
103+
$data = "Line 1\r\n\r\n\r\nLine 2";
104+
$form = new Form(new FormConfigBuilder('name', null, new EventDispatcher()));
105+
$event = new FormEvent($form, $data);
106+
107+
$listener = new CrlfNormalizerListener();
108+
$listener->preSubmit($event);
109+
110+
$this->assertSame("Line 1\n\n\nLine 2", $event->getData());
111+
}
112+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
13+
14+
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
15+
16+
class TextareaTypeTest extends BaseTypeTestCase
17+
{
18+
public const TESTED_TYPE = TextareaType::class;
19+
20+
public function testSubmitNull($expected = null, $norm = null, $view = null)
21+
{
22+
parent::testSubmitNull($expected, $norm, '');
23+
}
24+
25+
public function testSubmitNormalizeCrlf()
26+
{
27+
$form = $this->factory->create(static::TESTED_TYPE);
28+
$form->submit("Line 1\r\nLine 2\r\nLine 3");
29+
30+
$this->assertSame("Line 1\nLine 2\nLine 3", $form->getData());
31+
}
32+
33+
public function testSubmitNormalizeCr()
34+
{
35+
$form = $this->factory->create(static::TESTED_TYPE);
36+
$form->submit("Line 1\rLine 2\rLine 3");
37+
38+
$this->assertSame("Line 1\nLine 2\nLine 3", $form->getData());
39+
}
40+
41+
public function testSubmitNormalizeMixedNewlines()
42+
{
43+
$form = $this->factory->create(static::TESTED_TYPE);
44+
$form->submit("Line 1\r\nLine 2\rLine 3\nLine 4");
45+
46+
$this->assertSame("Line 1\nLine 2\nLine 3\nLine 4", $form->getData());
47+
}
48+
49+
public function testSubmitPreserveLf()
50+
{
51+
$form = $this->factory->create(static::TESTED_TYPE);
52+
$form->submit("Line 1\nLine 2\nLine 3");
53+
54+
$this->assertSame("Line 1\nLine 2\nLine 3", $form->getData());
55+
}
56+
57+
public function testSubmitSingleLine()
58+
{
59+
$form = $this->factory->create(static::TESTED_TYPE);
60+
$form->submit('Single line text');
61+
62+
$this->assertSame('Single line text', $form->getData());
63+
}
64+
65+
public function testBuildViewDoesNotHavePattern()
66+
{
67+
$form = $this->factory->create(static::TESTED_TYPE);
68+
$view = $form->createView();
69+
70+
$this->assertNull($view->vars['pattern']);
71+
$this->assertArrayNotHasKey('pattern', $view->vars['attr']);
72+
}
73+
74+
public function testWithTrimDisabled()
75+
{
76+
$form = $this->factory->create(static::TESTED_TYPE, null, ['trim' => false]);
77+
$form->submit(" Line 1\r\nLine 2 ");
78+
79+
$this->assertSame(" Line 1\nLine 2 ", $form->getData());
80+
}
81+
82+
public function testWithTrimEnabled()
83+
{
84+
$form = $this->factory->create(static::TESTED_TYPE, null, ['trim' => true]);
85+
$form->submit(" Line 1\r\nLine 2 ");
86+
87+
$this->assertSame("Line 1\nLine 2", $form->getData());
88+
}
89+
}

src/Symfony/Component/Form/Tests/Util/StringUtilTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,27 @@ public static function spaceProvider(): array
8787
];
8888
}
8989

90+
public static function normalizeNewlinesProvider(): array
91+
{
92+
return [
93+
["Line 1\r\nLine 2", "Line 1\nLine 2"],
94+
["Line 1\rLine 2", "Line 1\nLine 2"],
95+
["Line 1\r\nLine 2\rLine 3\nLine 4", "Line 1\nLine 2\nLine 3\nLine 4"],
96+
["Line 1\nLine 2", "Line 1\nLine 2"],
97+
['', ''],
98+
['Single line', 'Single line'],
99+
["Line 1\r\n\r\n\r\nLine 2", "Line 1\n\n\nLine 2"],
100+
];
101+
}
102+
103+
/**
104+
* @dataProvider normalizeNewlinesProvider
105+
*/
106+
public function testNormalizeNewlines($data, $expectedData)
107+
{
108+
$this->assertSame($expectedData, StringUtil::normalizeNewlines($data));
109+
}
110+
90111
/**
91112
* @dataProvider fqcnToBlockPrefixProvider
92113
*/

src/Symfony/Component/Form/Util/StringUtil.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ public static function trim(string $string): string
3636
return trim($string);
3737
}
3838

39+
/**
40+
* Converts both CRLF and CR to LF.
41+
*/
42+
public static function normalizeNewlines(string $string): string
43+
{
44+
return str_replace(["\r\n", "\r"], "\n", $string);
45+
}
46+
3947
/**
4048
* Converts a fully-qualified class name to a block prefix.
4149
*

0 commit comments

Comments
 (0)