PHP float bug: PHP is numerical dependent

I just read an interesting article about php hanging on some floating point numbers, see "Register" and Exploring Binary Files .

I never use float, I use number_format() to clear input and display, for example, prices.

Also, as far as I know, all the input from the forms, for example, are strings until I tell them otherwise, so I assume that this problem does not affect me.

Am I correct or do I need to check, for example, Wordpress and Squirrelmail installations on my server to see that they are applying something for swimming? Or better, grep all php files on my servers for float ?

+4
source share
8 answers

Ways to mitigate the problem:

  • Use a modern processor. Most modern 64-bit processors will be protected (in fact, I had problems finding a host that can play it, since they usually use more modern equipment). It seems that Amazon VM is also insured.
  • Update your version of PHP - 5.3.5 and 5.2.17 after its release (perhaps today), enable the fix.
  • Build with -ffloat-store in CFLAGS (slow down the code).
  • Manually apply patch to your code and rebuild PHP.

Looking for code with a float will probably not help, since zend_strtod used by the engine in many scripts for converting strings and numbers.

PS this btw code is the standard BSD code of the strtod library, not unique to PHP. So other projects using this code may also be affected.

+5
source

From hackernews :

This issue occurs due to IA-32 80-bit floating point arithmetic. simple fix: add the "-ffloat-store" flag to your CFLAGS.

The problematic function zend_strtod seems to analyze the mantissa (2.225 ... 011 parts) and the exponent (-308 parts) separately, c> buy the approximation m * 10 ^ e and consistently improve this approximation until the error is less than 0, 5 wt. The problem is that this number causes an infinite loop (i.e. iteration does not improve the error at all) in an 80-bit FP, but not in a 64-bit FP. Since x86-64 usually uses the SSE2 instruction set (with 64-bit FP) instead of the obsolete x87 it does not have this problem.

+4
source

As a quick workaround, you can scan the input arrays:

 foreach(array("_GET","_POST","_REQUEST","_COOKIES") as $G) { if (in_array('2.2250738585072011e-308', $$G)) { header("Status: 422 Unprocessable Entity"); exit; } } 

This is sufficient if you are not using subarrays in the input vars. It will work because it contains float as a string, input arrays contain strings, and in_array also works in the context of a string.

However, I did not consider whether there are other representations of this value. This is the only one that, as you know, still works, but maybe more. Thus, the update is more appropriate: |

+3
source

As marcog said it was an arithmetic floating point error with x87 math. If you want to know more about this, check out the GCC error, Link

+2
source

finding explicit float-casts will not help you - in php the variable is considered as what it is used for. small example:

 $mystring = "123.45"; //mystring is a string here $myvalue = $mystring * 4; // mystring is a float here // and there no explicit float-cast 

as you can see: updating / fixing your php installation is the only way to save a dead server.

EDIT: to your comment:

swimming really hard. even simple numbers, such as 0.7 or 0.8, cannot be stored exactly, and therefore it may happen that you, after some calculations, 0.899999999789 ... with even more shit, this is just a question time until you get the problem.

as an example (and if you are a Windows user):

  • open the calculator window
  • calculate sqare root of 4 (should be 2)
  • subtracting 2 from the result (should be 0, but ... woooow;))

this error is in the windows calculator since ... ever - and it shows that even large companies may not use float, but the calculator does not kill your system - if such an error can kill your system (for example, this is php-bug) You will have to update / fix, do not show.

+1
source

Finding a float is not enough, as you are looking for code that explicitly passes the value of the float variable, but you will not find instances in which casting is implicit.

 $d = '2.2250738585072011e-308'; $f = float($d); 

is explicit casting, but what about the code:

 $d = '2.2250738585072011e-308'; $f = $d + 0.1; 

or

 $d = '2.2250738585072011e-308'; if ($d == 0.5) { 

I believe this error has also been fixed in the latest PHP code, although packages like xampp are still affected.

+1
source

If you cannot fix your php installation, you can use the following: Any problems with the following work for php error # 53632

This is just a temporary workaround until you can fix your php installation

0
source

To catch all possible notations of a number, you need to use the substring search.

See http://www.aircraft24.com/en/info/php-float-dos-quickfix.htm for our latest workaround.

0
source

Source: https://habr.com/ru/post/1334365/


All Articles