Repository: codeigniter4/CodeIgniter4 (PHP)

Issue:
Bug: Type Error when Validator gets unexpected structured array
PHP Version

7.4

CodeIgniter4 Version

4,1,5

CodeIgniter4 Installation Method

Composer (new project)

Which operating systems have you tested for this bug?

Linux

Which server did you use?

apache

Database

MariaDB 10.1.31

What happened?
When using array key validation as below example:
> 'arr.*.index' => 'required'

And receive data of array as below
> [1,2,3,4,5]

Send a php error because an array is required in dot_array_search and _dot_array_search functions using inside the validation 

Steps to Reproduce
```php
$data['arr'] = [1,2,3,4,5];
$validation->setRules([
    'arr.*.index' => 'required',
]);
```

Send a php error

Expected Output
Need to return false because invalid data?

Anything else?


Discussion:
Thank you for reporting. I confirmed the bug.

```php
<?php

namespace App\Controllers;

use Config\Services;

class Home extends BaseController
{
    public function index()
    {
        $validator = Services::validation();
        $validator->setRules([
           'arr.*.index' => 'required',
       ]);

        $data['arr'] = [1,2,3,4,5];

        $isValid = $validator->run($data);
        d($isValid);
    }
}
```

> TypeError
> _array_search_dot(): Argument #2 ($array) must be of type array, int given, called in .../CodeIgniter4/system/Helpers/array_helper.php on line 56

In principle, I would think it is up to the developer to make sure that the data structure passed to the validator is of the expected type (and/or dimensionality). 
@sfadschm
Validator checks the passed data (structure) is valid or not.
Do you want to  validate the structure before passing it to Validator?
I think I see your point, but I also think the core of the problem is rather that a misformed array is passed here.
The PR looks reasonable tough also for other cases to avoid dot-search to fail 👍 
>  I also think the core of the problem is rather that a misformed array is passed here.

What do you mean? Where is *here* ?

A web site visitor (or an attacker) can send a misformed array.
> > I also think the core of the problem is rather that a misformed array is passed here.
> 
> What do you mean? Where is _here_ ?
> 
> A web site visitor (or an attacker) can send a misformed array.

_Here_ was refering to validation after form input, but I missed the case of attacker input. I like the solution and misunderstood the problem, so all good from my side 😄 



Patch:
diff --git a/system/Helpers/array_helper.php b/system/Helpers/array_helper.php
index a06d4bb96c6e..423f9c266dd5 100644
--- a/system/Helpers/array_helper.php
+++ b/system/Helpers/array_helper.php
@@ -53,6 +53,10 @@ function _array_search_dot(array $indexes, array $array)
             $answer = [];
 
             foreach ($array as $value) {
+                if (! is_array($value)) {
+                    return null;
+                }
+
                 $answer[] = _array_search_dot($indexes, $value);
             }
 


Test patch:
diff --git a/tests/system/Helpers/ArrayHelperTest.php b/tests/system/Helpers/ArrayHelperTest.php
index f6ae751e1bda..68941d670ce9 100644
--- a/tests/system/Helpers/ArrayHelperTest.php
+++ b/tests/system/Helpers/ArrayHelperTest.php
@@ -46,6 +46,18 @@ public function testArrayDotTooManyLevels()
         $this->assertSame(23, dot_array_search('foo.bar.baz', $data));
     }
 
+    /**
+     * @see https://github.com/codeigniter4/CodeIgniter4/issues/5369
+     */
+    public function testArrayDotValueIsListArray()
+    {
+        $data = [
+            'arr' => [1, 2, 3],
+        ];
+
+        $this->assertNull(dot_array_search('arr.*.index', $data));
+    }
+
     public function testArrayDotEscape()
     {
         $data = [