Try this:
>> const x = 288230376151711740;
>> x == x + 1
true
Or this: >> 2\*1024
Infinity
JS doesn't even have integers. It only has floats. JS is by far the worst language I know of when it comes to integer support.If you want a better example of arbitrary precision integers, try Python, for example.
I also worked on a project once where unique IDs of objects could get quite large (because they were random u64 integers). Those IDs were serialized and sent to a browser. Sometimes two objects were viewed as "the same" in the browser application because their IDs were truncated by the floating point precision issue.
Math.pow(2, 53) == Math.pow(2, 53) + 1
This is a bit clearer I think. The addition just barely overflows the 53 mantissa bits of the IEEE 754 double precision floating point number.By the way, JS has BigInts these days, which are supported by all major browsers: https://caniuse.com/bigint
>> const x = 288230376151711740n;
>> x == x + 1n
false 2**53 == 2**53+1
^^ even more clear.That's why Number.isSafeInteger(a) exists.
Integers up to +/- 9007199254740991 (Number.MAX_SAFE_INTEGER) are fine.
Although, C does have an equivalent to that: the GNU MP library (and probably others as well).
I for one am tired of the chicken & egg issue of "CPUs don't support efficient overflow checking because nobody uses it, so it's slow" and "Overflow checking is slow because the CPU doesn't support it, so nobody uses it". For all the other good security work done in both software and hardware, much for things far more complex than this, this seems like an absolutely batshit insane oversight considering the cost/benefits for fixing this.
Would it be possible to just silently replace with arbitrary sized integer and not break any code like safeintadd?
Null pointers are also handled by the kernel, not the CPU. Its called a segmentation fault because you are trying to access a memory segment that the OS doesn't want you to.
A NULL pointer in most (but not all) C implementations is address 0. Normally this address is not in a valid (mapped) page.
Any access to a virtual page that's not mapped by the HW page tables results in a page-fault exception. e.g. on x86, #PF.
This invokes the OS's page-fault exception handler to resolve the situation.
You may not be able to turn enforcement on for all code immediately. There's even the rare bits of code that depend on current overflow behavior. (Due to our human brains and the fact that we can easily name these bits of code, making the cognitively available, people often grotesquely overestimate the amount of code that operates this way. I'm sure it's only a matter of how many zeros belong in the 0.001%.) But we need this support to be available for code to be turn on easily and cheaply.
But what really boggles my mind, again given all the security work we've done, is that the reaction to this remains a combination of silence and "we can't do that!", when it seems to me the reaction ought to be "well duh jerf we all know that already." I don't get this. I don't get this attitude at all. This is a huge source of errors, a good fraction of which are security bugs, and nobody seems to care. Incomprehensible. This is, arguably, the number one thing that could be getting changed right now to fix security issues, and I just get slack-jawed "whaaaa?" in response to the idea.
One hundred plus one hundred is not negative fifty six! Here we are trying to hold together megabytes upon megabytes of security-critical code in a world where 100 + 100 = -56. Is it any wonder that writing any sort of code to maintain security invariants is tough in an environment where 100 + 100 = -56?
The x86 assembly uses fixed width immediates. CPU registers are a fixed width. For any code to compile and run, it needs to make decisions about how large stack frames need to be, and how much heap memory to allocate.
This was the parent's point about abstractions. You can make a library that pretends to be a variable sized integer, but to implement such a library you need to make a decision about how much space to allocate and the width of variables in order to compile. There is no getting away from how the hardware works.
These can be implemented in any higher level language or within C without using fixed width numerals if correct abstractions were available. Only device control parts should use fixed with numerals in my opinion.
I thought js "integers" are just floating point numbers?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
A newly designed OS kernel could perhaps take on this kind of feature. This would be the kind of OS that could be formally verified and would be willing to pay that runtime cost for arbitrary precision.
typedef struct { /* TODO */ } arb_int;
arb_int *new_arb_int(void);
void delete_arb_int(arb_int *);
arb_int *arb_int_add(arb_int *, arb_int *);
arb_int *arb_int_sub(arb_int *, arb_int *);
arb_int *arb_int_mul(arb_int *, arb_int *);
arb_int *arb_int_div(arb_int *, arb_int *);
bool arb_int_gt(arb_int *, arb_int *);
bool arb_int_lt(arb_int *, arb_int *);
bool arb_int_gte(arb_int *, arb_int *);
bool arb_int_lte(arb_int *, arb_int *);
bool arb_int_eq(arb_int *, arb_int *);