From adc6875870b7dec661c0165bcb689e45e6169722 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 17 Jun 2022 10:22:28 -0700 Subject: [PATCH] Added SDL_copyp to avoid size mismatch when copying values (thanks @1bsyl!) Closes https://github.com/libsdl-org/SDL/pull/5811 --- include/SDL_stdinc.h | 5 +++++ src/audio/SDL_audio.c | 6 +++--- src/core/linux/SDL_fcitx.c | 2 +- src/events/SDL_gesture.c | 2 +- src/render/SDL_render.c | 4 ++-- src/render/direct3d/SDL_render_d3d.c | 8 ++++---- src/render/direct3d11/SDL_render_d3d11.c | 10 +++++----- src/render/direct3d12/SDL_render_d3d12.c | 8 ++++---- src/render/opengl/SDL_render_gl.c | 8 ++++---- src/render/opengles/SDL_render_gles.c | 8 ++++---- src/render/opengles2/SDL_render_gles2.c | 8 ++++---- src/render/software/SDL_render_sw.c | 6 +++--- src/render/vitagxm/SDL_render_vita_gxm.c | 8 ++++---- src/thread/windows/SDL_syscond_cv.c | 2 +- src/thread/windows/SDL_sysmutex.c | 2 +- src/thread/windows/SDL_syssem.c | 2 +- src/video/os2/SDL_os2video.c | 2 +- src/video/wayland/SDL_waylandkeyboard.c | 2 +- 18 files changed, 49 insertions(+), 44 deletions(-) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index c21e54c06..c0bc8aa1a 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -501,6 +501,11 @@ extern DECLSPEC void *SDLCALL SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, #define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x))) #define SDL_zeroa(x) SDL_memset((x), 0, sizeof((x))) +#define SDL_copyp(dst, src) \ + { SDL_COMPILE_TIME_ASSERT(SDL_copyp, sizeof (*(dst)) == sizeof (*(src))); } \ + SDL_memcpy((dst), (src), sizeof (*(src))) + + /* Note that memset() is a byte assignment and this is a 32-bit assignment, so they're not directly equivalent. */ SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords) { diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index ac3ac1fc2..8cabcd9a2 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -382,7 +382,7 @@ add_audio_device(const char *name, SDL_AudioSpec *spec, void *handle, SDL_AudioD item->dupenum = 0; item->name = item->original_name; if (spec != NULL) { - SDL_memcpy(&item->spec, spec, sizeof(SDL_AudioSpec)); + SDL_copyp(&item->spec, spec); } else { SDL_zero(item->spec); } @@ -1131,7 +1131,7 @@ SDL_GetAudioDeviceSpec(int index, int iscapture, SDL_AudioSpec *spec) SDL_assert(item != NULL); } SDL_assert(item != NULL); - SDL_memcpy(spec, &item->spec, sizeof(SDL_AudioSpec)); + SDL_copyp(spec, &item->spec); retval = 0; } else { retval = SDL_InvalidParamError("index"); @@ -1193,7 +1193,7 @@ close_audio_device(SDL_AudioDevice * device) static int prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared) { - SDL_memcpy(prepared, orig, sizeof(SDL_AudioSpec)); + SDL_copyp(prepared, orig); if (orig->freq == 0) { const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY"); diff --git a/src/core/linux/SDL_fcitx.c b/src/core/linux/SDL_fcitx.c index b7a0cfacf..1ce8bd11f 100644 --- a/src/core/linux/SDL_fcitx.c +++ b/src/core/linux/SDL_fcitx.c @@ -431,7 +431,7 @@ SDL_Fcitx_UpdateTextRect(SDL_Rect *rect) SDL_Rect *cursor = &fcitx_client.cursor_rect; if (rect) { - SDL_memcpy(cursor, rect, sizeof(SDL_Rect)); + SDL_copyp(cursor, rect); } focused_win = SDL_GetKeyboardFocus(); diff --git a/src/events/SDL_gesture.c b/src/events/SDL_gesture.c index 8d97f3138..2cdb0d594 100644 --- a/src/events/SDL_gesture.c +++ b/src/events/SDL_gesture.c @@ -488,7 +488,7 @@ int SDL_GestureDelTouch(SDL_TouchID touchId) SDL_numGestureTouches--; if (i != SDL_numGestureTouches) { - SDL_memcpy(&SDL_gestureTouch[i], &SDL_gestureTouch[SDL_numGestureTouches], sizeof(SDL_gestureTouch[i])); + SDL_copyp(&SDL_gestureTouch[i], &SDL_gestureTouch[SDL_numGestureTouches]); } return 0; } diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 7d9d97eef..8537be397 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -368,7 +368,7 @@ QueueCmdSetViewport(SDL_Renderer *renderer) if (retval < 0) { cmd->command = SDL_RENDERCMD_NO_OP; } else { - SDL_memcpy(&renderer->last_queued_viewport, &renderer->viewport, sizeof (SDL_DRect)); + SDL_copyp(&renderer->last_queued_viewport, &renderer->viewport); renderer->viewport_queued = SDL_TRUE; } } @@ -394,7 +394,7 @@ QueueCmdSetClipRect(SDL_Renderer *renderer) cmd->data.cliprect.rect.y = (int)SDL_floor(renderer->clip_rect.y); cmd->data.cliprect.rect.w = (int)SDL_floor(renderer->clip_rect.w); cmd->data.cliprect.rect.h = (int)SDL_floor(renderer->clip_rect.h); - SDL_memcpy(&renderer->last_queued_cliprect, &renderer->clip_rect, sizeof (SDL_DRect)); + SDL_copyp(&renderer->last_queued_cliprect, &renderer->clip_rect); renderer->last_queued_cliprect_enabled = renderer->clipping_enabled; renderer->cliprect_queued = SDL_TRUE; } diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c index 2708d2d00..3d0eac892 100644 --- a/src/render/direct3d/SDL_render_d3d.c +++ b/src/render/direct3d/SDL_render_d3d.c @@ -1207,8 +1207,8 @@ D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti case SDL_RENDERCMD_SETVIEWPORT: { SDL_Rect *viewport = &data->drawstate.viewport; - if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); data->drawstate.viewport_dirty = SDL_TRUE; } break; @@ -1221,8 +1221,8 @@ D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti data->drawstate.cliprect_enabled_dirty = SDL_TRUE; } - if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)); + if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&data->drawstate.cliprect, rect); data->drawstate.cliprect_dirty = SDL_TRUE; } break; diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c index 30c44ce48..49a193ab0 100644 --- a/src/render/direct3d11/SDL_render_d3d11.c +++ b/src/render/direct3d11/SDL_render_d3d11.c @@ -1982,7 +1982,7 @@ D3D11_SetDrawState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, ID3D11 } if (updateSubresource == SDL_TRUE || SDL_memcmp(&rendererData->vertexShaderConstantsData.model, newmatrix, sizeof (*newmatrix)) != 0) { - SDL_memcpy(&rendererData->vertexShaderConstantsData.model, newmatrix, sizeof (*newmatrix)); + SDL_copyp(&rendererData->vertexShaderConstantsData.model, newmatrix); ID3D11DeviceContext_UpdateSubresource(rendererData->d3dContext, (ID3D11Resource *)rendererData->vertexShaderConstants, 0, @@ -2101,8 +2101,8 @@ D3D11_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver case SDL_RENDERCMD_SETVIEWPORT: { SDL_Rect *viewport = &rendererData->currentViewport; - if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); rendererData->viewportDirty = SDL_TRUE; } break; @@ -2114,8 +2114,8 @@ D3D11_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver rendererData->currentCliprectEnabled = cmd->data.cliprect.enabled; rendererData->cliprectDirty = SDL_TRUE; } - if (SDL_memcmp(&rendererData->currentCliprect, rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(&rendererData->currentCliprect, rect, sizeof (SDL_Rect)); + if (SDL_memcmp(&rendererData->currentCliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&rendererData->currentCliprect, rect); rendererData->cliprectDirty = SDL_TRUE; } break; diff --git a/src/render/direct3d12/SDL_render_d3d12.c b/src/render/direct3d12/SDL_render_d3d12.c index ac191f1dc..413e1d880 100644 --- a/src/render/direct3d12/SDL_render_d3d12.c +++ b/src/render/direct3d12/SDL_render_d3d12.c @@ -2591,8 +2591,8 @@ D3D12_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver case SDL_RENDERCMD_SETVIEWPORT: { SDL_Rect *viewport = &rendererData->currentViewport; - if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); rendererData->viewportDirty = SDL_TRUE; } break; @@ -2609,8 +2609,8 @@ D3D12_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver since direct3d12 doesn't allow disabling the scissor rectangle */ rect = &rendererData->currentViewport; } - if (SDL_memcmp(&rendererData->currentCliprect, rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(&rendererData->currentCliprect, rect, sizeof (SDL_Rect)); + if (SDL_memcmp(&rendererData->currentCliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&rendererData->currentCliprect, rect); rendererData->cliprectDirty = SDL_TRUE; } break; diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c index b5af52af3..dbbb7ee52 100644 --- a/src/render/opengl/SDL_render_gl.c +++ b/src/render/opengl/SDL_render_gl.c @@ -1254,8 +1254,8 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic case SDL_RENDERCMD_SETVIEWPORT: { SDL_Rect *viewport = &data->drawstate.viewport; - if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); data->drawstate.viewport_dirty = SDL_TRUE; } break; @@ -1268,8 +1268,8 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic data->drawstate.cliprect_enabled_dirty = SDL_TRUE; } - if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)); + if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&data->drawstate.cliprect, rect); data->drawstate.cliprect_dirty = SDL_TRUE; } break; diff --git a/src/render/opengles/SDL_render_gles.c b/src/render/opengles/SDL_render_gles.c index a6b58f2d7..9afd8d1af 100644 --- a/src/render/opengles/SDL_render_gles.c +++ b/src/render/opengles/SDL_render_gles.c @@ -796,8 +796,8 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert case SDL_RENDERCMD_SETVIEWPORT: { SDL_Rect *viewport = &data->drawstate.viewport; - if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); data->drawstate.viewport_dirty = SDL_TRUE; } break; @@ -809,8 +809,8 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; data->drawstate.cliprect_enabled_dirty = SDL_TRUE; } - if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)); + if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&data->drawstate.cliprect, rect); data->drawstate.cliprect_dirty = SDL_TRUE; } break; diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index c2f5d640f..112c1e8ac 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -1155,8 +1155,8 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver case SDL_RENDERCMD_SETVIEWPORT: { SDL_Rect *viewport = &data->drawstate.viewport; - if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); data->drawstate.viewport_dirty = SDL_TRUE; } break; @@ -1169,8 +1169,8 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver data->drawstate.cliprect_enabled_dirty = SDL_TRUE; } - if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)); + if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&data->drawstate.cliprect, rect); data->drawstate.cliprect_dirty = SDL_TRUE; } break; diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c index a1af12cd6..34092b58d 100644 --- a/src/render/software/SDL_render_sw.c +++ b/src/render/software/SDL_render_sw.c @@ -255,7 +255,7 @@ SW_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * text cmd->data.draw.count = 1; - SDL_memcpy(verts, srcrect, sizeof (SDL_Rect)); + SDL_copyp(verts, srcrect); verts++; verts->x = (int)dstrect->x; @@ -290,14 +290,14 @@ SW_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * te cmd->data.draw.count = 1; - SDL_memcpy(&verts->srcrect, srcrect, sizeof (SDL_Rect)); + SDL_copyp(&verts->srcrect, srcrect); verts->dstrect.x = (int)dstrect->x; verts->dstrect.y = (int)dstrect->y; verts->dstrect.w = (int)dstrect->w; verts->dstrect.h = (int)dstrect->h; verts->angle = angle; - SDL_memcpy(&verts->center, center, sizeof (SDL_FPoint)); + SDL_copyp(&verts->center, center); verts->flip = flip; verts->scale_x = scale_x; verts->scale_y = scale_y; diff --git a/src/render/vitagxm/SDL_render_vita_gxm.c b/src/render/vitagxm/SDL_render_vita_gxm.c index 98b03e629..a4b2cee6f 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm.c +++ b/src/render/vitagxm/SDL_render_vita_gxm.c @@ -999,8 +999,8 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void * case SDL_RENDERCMD_SETVIEWPORT: { SDL_Rect *viewport = &data->drawstate.viewport; - if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); data->drawstate.viewport_dirty = SDL_TRUE; } break; @@ -1013,8 +1013,8 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void * data->drawstate.cliprect_enabled_dirty = SDL_TRUE; } - if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)); + if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&data->drawstate.cliprect, rect); data->drawstate.cliprect_dirty = SDL_TRUE; } break; diff --git a/src/thread/windows/SDL_syscond_cv.c b/src/thread/windows/SDL_syscond_cv.c index 54d34084f..9c0ceb3a8 100644 --- a/src/thread/windows/SDL_syscond_cv.c +++ b/src/thread/windows/SDL_syscond_cv.c @@ -261,7 +261,7 @@ SDL_CreateCond(void) } #endif - SDL_memcpy(&SDL_cond_impl_active, impl, sizeof(SDL_cond_impl_active)); + SDL_copyp(&SDL_cond_impl_active, impl); } return SDL_cond_impl_active.Create(); } diff --git a/src/thread/windows/SDL_sysmutex.c b/src/thread/windows/SDL_sysmutex.c index b0b4abcb0..3974b3362 100644 --- a/src/thread/windows/SDL_sysmutex.c +++ b/src/thread/windows/SDL_sysmutex.c @@ -287,7 +287,7 @@ SDL_CreateMutex(void) } /* Copy instead of using pointer to save one level of indirection */ - SDL_memcpy(&SDL_mutex_impl_active, impl, sizeof(SDL_mutex_impl_active)); + SDL_copyp(&SDL_mutex_impl_active, impl); } return SDL_mutex_impl_active.Create(); } diff --git a/src/thread/windows/SDL_syssem.c b/src/thread/windows/SDL_syssem.c index 794a713a8..629f2a9cc 100644 --- a/src/thread/windows/SDL_syssem.c +++ b/src/thread/windows/SDL_syssem.c @@ -430,7 +430,7 @@ SDL_CreateSemaphore(Uint32 initial_value) #endif /* Copy instead of using pointer to save one level of indirection */ - SDL_memcpy(&SDL_sem_impl_active, impl, sizeof(SDL_sem_impl_active)); + SDL_copyp(&SDL_sem_impl_active, impl); } return SDL_sem_impl_active.Create(initial_value); } diff --git a/src/video/os2/SDL_os2video.c b/src/video/os2/SDL_os2video.c index 65428da65..81e8e554f 100644 --- a/src/video/os2/SDL_os2video.c +++ b/src/video/os2/SDL_os2video.c @@ -1572,7 +1572,7 @@ static void OS2_GetDisplayModes(_THIS, SDL_VideoDisplay *display) SDL_DisplayMode mode; debug_os2("Enter"); - SDL_memcpy(&mode, &display->current_mode, sizeof(SDL_DisplayMode)); + SDL_copyp(&mode, &display->current_mode); mode.driverdata = (MODEDATA *) SDL_malloc(sizeof(MODEDATA)); if (!mode.driverdata) return; /* yikes.. */ SDL_memcpy(mode.driverdata, display->current_mode.driverdata, sizeof(MODEDATA)); diff --git a/src/video/wayland/SDL_waylandkeyboard.c b/src/video/wayland/SDL_waylandkeyboard.c index ad91ca5c4..8f293a546 100644 --- a/src/video/wayland/SDL_waylandkeyboard.c +++ b/src/video/wayland/SDL_waylandkeyboard.c @@ -120,7 +120,7 @@ Wayland_SetTextInputRect(_THIS, SDL_Rect *rect) if (driverdata->text_input_manager) { struct SDL_WaylandInput *input = driverdata->input; if (input != NULL && input->text_input) { - SDL_memcpy(&input->text_input->cursor_rect, rect, sizeof(SDL_Rect)); + SDL_copyp(&input->text_input->cursor_rect, rect); zwp_text_input_v3_set_cursor_rectangle(input->text_input->text_input, rect->x, rect->y,