Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Form] weaken the rejection of submitted array data #29911

Closed
wants to merge 1 commit into from

Conversation

xabbuh
Copy link
Member

@xabbuh xabbuh commented Jan 16, 2019

Q A
Branch? 3.4
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #29809, #29841, #29905
License MIT
Doc PR

It seems that the bugfix made in #29307 seems to break quite some applications. I therefore suggest that we solve the issue a bit different by introducing a new accept_multiple_values option. This value will be null by default which means no checks will be performed for backwards compatibility. The core form types do explicitly set this value to false if they expect the submitted data to be strings. If a form is compound, the option value will automatically default to true.

Since from my experience most custom form types have child forms, they are already compound and so do accept arrays. Nothing will change for them. Other custom types will not have the check as long as they do not extend one of the built-in types that have this check enabled.

In Symfony 4.3 we can then deprecate the null default value so that each type must opt for either true or false as the value in 5.0.

@@ -328,6 +328,8 @@ public function configureOptions(OptionsResolver $resolver)
'placeholder' => $placeholderDefault,
'error_bubbling' => false,
'compound' => $compound,
// submitted arrays are dealt with in data transformers
'accept_multiple_values' => true,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if that's the best name. I could also imagine something like accept_array_data.

Copy link

@YetiCGN YetiCGN Jan 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: accept_unstructured_data? "Array" could be mistaken for a flat array without special string keys, just like multiple values on a TextType.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'scalar' => false?

@nicolas-grekas
Copy link
Member

Will that make the reported breaks work again? Eg submitting a json-decoded array in a TextType?
I'm not sure we should do this for now: input data should always be strictly validated. Allowing arrays was a really nasty behavior, on the edge of a security risk maybe for some.

@OskarStark
Copy link
Contributor

bugfix made in # seems to break

which PR are you talking about? 🤔

@althaus
Copy link
Contributor

althaus commented Jan 17, 2019

@OskarStark See #29809 for the main discussion triggered by PR #29307 .

@althaus
Copy link
Contributor

althaus commented Jan 17, 2019

The core form types do explicitly set this value to false if they expect the submitted data to be strings.

What'd the behaviour of the null form type which defaults to TextType? My reading is that those "evil" forms are still broken?

@xabbuh
Copy link
Member Author

xabbuh commented Jan 17, 2019

@nicolas-grekas As long as you do not explicitly set the accept_multiple_values to true yourself array values would still be rejected (that's why we need to be explicit about this in the core form types).

But what this will allow easily again having a custom type like this:

class UnstructuredType extends AbstractType
{
}

@althaus Yes, if you are not explicitly about the type being used and the TextType is the result of the guessing process, this PR does not change anything for you.

@alexander-schranz
Copy link
Contributor

alexander-schranz commented Jan 17, 2019

@xabbuh if I'm interpereting it correctly I could use for unstructured data this then:

use Symfony\Component\Form\Extension\Core\Type\FormType;

$builder->add('some_unstructured_data', FormType::class');

@xabbuh
Copy link
Member Author

xabbuh commented Jan 17, 2019

@alexander-schranz Yes, that should work (that basically is the same as this test: https://github.com/symfony/symfony/pull/29911/files#diff-de65be85a5affed1f499b79d96965419R1062). But I'd be happy if you could confirm that in your application context.

$this->form->add($this->getBuilder('foo', null, null, ['compound' => true])->getForm());

$this->form->submit([
'foo' => ['foo'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would also add test for a nested array not just a list:

[
  'foo' => [
    'foo' => 'foo',
    'bar' => [
      'baz' => 'baz',
    ]
  ]
]

@xabbuh

@alexander-schranz
Copy link
Contributor

@xabbuh will test it in the application at the evening. Thank you for having a look at the issue!

@xabbuh
Copy link
Member Author

xabbuh commented Jan 17, 2019

@alexander-schranz makes sense, done

@@ -37,6 +37,7 @@ public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'compound' => false,
'accept_multiple_values' => false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xabbuh this should set to true until 5.0 to avoid the bc break which was introduce in 3.4.21, else applications which did work before 3.4.21 still would crash.

@nicolas-grekas
Copy link
Member

I'm not sure at all we should do this change.
The behavior change we introduced is a bug fix.
I'm sorry some "hacked" the component and are caught by the fix, but every bug fix does that potentially.
Does this PR provide something that cannot be achieved otherwise?
Adding a new option means added complexity for everyone, better think twice about it.

@althaus
Copy link
Contributor

althaus commented Jan 21, 2019

I'm sorry some "hacked" the component

I'm pretty sure that 9 out of 10 didn't do this on purpose, but either by accident or due to lacking docs back then. The Form component really can be a b**ch sometimes. It's the only one forcing us to rework code parts every now and then due to some "fix". :/

I can also see that adding a fire-and-forget option just for this small thing on all those classes could raise more headache than it solves. So I'd be glad if someone can imagine a solution working for both sides.

@fnagel
Copy link
Contributor

fnagel commented Jan 21, 2019

I'm sorry some "hacked" the component and are caught by the fix, but every bug fix does that potentially.

True that, but even big bundles like RestBundle using that "hack" and recommend it in their docs.

@nicolas-grekas
Copy link
Member

True that, but even big bundles like RestBundle using that "hack" and recommend it in their docs.

time to fix them!

@dmaicher
Copy link
Contributor

I'm also not sure I would fix this by adding another option. I find it too confusing to have

  • compound
  • multiple
  • accept_multiple_values (or whatever new name we pick)

In the end the fix for all affected users would be something like this here, or not?
sulu/sulu#4349

@xabbuh
Copy link
Member Author

xabbuh commented Jan 21, 2019

@dmaicher Basically yes, except that the type could be shortened to not have to include the configureOptions() method at all.

@xabbuh xabbuh closed this Jan 25, 2019
@xabbuh xabbuh deleted the issue-29809 branch January 25, 2019 10:10
@xabbuh
Copy link
Member Author

xabbuh commented Jan 25, 2019

closing here as it doesn't look like the proposed change is of interest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants