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

Validating array where keys contain forward slashes #25146

Closed
sorge-it opened this issue Aug 8, 2018 · 5 comments
Closed

Validating array where keys contain forward slashes #25146

sorge-it opened this issue Aug 8, 2018 · 5 comments

Comments

@sorge-it
Copy link

sorge-it commented Aug 8, 2018

  • Laravel Version: 5.6.29
  • PHP Version: 7.2.8

Description:

When running validator on an array key which contains a forward slash, I run into an error exception in Validator.php line 2716 (Validator::getExplicitKeys($attribute), where preg_match is run on $pattern generated from the attribute.

I have not found the proper way (if there is any) to escape this forward slash, and note that in my use case the data comes in a pre-specified format which I cannot change. I realise I could change the key before validation, but I am wondering if there is a way to make the validator work as-is, or if the validator is even intended to work in this case.

The bug was already discuessed and fixed in 5.3: #16287
but was re-introduced in 5.4.

Steps To Reproduce:

The following code does not work, since calling $validator->fails() generates the ErrorException.

	$arr = [
			'fine' => 'foo',
		        'not/fine' => 'bar'
		];
		$validator = Validator::make($arr, [
			'fine' => 'required',
		        'not/fine' => 'required',
		]);

		if($validator->fails()) {
			dd('uh-oh');
		}
@staudenmeir
Copy link
Contributor

You must be running an older Laravel version.

It works for me and getExplicitKeys() is now in a different line.

@sorge-it
Copy link
Author

sorge-it commented Aug 8, 2018

Yes and no.

This is the 5.3 patch: 0b04c1d

The exception is thrown in line 61:
https://github.com/laravel/framework/blob/5.6/src/Illuminate/Validation/ValidationData.php

54 protected static function extractValuesForWildcards($masterData, $data, $attribute)
55    {
56        $keys = [];
57
57        $pattern = str_replace('\*', '[^\.]+', preg_quote($attribute));
58        foreach ($data as $key => $value) {
59
60            if ((bool) preg_match('/^'.$pattern.'/', $key, $matches)) {
61                $keys[] = $matches[0];

because preg_quote is missing the '/' parameter in line 57. This works fine:

57 $pattern = str_replace('\*', '[^\.]+', preg_quote($attribute, '/'));

@Miguel-Serejo
Copy link

Cannot reproduce on 5.6.29:

>>> $arr = [ 'fine' => 'foo', 'not/fine' => 'bar'];
=> [
     "fine" => "foo",
     "not/fine" => "bar",
   ]
>>> $validator = Validator::make($arr, ['fine' => 'required', 'not/fine' => 'required', ]);
=> Illuminate\Validation\Validator {#2942
     +customMessages: [],
     +fallbackMessages: [],
     +customAttributes: [],
     +customValues: [],
     +extensions: [],
     +replacers: [],
   }
>>> $validator->fails()
=> false
>>> $validator->passes()
=> true

@staudenmeir
Copy link
Contributor

Are you using wildcard rules with .*.?

@sorge-it
Copy link
Author

sorge-it commented Aug 9, 2018

Sorry guys, I did not give you enough information.

So here is the failing code (tinker):

>>> \Validator::validate(
            [
                'data' => [
                    'catalog' => [
                        'foo/' => [
                            'attribute1' => null,
                        ],
                    ],
                ],
            ],
            [
                'data.catalog.*.attribute1' => 'sometimes',
            ]
        );
...             [
...                 'data' => [
...                     'catalog' => [
...                         'foo/' => [
...                             'attribute1' => null,
...                         ],
...                     ],
...                 ],
...             ],
...             [
...                 'data.catalog.*.attribute1' => 'sometimes',
...             ]
...         );
PHP Warning:  preg_match(): Unknown modifier '/' in 
xxx/vendor/laravel/framework/src/Illuminate/Validation/ValidationData.php on line 61
>>>

The problem only exists, when you include the sometimes validator. If sometimes is not in the list of validators, the code works fine. In my production code I use sometimes|array|nullable.

Thanks!

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

No branches or pull requests

4 participants