py/objstringio: Catch mp_uint_t overflow of stream position in write().

This commit is contained in:
Tom Collins 2017-05-25 13:41:59 -07:00 committed by Damien George
parent ed6d2547df
commit e26fb3ad73
1 changed files with 11 additions and 6 deletions

View File

@ -72,22 +72,27 @@ STATIC mp_uint_t stringio_write(mp_obj_t o_in, const void *buf, mp_uint_t size,
(void)errcode;
mp_obj_stringio_t *o = MP_OBJ_TO_PTR(o_in);
check_stringio_is_open(o);
mp_int_t remaining = o->vstr->alloc - o->pos;
mp_uint_t new_pos = o->pos + size;
if (new_pos < size) {
// Writing <size> bytes will overflow o->pos beyond limit of mp_uint_t.
*errcode = MP_EFBIG;
return MP_STREAM_ERROR;
}
mp_uint_t org_len = o->vstr->len;
if ((mp_int_t)size > remaining) {
if (new_pos > o->vstr->alloc) {
// Take all what's already allocated...
o->vstr->len = o->vstr->alloc;
// ... and add more
vstr_add_len(o->vstr, size - remaining);
vstr_add_len(o->vstr, new_pos - o->vstr->alloc);
}
// If there was a seek past EOF, clear the hole
if (o->pos > org_len) {
memset(o->vstr->buf + org_len, 0, o->pos - org_len);
}
memcpy(o->vstr->buf + o->pos, buf, size);
o->pos += size;
if (o->pos > o->vstr->len) {
o->vstr->len = o->pos;
o->pos = new_pos;
if (new_pos > o->vstr->len) {
o->vstr->len = new_pos;
}
return size;
}