8000 Merge pull request #1520 from tannewt/check_seq_multiply_for_overflow · adafruit/circuitpython@041a84e · GitHub
[go: up one dir, main page]

Skip to content

Commit 041a84e

Browse files
authored
Merge pull request #1520 from tannewt/check_seq_multiply_for_overflow
Check sequence multiply for length overflow
2 parents 9bcc38e + 844c201 commit 041a84e

File tree

6 files changed

+18
-5
lines changed

6 files changed

+18
-5
lines changed

ports/atmel-samd/mpconfigport.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#define MICROPY_PY_DESCRIPTORS (1)
5555
#define MICROPY_PY_MATH (0)
5656
#define MICROPY_PY_CMATH (0)
57+
#define MICROPY_PY_MICROPYTHON_MEM_INFO (0)
5758
#define MICROPY_PY_URANDOM (0)
5859
#define MICROPY_PY_URANDOM_EXTRA_FUNCS (0)
5960
#define MICROPY_PY_STRUCT (0)
@@ -256,7 +257,6 @@ extern const struct _mp_obj_module_t pixelbuf_module;
256257
#define MICROPY_PY_UERRNO (1)
257258
#define MICROPY_PY_UERRNO_ERRORCODE (0)
258259
#define MICROPY_PY_URE (1)
259-
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
260260
#ifndef MICROPY_PY_FRAMEBUF
261261
#define MICROPY_PY_FRAMEBUF (0)
262262
#endif
@@ -342,7 +342,6 @@ extern const struct _mp_obj_module_t pixelbuf_module;
342342

343343
#else
344344
#define MICROPY_PY_BUILTINS_REVERSED (0)
345-
#define MICROPY_PY_MICROPYTHON_MEM_INFO (0)
346345
#define MICROPY_PY_FRAMEBUF (0)
347346
#ifndef EXTRA_BUILTIN_MODULES
348347
#define EXTRA_BUILTIN_MODULES

py/obj.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,8 @@ typedef struct {
844844
mp_int_t step;
845845
} mp_bound_slice_t;
846846

847+
// Compute the new length of a sequence and ensure an exception is thrown on overflow.
848+
size_t mp_seq_multiply_len(size_t item_sz, size_t len);
847849
void mp_seq_multiply(const void *items, size_t item_sz, size_t len, size_t times, void *dest);
848850
#if MICROPY_PY_BUILTINS_SLICE
849851
bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice_t *indexes);

py/objlist.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ STATIC mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
126126
if (n < 0) {
127127
n = 0;
128128
}
129-
mp_obj_list_t *s = list_new(o->len * n);
129+
size_t new_len = mp_seq_multiply_len(o->len, n);
130+
mp_obj_list_t *s = list_new(new_len);
130131
mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items);
131132
return MP_OBJ_FROM_PTR(s);
132133
}

py/objstr.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,9 @@ mp_obj_t mp_obj_str_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i
332332
return mp_const_empty_bytes;
333333
}
334334
}
335+
size_t new_len = mp_seq_multiply_len(lhs_len, n);
335336
vstr_t vstr;
336-
vstr_init_len(&vstr, lhs_len * n);
337+
vstr_init_len(&vstr, new_len);
337338
mp_seq_multiply(lhs_data, sizeof(*lhs_data), lhs_len, n, vstr.buf);
338339
return mp_obj_new_str_from_vstr(lhs_type, &vstr);
339340
}

py/objtuple.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ mp_obj_t mp_obj_tuple_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
160160
if (n <= 0) {
161161
return mp_const_empty_tuple;
162162
}
163-
mp_obj_tuple_t *s = MP_OBJ_TO_PTR(mp_obj_new_tuple(o->len * n, NULL));
163+
size_t new_len = mp_seq_multiply_len(o->len, n);
164+
mp_obj_tuple_t *s = MP_OBJ_TO_PTR(mp_obj_new_tuple(new_len, NULL));
164165
mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items);
165166
return MP_OBJ_FROM_PTR(s);
166167
}

py/sequence.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@
3434

3535
#define SWAP(type, var1, var2) { type t = var2; var2 = var1; var1 = t; }
3636

37+
// Detect when a multiply causes an overflow.
38+
size_t mp_seq_multiply_len(size_t item_sz, size_t len) {
39+
size_t new_len;
40+
if (__builtin_mul_overflow(item_sz, len, &new_len)) {
41+
mp_raise_msg(&mp_type_OverflowError, translate("small int overflow"));
42+
}
43+
return new_len;
44+
}
45+
3746
// Implements backend of sequence * integer operation. Assumes elements are
3847
// memory-adjacent in sequence.
3948
void mp_seq_multiply(const void *items, size_t item_sz, size_t len, size_t times, void *dest) {

0 commit comments

Comments
 (0)
0