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

[ErrorException] strtotime(): Epoch doesn't fit in a PHP integer during date validation when exceeding current epoch. #40686

Closed
coderkoala opened this issue Jan 28, 2022 · 13 comments

Comments

@coderkoala
Copy link
Contributor

  • Laravel Version: 8
  • PHP Version: 8
  • Database Driver & Version: MariaDB Latest docker image

Description:

In cases of extreme oversight, there's a way to run into an exception if you try to put in some obscenely far away date, as it'd exceed PHP's integer size when trying to use strtotime.

Petition to have exception handling introduced to have a safety fallback.

Steps To Reproduce:

  • Setup a date field frontend, relying solely on backend validation.
  • Try to setup that date field validate using the inbuilt date callback function.
  • Call the validator on a date callback, with an example value of 12-2-4123.
  • Encounter the problem.

Problematic code area:

laravel\framework\src\Illuminate\Validation\Concerns\ValidatesAttributes.php:452

Workaround:

Validate client side, add a custom function for date fields until resolved.

@coderkoala
Copy link
Contributor Author

Is there interest in having this issue fixed? I'd be more than happy to contribute a fix.

Proposed solution:

  • Cleanest: Add in a simple check in the if condition to check if the date exists within this epoch.
  • More thorough: introduce a try-catch block when trying to call strtotime.

I'd like to point further that this isn't strictly a laravel related issue, other libraries face the same issues when calling the function. It's more to do with PHP than Laravel. Still having a fix for this would be great, as dates are indispensable :)

@driesvints
Copy link
Member

Hmm, yeah it might be best to fix this. I think the try/catch can be a good first attempt and if that's refused, maybe the other solution. Can you maybe also give a really easy snippet with the validator to reproduce the issue?

@driesvints
Copy link
Member

Hmm, just tried it with this and that works:

Validator::make( [
  'foo' => '12-2-4123',
], [
  'foo' => 'date',
])->validate();

Can you provide the exact code that causes this?

@coderkoala
Copy link
Contributor Author

Sure thing :)

        $validationObject = Validator::make($request->all(), $this->validationRules);
        try {
            $validationFlag = $validationObject->fails();
        } catch( \Exception $e ) {
            $validationFlag = false;
        }

Despite this, I end up getting the error.

@driesvints
Copy link
Member

I'll need the exact data and the exact rules

@coderkoala
Copy link
Contributor Author

coderkoala commented Jan 28, 2022

[
    'created_at' => [
    'label' => __('Created At'),
    'placeholder' => __('Select appropriate Date'),
    'validation' => 'sometimes|date|before:2099-01-01',
    'required' => false,
    'type' => 'date',
    'render' => false,
    'hidden' => true
],
'valid_until' => [
    'label' => __('Valid Until'),
    'placeholder' => __('Select appropriate Date'),
    'validation' => 'required|date|before:2099-01-01',
    'required' => true,
    'type' => 'date',
    'render' => true,
    'hidden' => false
],
'updated_at' => [
    'label' => __('Updated At'),
    'placeholder' => __('Select appropriate Date'),
    'validation' => 'sometimes|date|before:2099-01-01',
    'required' => false,
    'type' => 'date',
    'render' => false,
    'hidden' => true
],
'deleted_at' => [
    'label' => __('Deleted At'),
    'placeholder' => __('Select appropriate Date'),
    'validation' => 'nullable|date|before:2099-01-01',
    'required' => false,
    'type' => 'date',
    'render' => false,
    'hidden' => true
]

I used 12-12-4999 to first encounter this bug.

@driesvints
Copy link
Member

Please post it like the example I shared. The exact code snippet with data.

@coderkoala
Copy link
Contributor Author

image

My request data was this(Laravel's Dump and die request object):

array:7 [▼
  "_token" => "aAI55QeK5Lv1G1N0psaJuqN8OwQcuinF6eJkeOhy"
  "name" => "qweqweqwe"
  "phone" => "9888888888"
  "email" => "iamtribulation@outlook.com"
  "license_data" => "{}"
  "user_id" => "1"
  "valid_until" => "4123-12-04"
]

All I did was

        $validationObject = Validator::make($request->all(), $this->validationRules);
        $validationFlag = $validationObject->fails();

$this->validationRules is as follows:

array:10 [▼
  "name" => "required|max:160"
  "phone" => "nullable|digits:10"
  "email" => "nullable|regex:/^.+@.+$/i|max:255"
  "license_key" => "nullable|alpha_num|length:10"
  "license_data" => "required|json"
  "user_id" => "nullable|integer"
  "created_at" => "sometimes|date"
  "valid_until" => "required|date"
  "updated_at" => "sometimes|date"
  "deleted_at" => "nullable|date"
]

Wrapping the function in a try-catch does basically make the redirect back fire with nothing in the validation error message bag.

Here's my PHP info (I use laragon on a windows env)
image

Do kindly let me know if you need any more info. I'm currently working on a fix on this.

@coderkoala
Copy link
Contributor Author

Entire stack shared here: https://flareapp.io/share/yPay4laP

@driesvints
Copy link
Member

I'm sorry but I can still not reproduce it with the data you provided:

Validator::make([
  "_token" => "aAI55QeK5Lv1G1N0psaJuqN8OwQcuinF6eJkeOhy",
  "name" => "qweqweqwe",
  "phone" => "9888888888",
  "email" => "iamtribulation@outlook.com",
  "license_data" => "{}",
  "user_id" => "1",
  "valid_until" => "4123-12-04",
], [
  "name" => "required|max:160",
  "phone" => "nullable|digits:10",
  "email" => "nullable|regex:/^.+@.+$/i|max:255",
  "license_key" => "nullable|alpha_num|length:10",
  "license_data" => "required|json",
  "user_id" => "nullable|integer",
  "created_at" => "sometimes|date",
  "valid_until" => "required|date",
  "updated_at" => "sometimes|date",
  "deleted_at" => "nullable|date",
])->validate();

This passes for me on the latest Laravel 8 version. I'll need to redirect you to a support channel:

@coderkoala
Copy link
Contributor Author

coderkoala commented Jan 28, 2022

@driesvints I'm sorry, but let me get this straight: Just because you're not able to replicate the issue, the issue doesn't exist? I've seen people face pitfalls with that attitude, but I'll trust your judgement with this one, I have no need for support.

I'll make a PR regardless, it should be non-invasive, add in a bit of defensive programming against strtotime failing in case of an integer overflow during conversion. I invite you to close the PR if you think it's a waste of your time.

@driesvints
Copy link
Member

@coderkoala more than welcome to send in the PR but I can't verify the issue if I can't reproduce it.

@willrowe
Copy link
Contributor

@coderkoala is the machine you are running PHP on 32-bit?

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

No branches or pull requests

3 participants