From d17e0f73a57eb65c82eb942bf4b33e3c6d8335c3 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Mon, 2 Nov 2020 20:38:48 -0700 Subject: update examples to use precise integer types --- safety.rst | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'safety.rst') diff --git a/safety.rst b/safety.rst index 6a73b85..b3df7f4 100644 --- a/safety.rst +++ b/safety.rst @@ -15,29 +15,30 @@ Buffer overflow --------------- Crowbar addresses buffer overflow with bounds checking. -In C, the type ``char *`` can point to a single character, a null-terminated string of unknown length, a buffer of fixed size, or nothing at all. -In Crowbar, the type ``char *`` can only point to either a single character or nothing at all. -If a buffer is declared as ``char[50] name;`` then it has type ``char[50]``, and can be implicitly converted to ``(char[50])*``, a pointer-to-50-chars. +In C, the type ``uint8_t *`` can point to a single byte, a null-terminated string of unknown length, a buffer of fixed size, or nothing at all. +In Crowbar, the type ``uint8 *`` can only point to either a single byte or nothing at all. +If a buffer is declared as ``uint8[50] name;`` then it has type ``uint8[50]``, and can be implicitly converted to ``(uint8[50])*``, a pointer-to-50-bytes. If memory is dynamically allocated, it works as follows:: - void process(size_t bufferSize, char[bufferSize] buffer) { + void process(uintsize bufferSize, uint8[bufferSize] buffer) { // do some work with buffer, given that we know its size } - int main(int argc, (char[1024?])[argc] argv) { - size_t bufferSize = getBufferSize(); - (char[bufferSize])* buffer = malloc(bufferSize); + int8 main(uintsize argc, (uint8[1024?])[argc] argv) { + uintsize bufferSize = getBufferSize(); + (uint8[bufferSize])* buffer = malloc(bufferSize); process(bufferSize, buffer); free(buffer); } -Note that ``malloc`` as part of the Crowbar standard library has signature ``(void[size])* malloc(size_t size);`` and so no cast is needed above. +Note that ``malloc`` as part of the Crowbar standard library has signature ``(void[size])* malloc(uintsize size);`` and so no cast is needed above. In C, ``buffer`` in ``main`` would have type pointer-to-VLA-of-char, but ``buffer`` in ``process`` would have type VLA-of-char, and this conversion would emit a compiler warning. However, in Crowbar, a ``(T[N])*`` is always implicitly convertible to ``T[N]``, so no warning exists. Note as well that the type of ``argv`` is complicated. This is because the elements of ``argv`` have unconstrained size. -TODO figure out if that's the right way to handle that + +.. todo:: figure out if that's the right way to handle that Buffer over-read ---------------- -- cgit v1.2.3