From: Adam Stylinski Date: Tue, 25 Mar 2025 21:58:19 +0000 (-0400) Subject: Fix a bug on the 32k and greater chorba specializations X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=18b933b88ae3ed470321b2435ddfef0ca117c509;p=thirdparty%2Fzlib-ng.git Fix a bug on the 32k and greater chorba specializations In testing a SIMD vectorization for this, I wrote a gtest which stumbled onto the fact that this had a bug on big endian. Before the initial CRC had been mixed in it needed to be byte swapped. --- diff --git a/arch/generic/crc32_chorba_c.c b/arch/generic/crc32_chorba_c.c index 35f8d410..604e39f8 100644 --- a/arch/generic/crc32_chorba_c.c +++ b/arch/generic/crc32_chorba_c.c @@ -30,7 +30,12 @@ Z_INTERNAL uint32_t crc32_chorba_118960_nondestructive (uint32_t crc, const z_wo size_t i = 0; +#if BYTE_ORDER == LITTLE_ENDIAN z_word_t next1 = crc; +#else + z_word_t next1 = ZSWAP64(crc); +#endif + z_word_t next2 = 0; z_word_t next3 = 0; z_word_t next4 = 0; @@ -484,7 +489,12 @@ Z_INTERNAL uint32_t crc32_chorba_32768_nondestructive (uint32_t crc, const uint6 uint64_t bitbuffer[32768 / sizeof(uint64_t)]; const uint8_t* bitbufferbytes = (const uint8_t*) bitbuffer; memset(bitbuffer, 0, 32768); - bitbuffer[0] ^= crc; +#if BYTE_ORDER == LITTLE_ENDIAN + bitbuffer[0] = crc; +#else + bitbuffer[0] = ZSWAP64(crc); +#endif + crc = 0; size_t i = 0; @@ -634,9 +644,10 @@ Z_INTERNAL uint32_t crc32_chorba_32768_nondestructive (uint32_t crc, const uint6 uint8_t* final_bytes = (uint8_t*) final; - for(size_t j = 0; j < (len-i); j++) { + for (size_t j = 0; j < (len-i); j++) { crc = crc_table[(crc ^ final_bytes[j] ^ bitbufferbytes[(j+i)]) & 0xff] ^ (crc >> 8); } + return crc; } diff --git a/test/test_crc32.cc b/test/test_crc32.cc index d2eb44d3..ee301ef6 100644 --- a/test/test_crc32.cc +++ b/test/test_crc32.cc @@ -26,6 +26,19 @@ typedef struct { unsigned long expect; } crc32_test; +ALIGNED_(16) uint8_t fullwin_buf[32768]; + +uint8_t* setup_buf() { + for (int i = 0; i < 32768; ++i) { + unsigned char ic = (unsigned char)(i % 256); + fullwin_buf[i] = ic; + } + + return fullwin_buf; +} + +static uint8_t *buf32k = setup_buf(); + static const crc32_test tests[] = { {0x0, (const uint8_t *)0x0, 0, 0x0}, {0xffffffff, (const uint8_t *)0x0, 0, 0x0}, @@ -179,7 +192,8 @@ static const crc32_test tests[] = { "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" - "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 600, 0x888AFA5B} + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 600, 0x888AFA5B}, + {0x0, buf32k, 32768, 0x217726B2} }; class crc32_variant : public ::testing::TestWithParam {