XPost: linux.debian.ports.sparc   
   From: glaubitz@physik.fu-berlin.de   
      
   This is a multi-part MIME message sent by reportbug.   
      
      
   Source: zopfli   
   Version: 1.0.3-3   
   Severity: important   
   User: debian-sparc@lists.debian.org   
   Usertags: sparc64   
   X-Debbugs-Cc: debian-sparc@lists.debian.org   
      
   Hi,   
      
   there are some instances of unaligned access in zopfli that trigger Bus error   
   crashes on sparc64 when running the testsuite of python-zopfli on sparc64 [1].   
      
   The upstream of python-zopfli just fixed [2] the issue after I reported it [3].   
      
   I'm attaching the patch, please considers cherry-picking it.   
      
   Thanks,   
   Adrian   
      
   > [1] https://buildd.debian.org/status/fetch.php?pkg=python-zopf   
   i&arch=sparc64&ver=0.4.0-1&stamp=1762664749&raw=0   
   > [2] https://github.com/fonttools/py-zopfli/commit/f87d464d1df5   
   07d0035f559278421b125236fc5   
   > [3] https://github.com/fonttools/py-zopfli/issues/28   
      
   --   
    .''`. John Paul Adrian Glaubitz   
   : :' : Debian Developer   
   `. `' Physicist   
    `- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913   
      
   From cd7f13b12a2c1a50f94ffe9ca5909854bdef8d93 Mon Sep 17 00:00:00 2001   
   From: Cosimo Lupo    
   Date: Fri, 13 Feb 2026 11:57:17 +0000   
   Subject: [PATCH] Fix SIGBUS on strict-alignment architectures (SPARC, MIPS)   
      
   GetMatch() casts unsigned char* pointers to size_t* and unsigned int*   
   and dereferences them for word-at-a-time comparison. These pointers   
   can be at any byte offset, so the casts produce unaligned accesses   
   which cause SIGBUS on strict-alignment architectures (SPARC, MIPS64,   
   etc.) and are undefined behavior per the C standard.   
      
   Replace the direct pointer casts with memcpy into properly aligned   
   local variables. Modern compilers optimize memcpy of a known small   
   size into a single load instruction on architectures that support   
   unaligned access (x86), so there is no performance regression.   
      
   Fixes google/zopfli#22 (open since 2013).   
   Also fixes fonttools/py-zopfli#28.   
   ---   
    src/zopfli/lz77.c | 19 +++++++++++++++----   
    1 file changed, 15 insertions(+), 4 deletions(-)   
      
   diff --git a/src/zopfli/lz77.c b/src/zopfli/lz77.c   
   index 9df899dd..52a2bed1 100644   
   --- a/src/zopfli/lz77.c   
   +++ b/src/zopfli/lz77.c   
   @@ -24,6 +24,7 @@ Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)   
    #include    
    #include    
    #include    
   +#include    
      
    void ZopfliInitLZ77Store(const unsigned char* data, ZopfliLZ77Store* store) {   
    store->size = 0;   
   @@ -300,15 +301,25 @@ static const unsigned char* GetMatch(const unsigned   
   char* scan,   
    const unsigned char* safe_end) {   
      
    if (sizeof(size_t) == 8) {   
   - /* 8 checks at once per array bounds check (size_t is 64-bit). */   
   - while (scan < safe_end && *((size_t*)scan) == *((size_t*)match)) {   
   + /* 8 checks at once per array bounds check (size_t is 64-bit).   
   + Use memcpy to avoid unaligned access (causes SIGBUS on strict-alignment   
   + architectures like SPARC and MIPS). The compiler will optimize memcpy   
   of   
   + a known size into a single load where the architecture supports it. */   
   + size_t sv, mv;   
   + while (scan < safe_end) {   
   + memcpy(&sv, scan, sizeof(sv));   
   + memcpy(&mv, match, sizeof(mv));   
   + if (sv != mv) break;   
    scan += 8;   
    match += 8;   
    }   
    } else if (sizeof(unsigned int) == 4) {   
    /* 4 checks at once per array bounds check (unsigned int is 32-bit). */   
   - while (scan < safe_end   
   - && *((unsigned int*)scan) == *((unsigned int*)match)) {   
   + unsigned int sv, mv;   
   + while (scan < safe_end) {   
   + memcpy(&sv, scan, sizeof(sv));   
   + memcpy(&mv, match, sizeof(mv));   
   + if (sv != mv) break;   
    scan += 4;   
    match += 4;   
    }   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|