From 939c0045dbf2694a12432ad861db166ecf483b67 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 20 Apr 2017 11:24:05 -0700 Subject: Switch to a shared piece of code to compute start and length of a buffer from start, end and length. The old code miscomputed length leading to writing and reading from memory past the end of the buffer. Consolidating the code should make it easier to get right everywhere. --- shared-bindings/busio/I2C.c | 35 +++++++++++------------------------ shared-bindings/busio/SPI.c | 33 +++++++++------------------------ 2 files changed, 20 insertions(+), 48 deletions(-) (limited to 'shared-bindings/busio') diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c index 7383cb104..b1794fdfb 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -30,6 +30,7 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/busio/I2C.h" +#include "lib/utils/buffer_helper.h" #include "lib/utils/context_manager_helpers.h" #include "py/runtime.h" //| .. currentmodule:: busio @@ -187,18 +188,11 @@ STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); - int32_t end = args[ARG_end].u_int; - if (end < 0) { - end += bufinfo.len; - } - uint32_t start = args[ARG_start].u_int; - uint32_t len = end - start; - if ((uint32_t) end < start) { - len = 0; - } else if (len > bufinfo.len) { - len = bufinfo.len; - } - uint8_t status = common_hal_busio_i2c_read(self, args[ARG_address].u_int, ((uint8_t*)bufinfo.buf) + start, len); + + int32_t start = args[ARG_start].u_int; + uint32_t length = bufinfo.len; + normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); + uint8_t status = common_hal_busio_i2c_read(self, args[ARG_address].u_int, ((uint8_t*)bufinfo.buf) + start, length); if (status != 0) { mp_raise_OSError(status); } @@ -241,21 +235,14 @@ STATIC mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_ma mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); - int32_t end = args[ARG_end].u_int; - if (end < 0) { - end += bufinfo.len; - } - uint32_t start = args[ARG_start].u_int; - uint32_t len = end - start; - if ((uint32_t) end < start) { - len = 0; - } else if (len > bufinfo.len) { - len = bufinfo.len; - } + + int32_t start = args[ARG_start].u_int; + uint32_t length = bufinfo.len; + normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); // do the transfer uint8_t status = common_hal_busio_i2c_write(self, args[ARG_address].u_int, - ((uint8_t*) bufinfo.buf) + start, len, args[ARG_stop].u_bool); + ((uint8_t*) bufinfo.buf) + start, length, args[ARG_stop].u_bool); if (status != 0) { mp_raise_OSError(status); } diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index d4d9ec345..0fb0c7ddf 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -32,6 +32,7 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/busio/SPI.h" +#include "lib/utils/buffer_helper.h" #include "lib/utils/context_manager_helpers.h" #include "py/mperrno.h" #include "py/nlr.h" @@ -217,19 +218,11 @@ STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_ mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); - int32_t end = args[ARG_end].u_int; - if (end < 0) { - end += bufinfo.len; - } - uint32_t start = args[ARG_start].u_int; - uint32_t len = end - start; - if ((uint32_t) end < start) { - len = 0; - } else if (len > bufinfo.len) { - len = bufinfo.len; - } + int32_t start = args[ARG_start].u_int; + uint32_t length = bufinfo.len; + normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); - bool ok = common_hal_busio_spi_write(self, ((uint8_t*)bufinfo.buf) + start, len); + bool ok = common_hal_busio_spi_write(self, ((uint8_t*)bufinfo.buf) + start, length); if (!ok) { mp_raise_OSError(MP_EIO); } @@ -262,19 +255,11 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); - int32_t end = args[ARG_end].u_int; - if (end < 0) { - end += bufinfo.len; - } - uint32_t start = args[ARG_start].u_int; - uint32_t len = end - start; - if ((uint32_t) end < start) { - len = 0; - } else if (len > bufinfo.len) { - len = bufinfo.len; - } + int32_t start = args[ARG_start].u_int; + uint32_t length = bufinfo.len; + normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); - bool ok = common_hal_busio_spi_read(self, ((uint8_t*)bufinfo.buf) + start, len, args[ARG_write_value].u_int); + bool ok = common_hal_busio_spi_read(self, ((uint8_t*)bufinfo.buf) + start, length, args[ARG_write_value].u_int); if (!ok) { mp_raise_OSError(MP_EIO); } -- cgit v1.2.3