mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-06-21 20:19:18 -04:00
Image::Rotate and Image::Flip computed chroma plane dimensions with AV_CEIL_RSHIFT(width, log2_chroma_w). The macro's runtime form is -((-(a)) >> (b)), which relies on arithmetic right shift of a negative value and is only valid for signed operands - FFmpeg always passes int. Image::width/height are unsigned, so the negation wraps, the shift is logical, and the result is 2^31 + ceil(w/2^b) instead of ceil(w/2^b): for 1280x720 the chroma rotate received src_w=2147484288 and src_h=2147484008 (captured in gdb), writing gigabytes out of bounds. Effect: zmc's decoder thread segfaulted on the first decoded frame of any monitor with a rotated or flipped orientation and a planar pixel format - a monitor with decoding Always crash-loops. Replace the macro at both sites with an explicit unsigned ceiling shift helper and a comment documenting the trap. Tests: new tests/zm_image.cpp covers Rotate 90/180/270 and Flip on YUV420P with per-plane marker pixels, plus odd dimensions exercising the chroma ceiling. The Rotate cases segfault before this fix (verified, exit 139) and pass after. Full suite 85/85 via ctest. Live-verified on a 1280x720 ROTATE_270 monitor with decoding Always: pre-fix crash within seconds, post-fix 90s clean run under gdb. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>