Skip to content

Memory allocation error when using sixel_encoder_encode_bytes() #224

@xyzzy42

Description

@xyzzy42

Combining sixel_encoder_encode_bytes() with any option that requires an image modification, e.g. libsixel image scaling, results in a memory allocation crash.

The problem is this:

  1. The external buffer supplied to sixel_encoder_encode_bytes() is placed into a sixel_frame_t.
  2. Eventually sixel_frame_convert_to_rgb888() or sixel_frame_resize() is called to modify the frame.
  3. This will allocate a new pixel buffer with sixel_allocator_malloc().
  4. The old pixel buffer in the sixel_frame_t is freed with sixel_allocator_free().
  5. The existing pixel buffer in the sixel_frame_t is replaced with the newly allocated buffer.

If the original pixel buffer supplied to sixel_encoder_encode_bytes() was not allocated by sixel_allocator_malloc(), then step 4 above will crash or corrupt the heap.

The example examples/opengl/main.c suffers from this problem. The buffer is from opengl, not allocated with sixel_allocator_malloc(), and will crash with image scaling or anything else that requires normalizing the image is done. The libpixel Python bindings also have this problem, as the image data is a Python object.

While this could be fixed by requiring the data passed to sixel_encoder_encode_bytes() to be a buffer allocated with sixel_allocator_malloc(), this is not very convenient for library users. The image will already be in some other kind of buffer, e.g. OpenGL or a Python PIL image, and the user would need to allocate another image buffer and copy the image into it.

Another solution, more efficient, would be to mark with a flag in sixel_frame_t whether the pixel data is "internally managed" or not. Internally managed data would be freed when the pixel data in the frame is replaced. External pixel data would not be freed. This would also fix existing users of sixel_encoder_encode_bytes() without needing a change to the API.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions