Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugins (alphablend): Fix blending and associated crashes due to buffer overruns #383

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

kaixiong
Copy link
Member

The alphablend morph uses the blending routines visual_alpha_blend_nn() wrongly. It passes the pixel buffer size in bytes instead of pixel count for the size parameter. Since buffer size is always equal or greater than pixel count (bytes per pixel >= 1 and row padding >= 0), this causes buffer overruns.

@kaixiong kaixiong requested a review from hartwork January 21, 2025 17:35
@kaixiong kaixiong self-assigned this Jan 21, 2025
Copy link
Member

@hartwork hartwork left a comment

Choose a reason for hiding this comment

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

@kaixiong two small things:

uint8_t *dest_row_ptr = visual_video_get_pixels (dest);

uint8_t alpha = progress * 255;
BlendFunc blend_func = get_blend_func (depth);
Copy link
Member

Choose a reason for hiding this comment

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

get_blend_func can return NULL. If we keep allowing it to, we likely need a check for NULL somewhere around here?

Copy link
Member Author

Choose a reason for hiding this comment

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

The default case is unreachable and largely included to silence compiler warnings about enum values unaccounted for (e.g. VISUAL_VIDEO_DEPTH_NONE and VISUAL_DEPTH_NONE_ALL).

We don't have unreachable() in C99 or C11 so I returned a NULL instead. Would you prefer abort()?

Copy link
Member

@hartwork hartwork Jan 22, 2025

Choose a reason for hiding this comment

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

@kaixiong I would favor some flavor of abort or assert — something with a message —, yes, maybe using libvisual's log_and_exit? (Maybe we need one more check for that for lv_checks.h.)

uint8_t *src2_row_ptr = visual_video_get_pixels (src2);
uint8_t *dest_row_ptr = visual_video_get_pixels (dest);

uint8_t alpha = progress * 255;
Copy link
Member

Choose a reason for hiding this comment

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

The original formula was uint8_t a = alpha * (1/255.0); with rather different results, unless I am missing something. Was the old formula just wrong and the new formula fixes it or is this change accidental?

PS: If that that part of the change could be made a separate commit, I think it could help Git history clarity.

Copy link
Member Author

Choose a reason for hiding this comment

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

The existing code is wrong. Across the morph transition, alpha should move from 0 to 255 as progress is increased from 0.0 to 1.0. This increases the weight of the blended-in image as the morph progresses.

Oddly enough, 0.4.x has the correct (and equivalent) formula so I might've inverted the two ranges due to confusion.

Let me split this change out into a separate commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants