Skip to content

bitmapfilter, aesio, analogbufio, floppyio, memorymonitor, busio: dec… - #11385

Merged
tannewt merged 3 commits into
adafruit:mainfrom
peterbay:declared-type-and-use-disagree
Sep 15, 2026
Merged

tannewt merged 3 commits into
adafruit:mainfrom
peterbay:declared-type-and-use-disagree

Conversation

@peterbay

Copy link
Copy Markdown

Code written by Claude Code, guided and corrected by @peterbay.

The problem

Six places where the declared type and the use disagree: two arguments read out of the wrong member of mp_arg_val_t, two buffers asked for read access and then written to, a memset of a local instead of the caller's array, and an index used one bucket past the end.

The changes

  • bitmapfilter.morph read offset through .u_bool. It is MP_ARG_INT in the argument table, so only its low byte reached the filter: offset=256 behaved as offset=0 and offset=257 as offset=1.

  • aesio's counter was read through .u_int. It is declared MP_ARG_OBJ with a MP_OBJ_NULL default, so the object's own address went in as the counter and anything at all was accepted — a string, None. Read through mp_obj_get_int_truncated now, which is also what rejects those. (The value is stored and never read afterwards, so nothing about the cipher changes; what changes is that a non-integer is refused rather than silently turned into a pointer.)

  • analogbufio.readinto asked for a read-only buffer and then filled it, so a bytes or a read-only memoryview was accepted and written to anyway.

  • floppyio.mfm_readinto did the same with its validity buffer, and clear_validity cleared a local array rather than the caller's, so it did nothing at all.

  • memorymonitor's bucket index ran past its array. The count runs to the width of a size_t but there are only ALLOCATION_SIZE_BUCKETS buckets, so an allocation of 65536 blocks or more incremented past the end, into the fields that follow it in the object.

  • busio.I2C.writeto_then_readfrom named the wrong buffer in its error. It validates in_length and passed MP_QSTR_out_buffer, so a short input buffer produced a message pointing at the output one.

Testing

Seeed XIAO nRF52840 Sense, on two builds differing only by these changes.

before after
morph(..., threshold=True, offset=256) 96 pixels set, the same as offset=0 256, the same as any large offset
morph(..., threshold=True, offset=257) 163, the same as offset=1 256
morph(..., threshold=True, offset=255) 256, unchanged either way 256
AES(key, MODE_CTR, iv, counter="nonsense") accepted TypeError: can't convert str to int
AES(key, MODE_CTR, iv, counter=None) accepted TypeError: can't convert NoneType to int
AES(key, MODE_CTR, iv, counter=7) accepted, unchanged either way accepted

The morph rows are the truncation in full: below 256 the low byte and the value are the same number, so the defect only shows once the offset passes it.

Four of the six are not in that table, for reasons that have nothing to do with the fixes. analogbufio and floppyio have no HAL on this port and cannot be built here at all. busio.I2C needs a bus with pull-ups, which this board has none free for. And memorymonitor does not compile anywhere, which is worth saying on its own.

A note on memorymonitor

Nothing enables CIRCUITPY_MEMORYMONITOR — it is ?= 0 and no port or board overrides it — and the module has not been built for long enough to stop compiling. On main today it fails with:

  • AllocationSize.c: m_new_obj is called with the object's type as a second argument. That form went away when the object representation changed; mp_obj_malloc is what does both jobs now.
  • __init__.c: mp_obj_new_exception_msg_vlist no longer exists.
  • AllocationAlarm.c fails too.

I have not touched any of that here — reviving the module is a separate piece of work, and guessing at it inside a bug-fix patch seemed worse than reporting it. The bucket fix is included because it is correct and because whoever does revive it should not have to find that one as well.

No new translatable strings.

…lared type and use disagree

bitmapfilter.morph read offset through .u_bool although it is MP_ARG_INT, so
only its low byte reached the filter and offset=256 behaved as offset=0.

aesio read counter through .u_int although it is MP_ARG_OBJ, so the object's
own address went in and a string or None was accepted without complaint.

analogbufio.readinto and floppyio.mfm_readinto both asked for read-only
buffers and then wrote to them, so a bytes was accepted and filled anyway.
floppyio's clear_validity also cleared a local array rather than the caller's.

memorymonitor's bucket index runs to the width of a size_t but the array has
ALLOCATION_SIZE_BUCKETS entries, so a large enough allocation incremented past
the end of it.

busio.I2C.writeto_then_readfrom validates in_length and named out_buffer in
the error it raises.
@peterbay

Copy link
Copy Markdown
Author

Testing and diagnostic script.
declared_type_and_use_disagree.py

@tannewt tannewt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@tannewt
tannewt added this pull request to the merge queue Sep 14, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 14, 2026
@tannewt
tannewt added this pull request to the merge queue Sep 15, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Sep 15, 2026
@dhalbert
dhalbert enabled auto-merge September 15, 2026 15:43
@dhalbert
dhalbert added this pull request to the merge queue Sep 15, 2026
@tannewt
tannewt removed this pull request from the merge queue due to the queue being cleared Sep 15, 2026
@tannewt
tannewt merged commit d5d940d into adafruit:main Sep 15, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants