summaryrefslogtreecommitdiffstats
path: root/options
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-09-13 01:26:26 +0200
committerwm4 <wm4@nowhere>2014-09-13 01:27:54 +0200
commitb5d253a5cb8c7759eacc708df1bfeac33b6f5c87 (patch)
tree8afd2f566e2c7060bcaef87497224ebb81cc54f5 /options
parent8bf57b8192a81a72dbd186e328f9f4b651ce8f6e (diff)
downloadmpv-b5d253a5cb8c7759eacc708df1bfeac33b6f5c87.tar.bz2
mpv-b5d253a5cb8c7759eacc708df1bfeac33b6f5c87.tar.xz
m_config: fix theoretic undefined behavior
The memcpy() is actually not enough: the types are incompatible, and no memcpy, union, etc. will change that. (Although no real compiler will ever break this.) Attempt to make this theoretically correct by actually using a struct pointer. It's not the same struct type, but supposedly it's ok, because all struct pointers always have the same size and representation in standard C.
Diffstat (limited to 'options')
-rw-r--r--options/m_config.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/options/m_config.c b/options/m_config.c
index 479c2e952b..14ae396d36 100644
--- a/options/m_config.c
+++ b/options/m_config.c
@@ -161,16 +161,19 @@ static int list_options(struct m_config *config)
// The memcpys are supposed to work around the strict aliasing violation,
// that would result if we just dereferenced a void** (where the void** is
-// actually casted from struct some_type* ).
+// actually casted from struct some_type* ). The dummy struct type is in
+// theory needed, because void* and struct pointers could have different
+// representations, while pointers to different struct types don't.
static void *substruct_read_ptr(const void *ptr)
{
- void *res;
- memcpy(&res, ptr, sizeof(void*));
+ struct mp_dummy_ *res;
+ memcpy(&res, ptr, sizeof(res));
return res;
}
static void substruct_write_ptr(void *ptr, void *val)
{
- memcpy(ptr, &val, sizeof(void*));
+ struct mp_dummy_ *src = val;
+ memcpy(ptr, &src, sizeof(src));
}
static void add_options(struct m_config *config,