> On Mar 3, 2021, at 08:04, Nikita Popov <nikita....@gmail.com> wrote:
> 
> Hi internals,
> 
> PHP's == comparison semantics for strings have a peculiar edge-case, where
> comparisons of the form "0e123" == "0e456" return true, because they are
> interpreted as floating point zero numbers. This is problematic, because
> strings of that form are usually not numbers, but hex-encoded hashes or
> similar.
> 
> I'm wondering if it may make sense to special-case the comparison semantics
> to not consider strings of the form "0e[DIGITS]" equal, unless they are
> exactly equal (i.e., fall back to lexicographical if both sides of the
> comparison are zero exponentials).
> 
> Here's a possible implementation: https://github.com/php/php-src/pull/6749
> 
> Of course, the usual rule that you should always use === still holds, but
> this at least eliminates the most dangerous edge case.


I encountered a similar situation a few years back.

We were testing whether a value was numeric and, if so, adding 0 to it in order 
to convert it to an appropriate number type. The code looked something like 
this:

    if (is_numeric($value)) {
        $value += 0;
    }

We chose not to do an explicit cast because the string could represent a float 
or an int, so we wanted the type coercion to do its magic.

We did this before calling `json_encode()` on the data structure, so that 
string numbers coming out of a database would be converted to numbers in JSON. 
For some reason, `JSON_NUMERIC_CHECK` wasn’t giving us what we wanted, but I 
can’t recall the issue we were having.

Anyway, we ran into some fun issues with hashes that looked like this:

    '131124826899e4096767887418316466'

That value should have remained a string in the JSON output, but `is_numeric()` 
returns `true` for it, so it became `INF`.

We were able to come up with a work-around, but it’s not foolproof.

Cheers,
Ben

Attachment: signature.asc
Description: Message signed with OpenPGP

Reply via email to