diff options
author | wm4 <wm4@nowhere> | 2014-09-13 01:26:26 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-09-13 01:27:54 +0200 |
commit | b5d253a5cb8c7759eacc708df1bfeac33b6f5c87 (patch) | |
tree | 8afd2f566e2c7060bcaef87497224ebb81cc54f5 | |
parent | 8bf57b8192a81a72dbd186e328f9f4b651ce8f6e (diff) | |
download | mpv-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.
-rw-r--r-- | options/m_config.c | 11 |
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, |