Re: Don't compare zero exponentials in strings as equal

From: Date: Wed, 03 Mar 2021 15:36:49 +0000
Subject: Re: Don't compare zero exponentials in strings as equal
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-113350@lists.php.net to get a copy of this message
> On Mar 3, 2021, at 08:04, Nikita Popov <nikita.ppv@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: [application/pgp-signature] Message signed with OpenPGP signature.asc
« previous php.internals (#113350) next »