mirror of
https://github.com/webmproject/libwebp.git
synced 2025-12-23 21:46:26 +01:00
Prepare decoder and demuxer for -fbounds-safety adoption
Change memcpy|memset|memchr to unsafe variants Add WEBP_ASSUME_UNSAFE_INDEXABLE_ABI to relevant files. I've also added it to lossless.h, yuv.h, and decode.h as they're all imported by code in dec, which will have -fbounds-safety annotations. Bug: 432511225 Change-Id: I3011a0a56633b8437ead31607c7ac5f6311fa846
This commit is contained in:
@@ -26,6 +26,8 @@
|
||||
#include "src/webp/format_constants.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ALPHDecoder object.
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "src/utils/filters_utils.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "src/webp/decode.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WebPDecBuffer
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "src/webp/decode.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Main reconstruction function.
|
||||
|
||||
@@ -47,7 +49,7 @@ static int CheckMode(int mb_x, int mb_y, int mode) {
|
||||
}
|
||||
|
||||
static void Copy32b(uint8_t* const dst, const uint8_t* const src) {
|
||||
memcpy(dst, src, 4);
|
||||
WEBP_UNSAFE_MEMCPY(dst, src, 4);
|
||||
}
|
||||
|
||||
static WEBP_INLINE void DoTransform(uint32_t bits, const int16_t* const src,
|
||||
@@ -131,9 +133,9 @@ static void ReconstructRow(const VP8Decoder* const dec,
|
||||
int n;
|
||||
|
||||
if (mb_y > 0) {
|
||||
memcpy(y_dst - BPS, top_yuv[0].y, 16);
|
||||
memcpy(u_dst - BPS, top_yuv[0].u, 8);
|
||||
memcpy(v_dst - BPS, top_yuv[0].v, 8);
|
||||
WEBP_UNSAFE_MEMCPY(y_dst - BPS, top_yuv[0].y, 16);
|
||||
WEBP_UNSAFE_MEMCPY(u_dst - BPS, top_yuv[0].u, 8);
|
||||
WEBP_UNSAFE_MEMCPY(v_dst - BPS, top_yuv[0].v, 8);
|
||||
}
|
||||
|
||||
// predict and add residuals
|
||||
@@ -144,7 +146,7 @@ static void ReconstructRow(const VP8Decoder* const dec,
|
||||
if (mb_x >= dec->mb_w - 1) { // on rightmost border
|
||||
memset(top_right, top_yuv[0].y[15], sizeof(*top_right));
|
||||
} else {
|
||||
memcpy(top_right, top_yuv[1].y, sizeof(*top_right));
|
||||
WEBP_UNSAFE_MEMCPY(top_right, top_yuv[1].y, sizeof(*top_right));
|
||||
}
|
||||
}
|
||||
// replicate the top-right pixels below
|
||||
@@ -177,9 +179,9 @@ static void ReconstructRow(const VP8Decoder* const dec,
|
||||
|
||||
// stash away top samples for next block
|
||||
if (mb_y < dec->mb_h - 1) {
|
||||
memcpy(top_yuv[0].y, y_dst + 15 * BPS, 16);
|
||||
memcpy(top_yuv[0].u, u_dst + 7 * BPS, 8);
|
||||
memcpy(top_yuv[0].v, v_dst + 7 * BPS, 8);
|
||||
WEBP_UNSAFE_MEMCPY(top_yuv[0].y, y_dst + 15 * BPS, 16);
|
||||
WEBP_UNSAFE_MEMCPY(top_yuv[0].u, u_dst + 7 * BPS, 8);
|
||||
WEBP_UNSAFE_MEMCPY(top_yuv[0].v, v_dst + 7 * BPS, 8);
|
||||
}
|
||||
}
|
||||
// Transfer reconstructed samples from yuv_b cache to final destination.
|
||||
@@ -190,11 +192,14 @@ static void ReconstructRow(const VP8Decoder* const dec,
|
||||
uint8_t* const u_out = dec->cache_u + mb_x * 8 + uv_offset;
|
||||
uint8_t* const v_out = dec->cache_v + mb_x * 8 + uv_offset;
|
||||
for (j = 0; j < 16; ++j) {
|
||||
memcpy(y_out + j * dec->cache_y_stride, y_dst + j * BPS, 16);
|
||||
WEBP_UNSAFE_MEMCPY(y_out + j * dec->cache_y_stride, y_dst + j * BPS,
|
||||
16);
|
||||
}
|
||||
for (j = 0; j < 8; ++j) {
|
||||
memcpy(u_out + j * dec->cache_uv_stride, u_dst + j * BPS, 8);
|
||||
memcpy(v_out + j * dec->cache_uv_stride, v_dst + j * BPS, 8);
|
||||
WEBP_UNSAFE_MEMCPY(u_out + j * dec->cache_uv_stride, u_dst + j * BPS,
|
||||
8);
|
||||
WEBP_UNSAFE_MEMCPY(v_out + j * dec->cache_uv_stride, v_dst + j * BPS,
|
||||
8);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -494,9 +499,12 @@ static int FinishRow(void* arg1, void* arg2) {
|
||||
// rotate top samples if needed
|
||||
if (cache_id + 1 == dec->num_caches) {
|
||||
if (!is_last_row) {
|
||||
memcpy(dec->cache_y - ysize, ydst + 16 * dec->cache_y_stride, ysize);
|
||||
memcpy(dec->cache_u - uvsize, udst + 8 * dec->cache_uv_stride, uvsize);
|
||||
memcpy(dec->cache_v - uvsize, vdst + 8 * dec->cache_uv_stride, uvsize);
|
||||
WEBP_UNSAFE_MEMCPY(dec->cache_y - ysize, ydst + 16 * dec->cache_y_stride,
|
||||
ysize);
|
||||
WEBP_UNSAFE_MEMCPY(dec->cache_u - uvsize, udst + 8 * dec->cache_uv_stride,
|
||||
uvsize);
|
||||
WEBP_UNSAFE_MEMCPY(dec->cache_v - uvsize, vdst + 8 * dec->cache_uv_stride,
|
||||
uvsize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "src/webp/format_constants.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
// In append mode, buffer allocations increase as multiples of this value.
|
||||
// Needs to be a power of 2.
|
||||
#define CHUNK_SIZE 4096
|
||||
@@ -196,7 +198,7 @@ WEBP_NODISCARD static int AppendToMemBuffer(WebPIDecoder* const idec,
|
||||
uint8_t* const new_buf =
|
||||
(uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf));
|
||||
if (new_buf == NULL) return 0;
|
||||
if (old_base != NULL) memcpy(new_buf, old_base, current_size);
|
||||
if (old_base != NULL) WEBP_UNSAFE_MEMCPY(new_buf, old_base, current_size);
|
||||
WebPSafeFree(mem->buf);
|
||||
mem->buf = new_buf;
|
||||
mem->buf_size = (size_t)extra_size;
|
||||
@@ -205,7 +207,7 @@ WEBP_NODISCARD static int AppendToMemBuffer(WebPIDecoder* const idec,
|
||||
}
|
||||
|
||||
assert(mem->buf != NULL);
|
||||
memcpy(mem->buf + mem->end, data, data_size);
|
||||
WEBP_UNSAFE_MEMCPY(mem->buf + mem->end, data, data_size);
|
||||
mem->end += data_size;
|
||||
assert(mem->end <= mem->buf_size);
|
||||
|
||||
@@ -401,7 +403,7 @@ static VP8StatusCode CopyParts0Data(WebPIDecoder* const idec) {
|
||||
if (part0_buf == NULL) {
|
||||
return VP8_STATUS_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(part0_buf, br->buf, part_size);
|
||||
WEBP_UNSAFE_MEMCPY(part0_buf, br->buf, part_size);
|
||||
mem->part0_buf = part0_buf;
|
||||
VP8BitReaderSetBuffer(br, part0_buf, part_size);
|
||||
} else {
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "src/webp/decode.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Main YUV<->RGB conversion functions
|
||||
|
||||
@@ -100,9 +102,9 @@ static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
|
||||
cur_y += io->y_stride;
|
||||
if (io->crop_top + y_end < io->crop_bottom) {
|
||||
// Save the unfinished samples for next call (as we're not done yet).
|
||||
memcpy(p->tmp_y, cur_y, mb_w * sizeof(*p->tmp_y));
|
||||
memcpy(p->tmp_u, cur_u, uv_w * sizeof(*p->tmp_u));
|
||||
memcpy(p->tmp_v, cur_v, uv_w * sizeof(*p->tmp_v));
|
||||
WEBP_UNSAFE_MEMCPY(p->tmp_y, cur_y, mb_w * sizeof(*p->tmp_y));
|
||||
WEBP_UNSAFE_MEMCPY(p->tmp_u, cur_u, uv_w * sizeof(*p->tmp_u));
|
||||
WEBP_UNSAFE_MEMCPY(p->tmp_v, cur_v, uv_w * sizeof(*p->tmp_v));
|
||||
// The fancy upsampler leaves a row unfinished behind
|
||||
// (except for the very last row)
|
||||
num_lines_out--;
|
||||
@@ -140,7 +142,7 @@ static int EmitAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
|
||||
assert(expected_num_lines_out == mb_h);
|
||||
if (alpha != NULL) {
|
||||
for (j = 0; j < mb_h; ++j) {
|
||||
memcpy(dst, alpha, mb_w * sizeof(*dst));
|
||||
WEBP_UNSAFE_MEMCPY(dst, alpha, mb_w * sizeof(*dst));
|
||||
alpha += io->width;
|
||||
dst += buf->a_stride;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "src/utils/bit_reader_utils.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
static WEBP_INLINE int clip(int v, int M) { return v < 0 ? 0 : v > M ? M : v; }
|
||||
|
||||
// Paragraph 14.1
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "src/utils/bit_reader_utils.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
#if !defined(USE_GENERIC_TREE)
|
||||
#if !defined(__arm__) && !defined(_M_ARM) && !WEBP_AARCH64 && !defined(__wasm__)
|
||||
// using a table is ~1-2% slower on ARM. Prefer the coded-tree approach then.
|
||||
@@ -316,7 +318,7 @@ static void ParseIntraMode(VP8BitReader* const br, VP8Decoder* const dec,
|
||||
#endif // USE_GENERIC_TREE
|
||||
top[x] = ymode;
|
||||
}
|
||||
memcpy(modes, top, 4 * sizeof(*top));
|
||||
WEBP_UNSAFE_MEMCPY(modes, top, 4 * sizeof(*top));
|
||||
modes += 4;
|
||||
left[y] = ymode;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#include "src/webp/format_constants.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int WebPGetDecoderVersion(void) {
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include "src/webp/decode.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "src/webp/decode.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include "src/webp/format_constants.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
#define NUM_ARGB_CACHE_ROWS 16
|
||||
|
||||
static const int kCodeLengthLiterals = 16;
|
||||
@@ -843,7 +845,7 @@ static void ApplyInverseTransforms(VP8LDecoder* const dec, int start_row,
|
||||
}
|
||||
if (rows_in != rows_out) {
|
||||
// No transform called, hence just copy.
|
||||
memcpy(rows_out, rows_in, cache_pixs * sizeof(*rows_out));
|
||||
WEBP_UNSAFE_MEMCPY(rows_out, rows_in, cache_pixs * sizeof(*rows_out));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1022,7 +1024,7 @@ static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) {
|
||||
break;
|
||||
case 2:
|
||||
#if !defined(WORDS_BIGENDIAN)
|
||||
memcpy(&pattern, src, sizeof(uint16_t));
|
||||
WEBP_UNSAFE_MEMCPY(&pattern, src, sizeof(uint16_t));
|
||||
#else
|
||||
pattern = ((uint32_t)src[0] << 8) | src[1];
|
||||
#endif
|
||||
@@ -1035,7 +1037,7 @@ static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) {
|
||||
#endif
|
||||
break;
|
||||
case 4:
|
||||
memcpy(&pattern, src, sizeof(uint32_t));
|
||||
WEBP_UNSAFE_MEMCPY(&pattern, src, sizeof(uint32_t));
|
||||
break;
|
||||
default:
|
||||
goto Copy;
|
||||
@@ -1044,8 +1046,8 @@ static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) {
|
||||
return;
|
||||
}
|
||||
Copy:
|
||||
if (dist >= length) { // no overlap -> use memcpy()
|
||||
memcpy(dst, src, length * sizeof(*dst));
|
||||
if (dist >= length) { // no overlap -> use WEBP_UNSAFE_MEMCPY()
|
||||
WEBP_UNSAFE_MEMCPY(dst, src, length * sizeof(*dst));
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < length; ++i) dst[i] = src[i];
|
||||
@@ -1079,11 +1081,11 @@ static WEBP_INLINE void CopyBlock32b(uint32_t* const dst, int dist,
|
||||
pattern = (uint64_t)src[0];
|
||||
pattern |= pattern << 32;
|
||||
} else {
|
||||
memcpy(&pattern, src, sizeof(pattern));
|
||||
WEBP_UNSAFE_MEMCPY(&pattern, src, sizeof(pattern));
|
||||
}
|
||||
CopySmallPattern32b(src, dst, length, pattern);
|
||||
} else if (dist >= length) { // no overlap
|
||||
memcpy(dst, src, length * sizeof(*dst));
|
||||
WEBP_UNSAFE_MEMCPY(dst, src, length * sizeof(*dst));
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < length; ++i) dst[i] = src[i];
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "src/webp/format_constants.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "src/webp/mux_types.h" // ALPHA_FLAG
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RIFF layout is:
|
||||
// Offset tag
|
||||
|
||||
@@ -25,6 +25,8 @@ extern "C" {
|
||||
#include "src/webp/decode.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WebPDecParams: Decoding output parameters. Transient internal object.
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "src/webp/mux_types.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
#define NUM_CHANNELS 4
|
||||
|
||||
// Channel extraction from a uint32_t representation of a uint8_t RGBA/BGRA
|
||||
@@ -168,7 +170,7 @@ WEBP_NODISCARD static int ZeroFillCanvas(uint8_t* buf, uint32_t canvas_width,
|
||||
const uint64_t size =
|
||||
(uint64_t)canvas_width * canvas_height * NUM_CHANNELS * sizeof(*buf);
|
||||
if (!CheckSizeOverflow(size)) return 0;
|
||||
memset(buf, 0, (size_t)size);
|
||||
WEBP_UNSAFE_MEMSET(buf, 0, (size_t)size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -179,7 +181,7 @@ static void ZeroFillFrameRect(uint8_t* buf, int buf_stride, int x_offset,
|
||||
assert(width * NUM_CHANNELS <= buf_stride);
|
||||
buf += y_offset * buf_stride + x_offset * NUM_CHANNELS;
|
||||
for (j = 0; j < height; ++j) {
|
||||
memset(buf, 0, width * NUM_CHANNELS);
|
||||
WEBP_UNSAFE_MEMSET(buf, 0, width * NUM_CHANNELS);
|
||||
buf += buf_stride;
|
||||
}
|
||||
}
|
||||
@@ -190,7 +192,7 @@ WEBP_NODISCARD static int CopyCanvas(const uint8_t* src, uint8_t* dst,
|
||||
const uint64_t size = (uint64_t)width * height * NUM_CHANNELS;
|
||||
if (!CheckSizeOverflow(size)) return 0;
|
||||
assert(src != NULL && dst != NULL);
|
||||
memcpy(dst, src, (size_t)size);
|
||||
WEBP_UNSAFE_MEMCPY(dst, src, (size_t)size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -456,7 +458,7 @@ void WebPAnimDecoderReset(WebPAnimDecoder* dec) {
|
||||
if (dec != NULL) {
|
||||
dec->prev_frame_timestamp = 0;
|
||||
WebPDemuxReleaseIterator(&dec->prev_iter);
|
||||
memset(&dec->prev_iter, 0, sizeof(dec->prev_iter));
|
||||
WEBP_UNSAFE_MEMSET(&dec->prev_iter, 0, sizeof(dec->prev_iter));
|
||||
dec->prev_frame_was_keyframe = 0;
|
||||
dec->next_frame = 1;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "src/webp/mux_types.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
#define DMUX_MAJ_VERSION 1
|
||||
#define DMUX_MIN_VERSION 6
|
||||
#define DMUX_REV_VERSION 0
|
||||
@@ -116,7 +118,7 @@ static int RemapMemBuffer(MemBuffer* const mem, const uint8_t* data,
|
||||
|
||||
static int InitMemBuffer(MemBuffer* const mem, const uint8_t* data,
|
||||
size_t size) {
|
||||
memset(mem, 0, sizeof(*mem));
|
||||
WEBP_UNSAFE_MEMSET(mem, 0, sizeof(*mem));
|
||||
return RemapMemBuffer(mem, data, size);
|
||||
}
|
||||
|
||||
@@ -874,7 +876,7 @@ static int SetFrame(int frame_num, WebPIterator* const iter) {
|
||||
int WebPDemuxGetFrame(const WebPDemuxer* dmux, int frame, WebPIterator* iter) {
|
||||
if (iter == NULL) return 0;
|
||||
|
||||
memset(iter, 0, sizeof(*iter));
|
||||
WEBP_UNSAFE_MEMSET(iter, 0, sizeof(*iter));
|
||||
iter->private_ = (void*)dmux;
|
||||
return SetFrame(frame, iter);
|
||||
}
|
||||
@@ -945,7 +947,7 @@ int WebPDemuxGetChunk(const WebPDemuxer* dmux, const char fourcc[4],
|
||||
int chunk_num, WebPChunkIterator* iter) {
|
||||
if (iter == NULL) return 0;
|
||||
|
||||
memset(iter, 0, sizeof(*iter));
|
||||
WEBP_UNSAFE_MEMSET(iter, 0, sizeof(*iter));
|
||||
iter->private_ = (void*)dmux;
|
||||
return SetChunk(fourcc, chunk_num, iter);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include "src/webp/decode.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
// Macros to give the offset of each channel in a uint32_t containing ARGB.
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
// uint32_t 0xff000000 is 0xff,00,00,00 in memory
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include "./types.h"
|
||||
|
||||
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user