We recently discovered that text2num() will happily convert the text entities "nan", "inf" and "-inf" to their corresponding floating point values. This leaves certain code open to fun exploits, as the normal practice to validate numeric input is to do "isnum(x) && !(x <= 0)" or whatever have you. The problem is that isnum(text2num("nan")) will return true, and if your numeric validation is done in a negating fashion, then this will happily pass nan, as every greater-than or less-than comparison against nan will return false.
The immediate workaround for this is to implement a isnan macro as follows:
"#define isnan(x) ( isnum((x)) && ((x) != (x)) )"
But this does raise the point that, despite having the floating point special values around (nan, inf, -inf), DM has no tools to actually identify these values. Which is mildly curious and leaves us with a bit of a hole in how we validate user input.
So, at minimum, it might be worth adding some form of procs to identify these special values. To be clear, I have in mind isinf, isnan, and also isfinite. It might also be swell if all of these returned false in cases where "isnum(x) != true", this way, 90% of isnum(x) validation could just be replaced with isfinite(x), which only really leaves you with sub- and supernormal numbers to contend with, but range checks shooouuuld be valid against those.
ID:2596058
Jul 30 2020, 1:27 am
|
|||||||
| |||||||
Jul 31 2020, 10:54 am
|
|
I just don't really get why isnum(NaN) is true.
|
In response to Zewaka
|
|
Zewaka wrote:
I just don't really get why isnum(NaN) is true. "NaN" is a special value (or values) of the IEEE 754 floating-point type which indicates some type of computation failure, or an undefined or unrepresentable quantity. It's "a number" because it's a possible value of the numeric data types float or double (as C calls them). |
You can also check for infinity, negative infinity, and indeterminate.
proc |
Hiead, only way to check for indeterminate, is to do as described in the original post, because 1.#IND == 1.#IND is false.
|
In response to StyleMistake
|
|
StyleMistake wrote:
Hiead, only way to check for indeterminate, is to do as described in the original post, because 1.#IND == 1.#IND is false. You're confusing indeterminate with NaN.
|
1.#IND == 0 also returns true though, so you probably don't want to check for that one.
|
In response to Exxion
|
|
Exxion wrote:
1.#IND == 0 also returns true though, so you probably don't want to check for that one. Oof. You're right. I guess it should be removed since 1.#IND is treated as 0 everywhere from num2text to actual calculations. mob/verb/Huh() |
In response to Hiead
|
|
Hiead wrote:
StyleMistake wrote: Indeterminate is NaN, it's just that compiler statically reduces all 1.#IND to null (or zero). You can get `1.#IND` value by evaluating `0 / 1.#INF` |