Chris Palmer | eff252d6 | 2017-11-07 22:34:41 | [diff] [blame] | 1 | # Integer Semantics, Unsafety, And You |
| 2 | |
| 3 | [TOC] |
| 4 | |
| 5 | These handy tips apply in any memory management situation and in any kind of IPC |
| 6 | situation (classic Chromium IPC, Mojo, Windows/POSIX IPC, Mach IPC, files, |
| 7 | sockets, parsing binary formats, ...). |
| 8 | |
| 9 | Basically, don't believe the lie that 'computers are good at arithmetic'. In |
| 10 | general, unless you explicitly check an arithmetic operation, it's safest to |
| 11 | assume the operation went wrong. The least painful way to systematically check |
| 12 | arithmetic is Chromium's base/numerics templates and helper functions. |
| 13 | |
| 14 | ## Be Aware Of The Subtleties Of Integer Types |
| 15 | |
| 16 | First [read about the scary security implications of integer arithmetic in |
| 17 | C/C++](http://en.wikipedia.org/wiki/Integer_overflow). Adhere to these best |
| 18 | practices: |
| 19 | |
| 20 | * Use the [integer templates and cast templates in |
Chris Palmer | 7c211415 | 2017-11-07 22:39:52 | [diff] [blame] | 21 | base/numerics](../../base/numerics/README.md) to avoid overflows, **especially when |
Chris Palmer | eff252d6 | 2017-11-07 22:34:41 | [diff] [blame] | 22 | calculating the size or offset of memory allocations**. |
| 23 | * Use unsigned types for values that shouldn't be negative or where defined |
Chris Palmer | 3ae82b4 | 2019-08-05 18:09:54 | [diff] [blame] | 24 | overflow behavior is required. (Overflow is undefined behavior for signed |
| 25 | types!) |
| 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 |
| 28 | use 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 |
| 30 | interpret `long` differently.) |
Chris Palmer | eff252d6 | 2017-11-07 22:34:41 | [diff] [blame] | 31 | |
| 32 | ## Be Aware Of The Subtleties Of Integer Types Across Languages |
| 33 | |
| 34 | ### Java |
| 35 | |
| 36 | When writing code for Chromium on Android, you will often need to marshall |
| 37 | arrays, and their sizes and indices, across the language barrier (and possibly |
| 38 | also across the IPC barrier). The trouble here is that the Java integer types |
| 39 | are well-defined, but the C++ integer types are whimsical. A Java `int` is a |
| 40 | signed 32-bit integer with well-defined overflow semantics, and a Java `long` is |
| 41 | a signed 64-bit integer with well-defined overflow semantics. in C++, only the |
| 42 | explicitly-sized types (e.g. `int32_t`) have guaranteed exact sizes, and only |
| 43 | unsigned integers (of any size) have defined overflow semantics. |
| 44 | |
| 45 | Essentially, 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 |
| 48 | course). Note that this also implies a 2^31 limit on the number of elements in |
| 49 | an array that is coming from or going to Java. That Should Be Enough For |
| 50 | Anybody, but it's good to keep in mind. |
| 51 | |
| 52 | You need to make sure that every integer value survives its journey across |
| 53 | languages intact. That generally means explicit casts with range checks; the |
Chris Palmer | 3ae82b4 | 2019-08-05 18:09:54 | [diff] [blame] | 54 | easiest way to do this is with the `base::checked_cast` or (much less likely) |
Chris Palmer | eff252d6 | 2017-11-07 22:34:41 | [diff] [blame] | 55 | `base::saturated_cast` templates in base/numerics. Depending on how the integer |
| 56 | object is going to be used, and in which direction the value is flowing, it may |
| 57 | make sense to cast the value to `jint` (an ID or regular integer), `jlong` (a |
| 58 | regular long integer), `size_t` (a size or index), or one of the other more |
Chris Palmer | 3ae82b4 | 2019-08-05 18:09:54 | [diff] [blame] | 59 | exotic C/C++ integer types like `off_t`. |
Chris Palmer | eff252d6 | 2017-11-07 22:34:41 | [diff] [blame] | 60 | |
| 61 | ### JavaScript And JSON |
| 62 | |
| 63 | [Here is some good reading on integers in |
| 64 | JavaScript](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). |
| 67 | See `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. |