blob: 8b73d9e65678cb7c2a06422b804695bf78824e00 [file] [log] [blame] [view]
Chris Palmereff252d62017-11-07 22:34:411# Integer Semantics, Unsafety, And You
2
3[TOC]
4
5These handy tips apply in any memory management situation and in any kind of IPC
6situation (classic Chromium IPCMojo, Windows/POSIX IPC, Mach IPC, files,
7sockets, parsing binary formats, ...).
8
9Basically, don't believe the lie that 'computers are good at arithmetic'. In
10general, unless you explicitly check an arithmetic operation, it's safest to
11assume the operation went wrong. The least painful way to systematically check
12arithmetic is Chromium's base/numerics templates and helper functions.
13
14## Be Aware Of The Subtleties Of Integer Types
15
16First [read about the scary security implications of integer arithmetic in
17C/C++](http://en.wikipedia.org/wiki/Integer_overflow). Adhere to these best
18practices:
19
20* Use the [integer templates and cast templates in
Chris Palmer7c2114152017-11-07 22:39:5221base/numerics](../../base/numerics/README.md) to avoid overflows, **especially when
Chris Palmereff252d62017-11-07 22:34:4122calculating the size or offset of memory allocations**.
23* Use unsigned types for values that shouldn't be negative or where defined
Chris Palmer3ae82b42019-08-05 18:09:5424overflow behavior is required. (Overflow is undefined behavior for signed
25types!)
26* Across any process boundary, use explicitly sized integer types, such as
27`int32_t`, `int64_t`, or `uint32_t`, since caller and callee could potentially
28use different interpretations of implicitly-sized types like `int` or `long`.
29(For example, a 64-bit browser process and a 32-bit plug-in process might
30interpret `long` differently.)
Chris Palmereff252d62017-11-07 22:34:4131
32## Be Aware Of The Subtleties Of Integer Types Across Languages
33
34### Java
35
36When writing code for Chromium on Android, you will often need to marshall
37arrays, and their sizes and indices, across the language barrier (and possibly
38also across the IPC barrier). The trouble here is that the Java integer types
39are well-defined, but the C++ integer types are whimsical. A Java `int` is a
40signed 32-bit integer with well-defined overflow semantics, and a Java `long` is
41a signed 64-bit integer with well-defined overflow semantics. in C++, only the
42explicitly-sized types (e.g. `int32_t`) have guaranteed exact sizes, and only
43unsigned integers (of any size) have defined overflow semantics.
44
45Essentially, Java integers **actually are** what people often (incorrectly)
46**assume** C++ integers are. Furthermore, Java `Array`s are indexed with Java
47`int`s, whereas C++ arrays are indexed with `size_t` (often implicitly cast, of
48course). Note that this also implies a 2^31 limit on the number of elements in
49an array that is coming from or going to Java. That Should Be Enough For
50Anybody, but it's good to keep in mind.
51
52You need to make sure that every integer value survives its journey across
53languages intact. That generally means explicit casts with range checks; the
Chris Palmer3ae82b42019-08-05 18:09:5454easiest way to do this is with the `base::checked_cast` or (much less likely)
Chris Palmereff252d62017-11-07 22:34:4155`base::saturated_cast` templates in base/numerics. Depending on how the integer
56object is going to be used, and in which direction the value is flowing, it may
57make sense to cast the value to `jint` (an ID or regular integer), `jlong` (a
58regular long integer), `size_t` (a size or index), or one of the other more
Chris Palmer3ae82b42019-08-05 18:09:5459exotic C/C++ integer types like `off_t`.
Chris Palmereff252d62017-11-07 22:34:4160
61### JavaScript And JSON
62
63[Here is some good reading on integers in
64JavaScript](http://2ality.com/2014/02/javascript-integers.html). TL;DR:
65
66* Normal JavaScript `Number`s have a 'safe' integer range of 53 bits (signed).
67See `Number.isSafeInteger`, `Number.MIN_SAFE_INTEGER`, and
68`Number.MAX_SAFE_INTEGER`.
69* Array indices are unsigned 32-bit values.
70* Character codes (`fromCharCode`, `charCodeAt`) are unsigned 16-bit values.