mirror of
https://github.com/webmproject/libwebp.git
synced 2025-08-29 15:22:12 +02:00
Add fbounds-safety annotations for WebPRescaler
.
Reasoning: The `irow` and `frow` pointers in `WebPRescaler` (src/utils/rescaler_utils.h:49) were annotated with `WEBP_COUNTED_BY(dst_width * num_channels)`. This is based on their initialization in `WebPRescalerInit` (src/utils/rescaler_utils.c:82-83) where they are assigned parts of the `work` buffer, whose total size is `2 * dst_width * num_channels`. The `work` parameter in `WebPRescalerInit` (src/utils/rescaler_utils.h:58, src/utils/rescaler_utils.c:33) was also annotated accordingly. To satisfy the side-by-side assignment requirement for external bounds, assignments to `rescaler->irow` and `rescaler->frow` in `WebPRescalerInit` were moved closer to the assignments of `dst_width` and `num_channels` (src/utils/rescaler_utils.c:50-53). Since `work` have bound information, `WEBP_UNSAFE_MEMSET` has been changed to `memset`. In `WebPRescalerImport` (src/utils/rescaler_utils.c:140-150), where `irow` and `frow` are swapped, self-assignments for `dst_width` and `num_channels` were added side-by-side with the pointer assignments. Additionally, `WEBP_UNSAFE_FORGE_BIDI_INDEXABLE` was used for the pointer assignments to handle the `WEBP_ASSUME_UNSAFE_INDEXABLE_ABI` setting used during testing. Bug: 432511821 Change-Id: If716fb79a06dee9e807eff060806daf038810523
This commit is contained in:
@@ -30,7 +30,8 @@ WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
|||||||
int WebPRescalerInit(WebPRescaler* const rescaler, int src_width,
|
int WebPRescalerInit(WebPRescaler* const rescaler, int src_width,
|
||||||
int src_height, uint8_t* const dst, int dst_width,
|
int src_height, uint8_t* const dst, int dst_width,
|
||||||
int dst_height, int dst_stride, int num_channels,
|
int dst_height, int dst_stride, int num_channels,
|
||||||
rescaler_t* const work) {
|
rescaler_t* const WEBP_COUNTED_BY(2ULL * dst_width *
|
||||||
|
num_channels) work) {
|
||||||
const int x_add = src_width, x_sub = dst_width;
|
const int x_add = src_width, x_sub = dst_width;
|
||||||
const int y_add = src_height, y_sub = dst_height;
|
const int y_add = src_height, y_sub = dst_height;
|
||||||
const uint64_t total_size = 2ull * dst_width * num_channels * sizeof(*work);
|
const uint64_t total_size = 2ull * dst_width * num_channels * sizeof(*work);
|
||||||
@@ -47,6 +48,9 @@ int WebPRescalerInit(WebPRescaler* const rescaler, int src_width,
|
|||||||
rescaler->dst = dst;
|
rescaler->dst = dst;
|
||||||
rescaler->dst_stride = dst_stride;
|
rescaler->dst_stride = dst_stride;
|
||||||
rescaler->num_channels = num_channels;
|
rescaler->num_channels = num_channels;
|
||||||
|
rescaler->irow = work;
|
||||||
|
rescaler->frow = work + num_channels * dst_width;
|
||||||
|
memset(work, 0, (size_t)total_size);
|
||||||
|
|
||||||
// for 'x_expand', we use bilinear interpolation
|
// for 'x_expand', we use bilinear interpolation
|
||||||
rescaler->x_add = rescaler->x_expand ? (x_sub - 1) : x_add;
|
rescaler->x_add = rescaler->x_expand ? (x_sub - 1) : x_add;
|
||||||
@@ -79,9 +83,6 @@ int WebPRescalerInit(WebPRescaler* const rescaler, int src_width,
|
|||||||
rescaler->fy_scale = WEBP_RESCALER_FRAC(1, rescaler->x_add);
|
rescaler->fy_scale = WEBP_RESCALER_FRAC(1, rescaler->x_add);
|
||||||
// rescaler->fxy_scale is unused here.
|
// rescaler->fxy_scale is unused here.
|
||||||
}
|
}
|
||||||
rescaler->irow = work;
|
|
||||||
rescaler->frow = work + num_channels * dst_width;
|
|
||||||
WEBP_UNSAFE_MEMSET(work, 0, (size_t)total_size);
|
|
||||||
|
|
||||||
WebPRescalerDspInit();
|
WebPRescalerDspInit();
|
||||||
return 1;
|
return 1;
|
||||||
@@ -136,7 +137,11 @@ int WebPRescalerImport(WebPRescaler* const rescaler, int num_lines,
|
|||||||
if (rescaler->y_expand) {
|
if (rescaler->y_expand) {
|
||||||
rescaler_t* const tmp = rescaler->irow;
|
rescaler_t* const tmp = rescaler->irow;
|
||||||
rescaler->irow = rescaler->frow;
|
rescaler->irow = rescaler->frow;
|
||||||
rescaler->frow = tmp;
|
rescaler->frow = WEBP_UNSAFE_FORGE_BIDI_INDEXABLE(
|
||||||
|
rescaler_t*, tmp,
|
||||||
|
rescaler->num_channels * rescaler->dst_width * sizeof(*tmp));
|
||||||
|
WEBP_SELF_ASSIGN(rescaler->dst_width);
|
||||||
|
WEBP_SELF_ASSIGN(rescaler->num_channels);
|
||||||
}
|
}
|
||||||
WebPRescalerImportRow(rescaler, src);
|
WebPRescalerImportRow(rescaler, src);
|
||||||
if (!rescaler->y_expand) { // Accumulate the contribution of the new row.
|
if (!rescaler->y_expand) { // Accumulate the contribution of the new row.
|
||||||
|
@@ -46,7 +46,9 @@ struct WebPRescaler {
|
|||||||
int src_y, dst_y; // row counters for input and output
|
int src_y, dst_y; // row counters for input and output
|
||||||
uint8_t* dst;
|
uint8_t* dst;
|
||||||
int dst_stride;
|
int dst_stride;
|
||||||
rescaler_t *irow, *frow; // work buffer
|
// work buffer
|
||||||
|
rescaler_t* WEBP_COUNTED_BY(dst_width* num_channels) irow;
|
||||||
|
rescaler_t* WEBP_COUNTED_BY(dst_width* num_channels) frow;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize a rescaler given scratch area 'work' and dimensions of src & dst.
|
// Initialize a rescaler given scratch area 'work' and dimensions of src & dst.
|
||||||
@@ -54,7 +56,8 @@ struct WebPRescaler {
|
|||||||
int WebPRescalerInit(WebPRescaler* const rescaler, int src_width,
|
int WebPRescalerInit(WebPRescaler* const rescaler, int src_width,
|
||||||
int src_height, uint8_t* const dst, int dst_width,
|
int src_height, uint8_t* const dst, int dst_width,
|
||||||
int dst_height, int dst_stride, int num_channels,
|
int dst_height, int dst_stride, int num_channels,
|
||||||
rescaler_t* const work);
|
rescaler_t* const WEBP_COUNTED_BY(2ULL * dst_width *
|
||||||
|
num_channels) work);
|
||||||
|
|
||||||
// If either 'scaled_width' or 'scaled_height' (but not both) is 0 the value
|
// If either 'scaled_width' or 'scaled_height' (but not both) is 0 the value
|
||||||
// will be calculated preserving the aspect ratio, otherwise the values are
|
// will be calculated preserving the aspect ratio, otherwise the values are
|
||||||
|
Reference in New Issue
Block a user