codeigniter4 / CodeIgniter4

Open Source PHP Framework (originally from EllisLab)
https://codeigniter.com/
MIT License
5.38k stars 1.9k forks source link

Bug: File validation rule `max_size` doesn't allow not provided file #8250

Closed MaulanaMalikS closed 11 months ago

MaulanaMalikS commented 11 months ago

PHP Version

8.2

CodeIgniter4 Version

v4.4.1

CodeIgniter4 Installation Method

Composer (using codeigniter4/appstarter)

Which operating systems have you tested for this bug?

Windows

Which server did you use?

cli

Database

No response

What happened?

I'm currently working on an API that includes file upload functionality. I've implemented validation, including a rule to check the maximum file size. Here's a simplified version of the validation method:

private function getValidationErrors(array $data): array
{
    // ... rest of the code ...
    $rules['file'] = ['max_size[file,64000]'];

    $this->validateData($data, $rules);

    // ... rest of the code ...
}

When I submit the data with file param is empty, the validation run correctly:

285563112-2c0fc615-6433-435f-b267-6a673267174b

But when I submit the data without file param at all, the validation return error:

285563481-6ec67e71-7330-4cdf-93fd-5761488ccdf8

As per the CodeIgniter documentation, "Only rules specifically created for file validation (like the ones listed in the table above) can be used to validate files. Therefore, adding any general rules, like permit_empty, to file validation rules array or string, the file validation will not work correctly."

My goal is to make the file field optional while still applying the max_size rule. This works as expected when I submit an file filed with empty data, but not when I don't include the file field at all.

Upon inspecting the CodeIgniter CodeIgniter\Validation\FileRules class: https://github.com/codeigniter4/CodeIgniter4/blob/develop/system/Validation/FileRules.php#L98-L100 I suspect that the initial check ($file === null) is make the validation to return error when the field is not provided. This behavior seems counterintuitive, as it suggests that submitting a field with empty data is different from not including the field at all.

Also I think it's not a good solution if I have to check whether the file field is submitted (even if it's empty) and then apply the rule, and skipping the rule if the field is not submitted.

Steps to Reproduce

Use max_size validation rules.

Expected Output

The validation not return error when file field is not submitted.

Anything else?

https://github.com/codeigniter4/CodeIgniter4/blob/develop/system/Validation/FileRules.php#L98-L100 Changing CodeIgniter\Validation\FileRules on line 98 - 100 to:

if ($file === null) {
    return true;
}

fix the problem

kenjis commented 11 months ago

I'm not sure, but what if you add the if_exist rule?

MaulanaMalikS commented 11 months ago

I'm not sure, but what if you add the if_exist rule?

Yes, it works, but the documentation states that Only rules specifically created for file validation (like the ones listed in the table above) can be used to validate files. https://codeigniter.com/user_guide/libraries/validation.html#rules-for-file-uploads Does this mean the documentation is incorrect, or is my understanding wrong?

kenjis commented 11 months ago

No, it does not work. Even if you upload a file, the Validation does not check the file at all. We cannot use if_exist either, because the rule does not check $_FILE, and when you upload a file with form-data, PHP sets it in $_FILE. The documentation is correct.

kenjis commented 11 months ago

It seems you need a new special rule if_exist for File Uploads.

Or check if a file is uploaded and skip the validation. See https://codeigniter4.github.io/CodeIgniter4/libraries/uploaded_files.html#single-file

kenjis commented 11 months ago

This is not a bug. The rule max_size should return false if file does not exist. Other rules does like that.

MaulanaMalikS commented 11 months ago

No, it does not work. Even if you upload a file, the Validation does not check the file at all. We cannot use if_exist either, because the rule does not check $_FILE, and when you upload a file with form-data, PHP sets it in $_FILE. The documentation is correct.

My bad, I only checked for if_exist without uploading files and did not check when files is uploaded.

It seems you need a new special rule if_exist for File Uploads.

I'm certain that's the case. Is there any plan to add the if_exist rule for File Upload anytime soon?

Thanks for your responses!

kenjis commented 11 months ago

Is there any plan to add the if_exist rule for File Upload anytime soon?

No.