> 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
signature.asc
Description: Message signed with OpenPGP