You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
frombytes() and in-place ImageCms transforms write into read-only image memory #10235
The same as with paste(), putpixel(), putdata() or putalpha(): the image is copied first and the copy is changed, while the file and data stay as they were.
What actually happened?
The first two crash, with a bus error on macOS and a segmentation fault on Linux. The third prints b'\x01\x01\x01\x01': the bytes object was changed. An image from Image.fromarrow() behaves the same way, the new values end up in the Arrow array.
frombytes() gives self.im to the decoder without looking at readonly, and ImageCmsTransform.apply(im, imOut), which inPlace=True uses, writes into imOut the same way. The methods above call _ensure_mutable() first.
This fixes it for me, and the test suite still passes:
# Image.frombytes(), after the zero-size checkifself.im.readonly:
self._copy()
I did not use _ensure_mutable() in frombytes() because plugins call frombytes() from their own load(), while ImageFile.readonly is still 1. Every GbrImagePlugin and WalImageFile image would be copied once more, and a plugin that marks itself loaded only after frombytes() (pillow-heif 1.8.1, for example) ends in RecursionError.
Thanks for asking. I had already prepared a PR as well, #10264. frombytes() is the same in both. In apply(), #10256 calls _ensure_mutable(), which copies every image file that isn't loaded yet: an in-place transform of a freshly opened 12 MP JPEG peaks at 114 MiB instead of 68 MiB. #10264 copies only when the memory itself is read-only, and its tests cover memory-mapped files, which is where the crash happens.
That said, I don't mind which one is merged. If you prefer #10256, for example for consistency with paste(), feel free to merge it and close mine.
Activity
radarhere commentedon Oct 18, 2026
Did you want to create a PR? Seems like you're most of the way there.
radarhere commentedon Oct 20, 2026
Let us know what you think of #10256.
If you are in favour, I'll review it.
If you aren't, I'll close as an AI that doesn't understand that we were waiting for your PR.
bigcat88 commentedon Oct 20, 2026
Thanks for asking. I had already prepared a PR as well, #10264.
frombytes()is the same in both. Inapply(), #10256 calls_ensure_mutable(), which copies every image file that isn't loaded yet: an in-place transform of a freshly opened 12 MP JPEG peaks at 114 MiB instead of 68 MiB. #10264 copies only when the memory itself is read-only, and its tests cover memory-mapped files, which is where the crash happens.That said, I don't mind which one is merged. If you prefer #10256, for example for consistency with
paste(), feel free to merge it and close mine.