Skip to content

Commit e152198

Browse files
jeplerdpgeorge
authored andcommitted
extmod/modframebuf: Fix crash in scroll() for large inputs.
If mp_int_t is wider than int, then the tests such as `xend < 0` can fail even when the amount of scrolling requested is out of range. This resulted in a segmentation fault when attempting an out-of-bounds access to the framebuffer. Signed-off-by: Jeff Epler <jepler@gmail.com>
1 parent 2bba507 commit e152198

File tree

2 files changed

+20
-14
lines changed

2 files changed

+20
-14
lines changed

extmod/modframebuf.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -787,39 +787,40 @@ static mp_obj_t framebuf_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t ys
787787
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(self_in);
788788
mp_int_t xstep = mp_obj_get_int(xstep_in);
789789
mp_int_t ystep = mp_obj_get_int(ystep_in);
790-
int sx, y, xend, yend, dx, dy;
790+
unsigned int sx, y, xend, yend;
791+
int dx, dy;
791792
if (xstep < 0) {
792-
sx = 0;
793-
xend = self->width + xstep;
794-
if (xend <= 0) {
793+
if (-xstep >= self->width) {
795794
return mp_const_none;
796795
}
796+
sx = 0;
797+
xend = self->width + (int)xstep;
797798
dx = 1;
798799
} else {
799-
sx = self->width - 1;
800-
xend = xstep - 1;
801-
if (xend >= sx) {
800+
if (xstep >= self->width) {
802801
return mp_const_none;
803802
}
803+
sx = self->width - 1;
804+
xend = (int)xstep - 1;
804805
dx = -1;
805806
}
806807
if (ystep < 0) {
807-
y = 0;
808-
yend = self->height + ystep;
809-
if (yend <= 0) {
808+
if (-ystep >= self->height) {
810809
return mp_const_none;
811810
}
811+
y = 0;
812+
yend = self->height + (int)ystep;
812813
dy = 1;
813814
} else {
814-
y = self->height - 1;
815-
yend = ystep - 1;
816-
if (yend >= y) {
815+
if (ystep >= self->height) {
817816
return mp_const_none;
818817
}
818+
y = self->height - 1;
819+
yend = (int)ystep - 1;
819820
dy = -1;
820821
}
821822
for (; y != yend; y += dy) {
822-
for (int x = sx; x != xend; x += dx) {
823+
for (unsigned x = sx; x != xend; x += dx) {
823824
setpixel(self, x, y, getpixel(self, x - xstep, y - ystep));
824825
}
825826
}

tests/extmod/framebuf_scroll.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,9 @@ def prepare_buffer():
4242
fbuf.scroll(15, 7)
4343
fbuf.scroll(10, -1)
4444
fbuf.scroll(1, -10)
45+
try:
46+
fbuf.scroll(1000000000000, -1)
47+
except OverflowError:
48+
# When mp_int_t is 32 bits, this throws OverflowError.
49+
pass
4550
printbuf()

0 commit comments

Comments
 (0)