framebuf: crash with incorrect usage (native subclassing?)
Port, board and/or hardware
unix port, coverage build, x86_64 linux
MicroPython version
MicroPython v1.26.0-preview.524.g255d74b5a8 on 2025-08-06; linux [GCC 12.2.0] version
Reproduction
Run the following Python code:
import framebuf
class FB(framebuffer.FrameBuffer): pass
FB.pixel(0,0,0)
Expected behaviour
A TypeError or other appropriate error is raised
Observed behaviour
A segmentation fault.
MicroPython v1.26.0-preview.524.g255d74b5a8 on 2025-08-06; linux [GCC 12.2.0] version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>> import framebuf
>>> class FB(framebuf.FrameBuffer): pass
...
>>> FB.pixel(0,0,0)
Program received signal SIGSEGV, Segmentation fault.
0x0000555555634845 in framebuf_pixel (n_args=3, args_in=0x7fffffffda30)
at ../../extmod/modframebuf.c:376
376 if (0 <= x && x < self->width && 0 <= y && y < self->height) {
(gdb) where
#0 0x0000555555634845 in framebuf_pixel (n_args=3, args_in=0x7fffffffda30)
at ../../extmod/modframebuf.c:376
#1 0x00005555555fdf8d in fun_builtin_var_call (
self_in=0x555555711250 <framebuf_pixel_obj>, n_args=3, n_kw=0, args=0x7fffffffda30)
at ../../py/objfun.c:123
Additional Information
This was found by fuzzing.
Incidentally, when there is NOT a subclass involved, the error is detected:
>>> framebuf.FrameBuffer.pixel(0,0,0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: argument should be a 'FrameBuffer' not a 'int'
Code of Conduct
Yes, I agree
FrameBuffer Initialisation fails with ValueError on `memoryview`
Port, board and/or hardware
RP2; Unix (but I believe this affects any board with framebuffer support)
MicroPython version
MicroPython v1.23.0 on 2024-06-02; Raspberry Pi Pico with RP2040
Reproduction
Run the code below in the REPL, or run a script with the same code in it:
import array
import framebuf
buf = array.array('H', bytearray(2*8*8))
sub_buf = memoryview(buf)[4:]
fbuf = framebuf.FrameBuffer(sub_buf, 4, 8, framebuf.RGB565, 8)
Expected behaviour
I expected the code to work without error.
Observed behaviour
I get an unexpected ValueError with no explanation:
>>> import array
>>> import framebuf
>>> buf = array.array('H', bytearray(2*8*8))
>>> sub_buf = memoryview(buf)[4:]
>>> fbuf = framebuf.FrameBuffer(sub_buf, 4, 8, framebuf.RGB565, 8)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError:
Additional Information
The "what am I actually trying to do" here is to create a frame buffer on a subsection of another buffer using a memory view to avoid copying data, either:
- to clip out a sprite from a larger sprite-sheet buffer to display using
FrameBuffer.blit - to clip drawing to a sub-region of a larger image (for this you have to have a memory view into the same underlying buffer)
This is likely related to, but different from #15571, as that is an issue with bit-alignment. As with that issue, I think that the lines at fault are here: https://github.com/micropython/micropython/blob/17d82344581ad3a76033fae54c5d3304e17f185f/extmod/modframebuf.c#L317-L319
If you look at the underlying buffers, you have something like the following:
....xxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
where . are values in the underlying buffer that are skipped by the memoryview, x are values that should be visible in the framebuffer, and s are values which are skipped by the stride of 8.
It appears that what the FrameBuffer code is expecting is the following:
....xxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssss
even though the last 4 values are never written to.
Work-around
This can be worked around by allocating extra memory to the underlying buffer, although that's fiddly for the first use-case if the data is loaded from an existing sprite sheet buffer, eg. loaded from a file.
Code of Conduct
Yes, I agree