You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-04 22:03:09 +02:00
avfilter/vf_overlay: Don't perform UB pointer arithmetic
This happens when the pixel format of the output does not have an alpha channel. It leads to FATE failures with the ffmpeg-filter_colorkey, filter-overlay-dvdsub-2397 filter-overlay, filter-overlay_{gbrp_gbrap,nv12,nv21,yuv420,yuv420_yuva420, yuv420p10,yuv422_yuva422,yuv422p10,yuv444_yuva444,yuv444p10} and sub2video tests when using Clang UBSan. Fix this by only performing the pointer arithmetic when it is going to be used. This can be checked via variables that compile-time constants due to inlining, so that the checks are free. Given that the pointer is potentially used as a function argument, the compiler could elide the calculation, but not it can. The size of .text decreased by 1632B with GCC 14 and by 1392B with Clang 19 (both -O3). Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
@ -467,7 +467,7 @@ static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext
|
|||||||
int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub); \
|
int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub); \
|
||||||
int yp = y>>vsub; \
|
int yp = y>>vsub; \
|
||||||
int xp = x>>hsub; \
|
int xp = x>>hsub; \
|
||||||
uint##depth##_t *s, *sp, *d, *dp, *dap, *a, *da, *ap; \
|
uint##depth##_t *s, *sp, *d, *dp, *dap, *a, *ap; \
|
||||||
int jmax, j, k, kmax; \
|
int jmax, j, k, kmax; \
|
||||||
int slice_start, slice_end; \
|
int slice_start, slice_end; \
|
||||||
const uint##depth##_t max = (1 << nbits) - 1; \
|
const uint##depth##_t max = (1 << nbits) - 1; \
|
||||||
@ -486,6 +486,7 @@ static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext
|
|||||||
+ (yp + slice_start) * dst->linesize[dst_plane] \
|
+ (yp + slice_start) * dst->linesize[dst_plane] \
|
||||||
+ dst_offset); \
|
+ dst_offset); \
|
||||||
ap = (uint##depth##_t *)(src->data[3] + (slice_start << vsub) * src->linesize[3]); \
|
ap = (uint##depth##_t *)(src->data[3] + (slice_start << vsub) * src->linesize[3]); \
|
||||||
|
if (main_has_alpha) \
|
||||||
dap = (uint##depth##_t *)(dst->data[3] + ((yp + slice_start) << vsub) * dst->linesize[3]); \
|
dap = (uint##depth##_t *)(dst->data[3] + ((yp + slice_start) << vsub) * dst->linesize[3]); \
|
||||||
\
|
\
|
||||||
for (j = slice_start; j < slice_end; j++) { \
|
for (j = slice_start; j < slice_end; j++) { \
|
||||||
@ -493,7 +494,7 @@ static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext
|
|||||||
d = dp + (xp+k) * dst_step; \
|
d = dp + (xp+k) * dst_step; \
|
||||||
s = sp + k; \
|
s = sp + k; \
|
||||||
a = ap + (k<<hsub); \
|
a = ap + (k<<hsub); \
|
||||||
da = dap + ((xp+k) << hsub); \
|
uint##depth##_t *da = main_has_alpha ? dap + ((xp+k) << hsub) : NULL; \
|
||||||
kmax = FFMIN(-xp + dst_wp, src_wp); \
|
kmax = FFMIN(-xp + dst_wp, src_wp); \
|
||||||
\
|
\
|
||||||
if (nbits == 8 && ((vsub && j+1 < src_hp) || !vsub) && octx->blend_row[i]) { \
|
if (nbits == 8 && ((vsub && j+1 < src_hp) || !vsub) && octx->blend_row[i]) { \
|
||||||
@ -502,6 +503,7 @@ static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext
|
|||||||
\
|
\
|
||||||
s += c; \
|
s += c; \
|
||||||
d += dst_step * c; \
|
d += dst_step * c; \
|
||||||
|
if (main_has_alpha) \
|
||||||
da += (1 << hsub) * c; \
|
da += (1 << hsub) * c; \
|
||||||
a += (1 << hsub) * c; \
|
a += (1 << hsub) * c; \
|
||||||
k += c; \
|
k += c; \
|
||||||
@ -560,12 +562,14 @@ static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext
|
|||||||
} \
|
} \
|
||||||
s++; \
|
s++; \
|
||||||
d += dst_step; \
|
d += dst_step; \
|
||||||
|
if (main_has_alpha) \
|
||||||
da += 1 << hsub; \
|
da += 1 << hsub; \
|
||||||
a += 1 << hsub; \
|
a += 1 << hsub; \
|
||||||
} \
|
} \
|
||||||
dp += dst->linesize[dst_plane] / bytes; \
|
dp += dst->linesize[dst_plane] / bytes; \
|
||||||
sp += src->linesize[i] / bytes; \
|
sp += src->linesize[i] / bytes; \
|
||||||
ap += (1 << vsub) * src->linesize[3] / bytes; \
|
ap += (1 << vsub) * src->linesize[3] / bytes; \
|
||||||
|
if (main_has_alpha) \
|
||||||
dap += (1 << vsub) * dst->linesize[3] / bytes; \
|
dap += (1 << vsub) * dst->linesize[3] / bytes; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user