diff --git a/src/dec/alpha_dec.c b/src/dec/alpha_dec.c index b3cb4edf..2632073f 100644 --- a/src/dec/alpha_dec.c +++ b/src/dec/alpha_dec.c @@ -26,6 +26,8 @@ #include "src/webp/format_constants.h" #include "src/webp/types.h" +WEBP_ASSUME_UNSAFE_INDEXABLE_ABI + //------------------------------------------------------------------------------ // ALPHDecoder object. diff --git a/src/dec/alphai_dec.h b/src/dec/alphai_dec.h index 6dfe5a96..44739392 100644 --- a/src/dec/alphai_dec.h +++ b/src/dec/alphai_dec.h @@ -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 diff --git a/src/dec/buffer_dec.c b/src/dec/buffer_dec.c index 5a4a3862..787e6406 100644 --- a/src/dec/buffer_dec.c +++ b/src/dec/buffer_dec.c @@ -22,6 +22,8 @@ #include "src/webp/decode.h" #include "src/webp/types.h" +WEBP_ASSUME_UNSAFE_INDEXABLE_ABI + //------------------------------------------------------------------------------ // WebPDecBuffer diff --git a/src/dec/frame_dec.c b/src/dec/frame_dec.c index dcb691e9..806e294d 100644 --- a/src/dec/frame_dec.c +++ b/src/dec/frame_dec.c @@ -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); } } diff --git a/src/dec/idec_dec.c b/src/dec/idec_dec.c index 3eab0acb..dd0e0879 100644 --- a/src/dec/idec_dec.c +++ b/src/dec/idec_dec.c @@ -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 { diff --git a/src/dec/io_dec.c b/src/dec/io_dec.c index 8230f6bf..cea04225 100644 --- a/src/dec/io_dec.c +++ b/src/dec/io_dec.c @@ -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; } diff --git a/src/dec/quant_dec.c b/src/dec/quant_dec.c index 31b2e5b4..9194e044 100644 --- a/src/dec/quant_dec.c +++ b/src/dec/quant_dec.c @@ -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 diff --git a/src/dec/tree_dec.c b/src/dec/tree_dec.c index 58c8e040..bd93d53b 100644 --- a/src/dec/tree_dec.c +++ b/src/dec/tree_dec.c @@ -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; } diff --git a/src/dec/vp8_dec.c b/src/dec/vp8_dec.c index 3225cb98..b43fb556 100644 --- a/src/dec/vp8_dec.c +++ b/src/dec/vp8_dec.c @@ -32,6 +32,8 @@ #include "src/webp/format_constants.h" #include "src/webp/types.h" +WEBP_ASSUME_UNSAFE_INDEXABLE_ABI + //------------------------------------------------------------------------------ int WebPGetDecoderVersion(void) { diff --git a/src/dec/vp8_dec.h b/src/dec/vp8_dec.h index 2be0d799..a0f66ba6 100644 --- a/src/dec/vp8_dec.h +++ b/src/dec/vp8_dec.h @@ -19,6 +19,8 @@ #include "src/webp/decode.h" #include "src/webp/types.h" +WEBP_ASSUME_UNSAFE_INDEXABLE_ABI + #ifdef __cplusplus extern "C" { #endif diff --git a/src/dec/vp8i_dec.h b/src/dec/vp8i_dec.h index 62720ac7..28ec15c5 100644 --- a/src/dec/vp8i_dec.h +++ b/src/dec/vp8i_dec.h @@ -27,6 +27,8 @@ #include "src/webp/decode.h" #include "src/webp/types.h" +WEBP_ASSUME_UNSAFE_INDEXABLE_ABI + #ifdef __cplusplus extern "C" { #endif diff --git a/src/dec/vp8l_dec.c b/src/dec/vp8l_dec.c index b584d3ff..d25b3dab 100644 --- a/src/dec/vp8l_dec.c +++ b/src/dec/vp8l_dec.c @@ -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]; diff --git a/src/dec/vp8li_dec.h b/src/dec/vp8li_dec.h index bffad693..cbf3ce1f 100644 --- a/src/dec/vp8li_dec.h +++ b/src/dec/vp8li_dec.h @@ -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 diff --git a/src/dec/webp_dec.c b/src/dec/webp_dec.c index dd1a6f6c..9377d2b9 100644 --- a/src/dec/webp_dec.c +++ b/src/dec/webp_dec.c @@ -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 diff --git a/src/dec/webpi_dec.h b/src/dec/webpi_dec.h index 5aa9bc4d..506ffcc0 100644 --- a/src/dec/webpi_dec.h +++ b/src/dec/webpi_dec.h @@ -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. diff --git a/src/demux/anim_decode.c b/src/demux/anim_decode.c index 01ef9ce8..259aaff7 100644 --- a/src/demux/anim_decode.c +++ b/src/demux/anim_decode.c @@ -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; } diff --git a/src/demux/demux.c b/src/demux/demux.c index c7c91d6b..c4f8d1a2 100644 --- a/src/demux/demux.c +++ b/src/demux/demux.c @@ -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); } diff --git a/src/dsp/lossless.h b/src/dsp/lossless.h index a80efcb8..7df94119 100644 --- a/src/dsp/lossless.h +++ b/src/dsp/lossless.h @@ -19,6 +19,8 @@ #include "src/webp/decode.h" #include "src/webp/types.h" +WEBP_ASSUME_UNSAFE_INDEXABLE_ABI + #ifdef __cplusplus extern "C" { #endif diff --git a/src/dsp/yuv.h b/src/dsp/yuv.h index 52f9b14d..107c167e 100644 --- a/src/dsp/yuv.h +++ b/src/dsp/yuv.h @@ -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 diff --git a/src/webp/decode.h b/src/webp/decode.h index 0cd36655..8a57fb26 100644 --- a/src/webp/decode.h +++ b/src/webp/decode.h @@ -18,6 +18,8 @@ #include "./types.h" +WEBP_ASSUME_UNSAFE_INDEXABLE_ABI + #ifdef __cplusplus extern "C" { #endif