ZF-1882: Improve integer validation

Description

Right now Zend_Validate_Int uses intval() function while checking if given value is valid integer. There is a problem with that solution because this validation rejects all correct integers that exceedes bounds of integer type. Also note that this method of validation sometimes also approves values like 0.00000001 as valid integers, which is wrong.

This can be easy fixed by using regular expressions instead of intval() function.

This code of isValid() method:


if (strval(intval($valueFiltered)) != $valueFiltered) {
      $this->_error();
      return false;
}

can be replaced by the following one:


if (!preg_match('/^[-+]?((\d+(\.0*)?)|(0x[\dABCDE]+))$/', $valueFiltered)) {
      $this->_error();
      return false;
}

This improvement will validate all, even extremely long integer values (passed as string of course, because we don't want value beyond integer type). This can be usefull when for example when working on databases that accepts wider range of integer values than php or when working on GMP values converted to string.

Comments

This leads to another problem:

When the locale of your environment is set to another value than 'en' the validation will not work anymore.

If you define 1000 as integer and cast it to an string you will get '1.000' when 'de' is set as locale or '1 000' if your locale is set to 'fr'.

You regex will not work in such environments...

The simplest solution would be to use Zend_Locale_Format::isInteger($number) for such cases... or as fallback to intval().

This doesn't appear to have been fixed in 1.5.0. Please update if this is not correct.

Please evaluate and categorize/assign as necessary.

Please review the attached patch.

The patch does not make clear the changes; could you re-attach a new version (e.g., with correct line endings)? Still, I'll apply the patch to my local copy and diff without regard to white space.

It appears this is just output of svn diff, not a {{patch}}-compatible file; please attach such a new version.

Sorry, i used wrong line endings. please check the attached file (new one)

{{setFailOnPhpIntegerBoundary()}} should return {{$this}} for convenience.

Also, it appears that {{$this->_error()}} is called without differentiating the cause of the error. It would be nice to expose the specific cause of the validation failure to the developer, rather than hiding it. Put another way, multiple causes of validation failure are producing the same validation failure message, which hides information that could otherwise be exposed to the application (e.g., for logging, usability analysis, etc.).

changes taken into account, please verify

V3 attached, please verify

In my eyes this patch is problematic.

Zend_Validate_Int accepts only english notation regarding to replacing the actual set number tokens to english. But when you use Zend_Locale_Format you rely to the last set default locale which can differ from the one from setlocale.

I would ask you to fix the used locale to english to prevent this problem.

Also you should create a new issue to allow the usage of ANY locale which would allow the user to check for inputs of foreign locales by will. This would allow the same benefit as already available in Zend_Validate_Date.

Thomas,

I've taken your suggestions into account, could you verify (V4).

This issue also affect Zend_Validate_Float. If you set another locale (with setlocale()) the validator will fail, because PHP function floatval() return a value with the correct (for the locale) decimal separator, but Zend_Validate_Float replace the separator with a dot '.'

It's possible to fix Zend_Validate_Float to take in account the current locale?

Here is the code:


setlocale('it_IT.UTF-8');
$number = 123.15;
$float = new Zend_Validate_Float();
if ($float->isValid($number)) {
    echo $number . " is a valid float.";
} else {
    echo $number . " is NOT a valid float.";
}

This output, ever, "is NOT a valid float"... and even with:


$number = floatval(123.15);
// or
$number = floatval(123,15);

Andries, what is the status of this issue? Has it already been committed? Are you just waiting for Thomas' feedback?

New feature implemented with r13375