Issue #2560137 by dawehner, pwolanin, klausi, tsphethean, sun: Posting an array as value of a form element is allowed even when a string is expected (and bypasses #maxlength constraints) - first step: text fields
parent
7569493d97
commit
e513467c52
|
@ -104,6 +104,11 @@ class MachineName extends Textfield {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
|
||||
if ($input !== FALSE && $input !== NULL) {
|
||||
// This should be a string, but allow other scalars since they might be
|
||||
// valid input in programmatic form submissions.
|
||||
return is_scalar($input) ? (string) $input : '';
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element;
|
||||
|
||||
/**
|
||||
|
@ -68,4 +69,16 @@ class Password extends FormElement {
|
|||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
|
||||
if ($input !== FALSE && $input !== NULL) {
|
||||
// This should be a string, but allow other scalars since they might be
|
||||
// valid input in programmatic form submissions.
|
||||
return is_scalar($input) ? (string) $input : '';
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,9 +50,20 @@ class PasswordConfirm extends FormElement {
|
|||
*/
|
||||
public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
|
||||
if ($input === FALSE) {
|
||||
$element += array('#default_value' => array());
|
||||
return $element['#default_value'] + array('pass1' => '', 'pass2' => '');
|
||||
$element += ['#default_value' => []];
|
||||
return $element['#default_value'] + ['pass1' => '', 'pass2' => ''];
|
||||
}
|
||||
$value = ['pass1' => '', 'pass2' => ''];
|
||||
// Throw out all invalid array keys; we only allow pass1 and pass2.
|
||||
foreach ($value as $allowed_key => $default) {
|
||||
// These should be strings, but allow other scalars since they might be
|
||||
// valid input in programmatic form submissions. Any nested array values
|
||||
// are ignored.
|
||||
if (isset($input[$allowed_key]) && is_scalar($input[$allowed_key])) {
|
||||
$value[$allowed_key] = (string) $input[$allowed_key];
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element;
|
||||
|
||||
/**
|
||||
|
@ -55,4 +56,15 @@ class Textarea extends FormElement {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
|
||||
if ($input !== FALSE && $input !== NULL) {
|
||||
// This should be a string, but allow other scalars since they might be
|
||||
// valid input in programmatic form submissions.
|
||||
return is_scalar($input) ? (string) $input : '';
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,10 +77,14 @@ class Textfield extends FormElement {
|
|||
*/
|
||||
public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
|
||||
if ($input !== FALSE && $input !== NULL) {
|
||||
// Equate $input to the form value to ensure it's marked for
|
||||
// validation.
|
||||
// This should be a string, but allow other scalars since they might be
|
||||
// valid input in programmatic form submissions.
|
||||
if (!is_scalar($input)) {
|
||||
$input = '';
|
||||
}
|
||||
return str_replace(array("\r", "\n"), '', $input);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,9 +39,12 @@ class Token extends Hidden {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
|
||||
if ($input !== FALSE) {
|
||||
return (string) $input;
|
||||
if ($input !== FALSE && $input !== NULL) {
|
||||
// This should be a string, but allow other scalars since they might be
|
||||
// valid input in programmatic form submissions.
|
||||
return is_scalar($input) ? (string) $input : '';
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Render\Element\MachineNameTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element\MachineName;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Render\Element\MachineName
|
||||
* @group Render
|
||||
*/
|
||||
class MachineNameTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::valueCallback
|
||||
*
|
||||
* @dataProvider providerTestValueCallback
|
||||
*/
|
||||
public function testValueCallback($expected, $input) {
|
||||
$element = [];
|
||||
$form_state = $this->prophesize(FormStateInterface::class)->reveal();
|
||||
$this->assertSame($expected, MachineName::valueCallback($element, $input, $form_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testValueCallback().
|
||||
*/
|
||||
public function providerTestValueCallback() {
|
||||
$data = [];
|
||||
$data[] = [NULL, FALSE];
|
||||
$data[] = [NULL, NULL];
|
||||
$data[] = ['', ['test']];
|
||||
$data[] = ['test', 'test'];
|
||||
$data[] = ['123', 123];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Render\Element\PasswordConfirmTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element\PasswordConfirm;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Render\Element\PasswordConfirm
|
||||
* @group Render
|
||||
*/
|
||||
class PasswordConfirmTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::valueCallback
|
||||
*
|
||||
* @dataProvider providerTestValueCallback
|
||||
*/
|
||||
public function testValueCallback($expected, $element, $input) {
|
||||
$form_state = $this->prophesize(FormStateInterface::class)->reveal();
|
||||
$this->assertSame($expected, PasswordConfirm::valueCallback($element, $input, $form_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testValueCallback().
|
||||
*/
|
||||
public function providerTestValueCallback() {
|
||||
$data = [];
|
||||
$data[] = [['pass1' => '', 'pass2' => ''], [], NULL];
|
||||
$data[] = [['pass1' => '', 'pass2' => ''], ['#default_value' => ['pass2' => 'value']], NULL];
|
||||
$data[] = [['pass2' => 'value', 'pass1' => ''], ['#default_value' => ['pass2' => 'value']], FALSE];
|
||||
$data[] = [['pass1' => '123456', 'pass2' => 'qwerty'], [], ['pass1' => '123456', 'pass2' => 'qwerty']];
|
||||
$data[] = [['pass1' => '123', 'pass2' => '234'], [], ['pass1' => 123, 'pass2' => 234]];
|
||||
$data[] = [['pass1' => '', 'pass2' => '234'], [], ['pass1' => ['array'], 'pass2' => 234]];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Render\Element\PasswordTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element\Password;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Render\Element\Password
|
||||
* @group Render
|
||||
*/
|
||||
class PasswordTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::valueCallback
|
||||
*
|
||||
* @dataProvider providerTestValueCallback
|
||||
*/
|
||||
public function testValueCallback($expected, $input) {
|
||||
$element = [];
|
||||
$form_state = $this->prophesize(FormStateInterface::class)->reveal();
|
||||
$this->assertSame($expected, Password::valueCallback($element, $input, $form_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testValueCallback().
|
||||
*/
|
||||
public function providerTestValueCallback() {
|
||||
$data = [];
|
||||
$data[] = [NULL, FALSE];
|
||||
$data[] = [NULL, NULL];
|
||||
$data[] = ['', ['test']];
|
||||
$data[] = ['test', 'test'];
|
||||
$data[] = ['123', 123];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Render\Element\TextareaTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element\Textarea;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Render\Element\Textarea
|
||||
* @group Render
|
||||
*/
|
||||
class TextareaTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::valueCallback
|
||||
*
|
||||
* @dataProvider providerTestValueCallback
|
||||
*/
|
||||
public function testValueCallback($expected, $input) {
|
||||
$element = [];
|
||||
$form_state = $this->prophesize(FormStateInterface::class)->reveal();
|
||||
$this->assertSame($expected, Textarea::valueCallback($element, $input, $form_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testValueCallback().
|
||||
*/
|
||||
public function providerTestValueCallback() {
|
||||
$data = [];
|
||||
$data[] = [NULL, FALSE];
|
||||
$data[] = [NULL, NULL];
|
||||
$data[] = ['', ['test']];
|
||||
$data[] = ['test', 'test'];
|
||||
$data[] = ['123', 123];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Render\Element\TextfieldTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element\Textfield;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Render\Element\Textfield
|
||||
* @group Render
|
||||
*/
|
||||
class TextfieldTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::valueCallback
|
||||
*
|
||||
* @dataProvider providerTestValueCallback
|
||||
*/
|
||||
public function testValueCallback($expected, $input) {
|
||||
$element = [];
|
||||
$form_state = $this->prophesize(FormStateInterface::class)->reveal();
|
||||
$this->assertSame($expected, Textfield::valueCallback($element, $input, $form_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testValueCallback().
|
||||
*/
|
||||
public function providerTestValueCallback() {
|
||||
$data = [];
|
||||
$data[] = [NULL, FALSE];
|
||||
$data[] = [NULL, NULL];
|
||||
$data[] = ['', ['test']];
|
||||
$data[] = ['test', 'test'];
|
||||
$data[] = ['123', 123];
|
||||
$data[] = ['testwithnewline', "test\nwith\rnewline"];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Render\Element\TokenTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element\Token;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Render\Element\Token
|
||||
* @group Render
|
||||
*/
|
||||
class TokenTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::valueCallback
|
||||
*
|
||||
* @dataProvider providerTestValueCallback
|
||||
*/
|
||||
public function testValueCallback($expected, $input) {
|
||||
$element = [];
|
||||
$form_state = $this->prophesize(FormStateInterface::class)->reveal();
|
||||
$this->assertSame($expected, Token::valueCallback($element, $input, $form_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testValueCallback().
|
||||
*/
|
||||
public function providerTestValueCallback() {
|
||||
$data = [];
|
||||
$data[] = [NULL, FALSE];
|
||||
$data[] = [NULL, NULL];
|
||||
$data[] = ['', ['test']];
|
||||
$data[] = ['test', 'test'];
|
||||
$data[] = ['123', 123];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue