When compiling xz_dec_stream.c with GCC (at least with versions 5.4.0
and 7.1.0), it complains thusly:

        In function 'dec_stream_footer':
        error: dereferencing type-punned pointer will break
              strict-aliasing rules [-Werror=strict-aliasing]
           if (xz_crc32(s->temp.buf + 4, 6, 0) != get_le32(s->temp.buf))
               ^~

Despite the arrow pointing to the xz_crc32() call, the actual problem is
the get_le32() macro expansion.

The thing is, the `buf` field was put just after two fields of type
size_t for the express purpose of avoiding alignment issues, as per the
comment above the `temp` struct.

Meaning: GCC gets this all wrong and should not complain.

An earlier attempt to fix (76b65624b (unxz: get_le32
macro is obviously wrong, 2017-08-07)) this by simply forcing
get_unaligned_32() (which is unnecessarily slow because it rebuilds a
32-bit int from accessing already-aligned bytes one by one) was a bit
heavy-handed.

But we can help GCC by turning the get_le32() macro into an inline
function. So let's do that, it also helps compile time safety by making
the code a little bit stricter.

Signed-off-by: Johannes Schindelin <johannes.schinde...@gmx.de>
---
Published-As: 
https://github.com/dscho/busybox-w32/releases/tag/busybox-type-punned-warning-v2
Fetch-It-Via: git fetch https://github.com/dscho/busybox-w32 
busybox-type-punned-warning-v2

Interdiff vs v1:
 diff --git a/archival/libarchive/decompress_unxz.c 
b/archival/libarchive/decompress_unxz.c
 index 0be85500c..e24cff98b 100644
 --- a/archival/libarchive/decompress_unxz.c
 +++ b/archival/libarchive/decompress_unxz.c
 @@ -37,6 +37,11 @@ static uint32_t xz_crc32(const uint8_t *buf, size_t size, 
uint32_t crc)
   || !defined(put_unaligned_be32)
  # error get_unaligned_le32 accessors are not defined
  #endif
 +static ALWAYS_INLINE uint32_t get_le32_fast(const void *p)
 +{
 +  return *(uint32_t *)p;
 +}
 +#define get_le32 get_le32_fast
  
  #include "unxz/xz_dec_bcj.c"
  #include "unxz/xz_dec_lzma2.c"
 diff --git a/archival/libarchive/unxz/xz_dec_stream.c 
b/archival/libarchive/unxz/xz_dec_stream.c
 index 8131ee30a..bf791055b 100644
 --- a/archival/libarchive/unxz/xz_dec_stream.c
 +++ b/archival/libarchive/unxz/xz_dec_stream.c
 @@ -423,15 +423,6 @@ static enum xz_ret XZ_FUNC dec_stream_footer(struct 
xz_dec *s)
        if (!memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE))
                return XZ_DATA_ERROR;
  
 -#if defined(__GNUC__)
 -      /*
 -       * The temp.buf field is put just after two fields of type size_t for
 -       * the express purpose of avoiding alignment issues. But GCC complains
 -       * about it nevertheless... so: shut GCC up for a few lines.
 -       */
 -#pragma GCC diagnostic push
 -#pragma GCC diagnostic ignored "-Wstrict-aliasing"
 -#endif
        if (xz_crc32(s->temp.buf + 4, 6, 0) != get_le32(s->temp.buf))
                return XZ_DATA_ERROR;
  
 @@ -442,9 +433,6 @@ static enum xz_ret XZ_FUNC dec_stream_footer(struct xz_dec 
*s)
         */
        if ((s->index.size >> 2) != get_le32(s->temp.buf + 4))
                return XZ_DATA_ERROR;
 -#if defined(__GNUC__)
 -#pragma GCC diagnostic pop
 -#endif
  
        if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->check_type)
                return XZ_DATA_ERROR;
 archival/libarchive/decompress_unxz.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/archival/libarchive/decompress_unxz.c 
b/archival/libarchive/decompress_unxz.c
index 0be85500c..e24cff98b 100644
--- a/archival/libarchive/decompress_unxz.c
+++ b/archival/libarchive/decompress_unxz.c
@@ -37,6 +37,11 @@ static uint32_t xz_crc32(const uint8_t *buf, size_t size, 
uint32_t crc)
  || !defined(put_unaligned_be32)
 # error get_unaligned_le32 accessors are not defined
 #endif
+static ALWAYS_INLINE uint32_t get_le32_fast(const void *p)
+{
+  return *(uint32_t *)p;
+}
+#define get_le32 get_le32_fast
 
 #include "unxz/xz_dec_bcj.c"
 #include "unxz/xz_dec_lzma2.c"

base-commit: a907b828d6e9f1357fc2e1db09d3eb1d3fb9b826
-- 
2.14.0.windows.1.2.g0f3342804fc
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to