[med-svn] [Git][med-team/htscodecs][upstream] New upstream version 1.5.2

Étienne Mollier (@emollier) gitlab at salsa.debian.org
Mon Oct 23 20:54:42 BST 2023



Étienne Mollier pushed to branch upstream at Debian Med / htscodecs


Commits:
d6a42009 by Étienne Mollier at 2023-10-23T20:50:29+02:00
New upstream version 1.5.2
- - - - -


18 changed files:

- .cirrus.yml
- NEWS.md
- configure.ac
- htscodecs/arith_dynamic.c
- htscodecs/c_range_coder.h
- htscodecs/fqzcomp_qual.c
- htscodecs/htscodecs.h
- htscodecs/rANS_static.c
- htscodecs/rANS_static16_int.h
- htscodecs/rANS_static32x16pr_avx2.c
- htscodecs/rANS_static32x16pr_sse4.c
- htscodecs/rANS_static4x16pr.c
- htscodecs/tokenise_name3.c
- htscodecs/varint.h
- tests/arith_dynamic_test.c
- tests/rANS_static4x16pr_test.c
- tests/rANS_static_test.c
- tests/tokenise_name3_test.c


Changes:

=====================================
.cirrus.yml
=====================================
@@ -156,7 +156,7 @@ task:
 task:
   name: freebsd
   freebsd_instance:
-    image_family: freebsd-13-1
+    image_family: freebsd-13-2
 
   pkginstall_script:
     - pkg update -f


=====================================
NEWS.md
=====================================
@@ -1,3 +1,65 @@
+Release 1.5.2: 6th October 2023
+-------------------------------
+
+*** SECURITY FIXES ***
+
+This release contains multiple bug fixes, including a couple
+buffer overruns that could corrupt memory when used in specific
+scenarios.  These have not been observed with real data, but could
+represent an attack vector for a malicious user.  (We know of no
+exploit.)
+
+
+Changes
+
+- The range coder has been extended to do bounds checking if the
+  new RC_SetOutputEnd() is called.  This has a small performance hit
+  for the encoder, depending on compiler, but tests showed within 10%
+  at worst.
+
+Bug fixes
+
+- Fix write-buffer overruns in fqzcomp and name tokeniser.
+
+  SECURITY ISSUE: FQZComp could overflow the computed maximum growth
+  size, causing writes beyond the ends of the allocated memory.  This
+  is triggered by many very small 1bp reads.  Fixed the maximum
+  bounds for compressed data.
+
+  SECURITY ISSUE: The name tokeniser using the maximum number of
+  tokens (128) would erroneously write a 129th token.  This is a
+  restricted overflow of a few bytes.
+
+  (PR#97, reported by Shubham Chandak)
+
+- Fix an maximum 8-byte read overflow in the AVX2 rans decoder.
+  SECURITY ISSUE: This was only present when using gcc.
+  (PR#100, reported by Rob Davies)
+
+- The rANS Order-1 SSE4 decoder could decode incorrectly.
+  When a single symbol only occurs and we're using 12-bit freqs, the
+  frequency of 4096 was interpreted as freq 0.  This only happens in
+  the non-SIMD tidy-up stage at the end of the decode, so at worst the
+  final 31 bytes may be incorrect. (PR#102)
+
+- Fixed a 1-byte heap read-buffer overflow. Existed since 6a87ead2
+  (Oct 2021).  Low severity security due to size and high likelihood
+  it's just malloc meta-data. (PR#95; OSS-Fuzz 62270)
+
+- rans_compress_4x16 now works on zero length input.
+  Previously this was giving divide-by-zero errors.
+  (PR#101, reported by Shubham Chandak)
+
+- Remove asserts which caused warnings about unused variables when
+  building with -DNDEBUG.
+
+- Fix ARM builds when HWCAP_ASIMD is missing (on Conda) (PR#91)
+
+- Improve FreeBSD CI testing
+
+- Fix undefined behaviour from signed bit-shifting (PR#90).
+
+
 Release 1.5.1: 19th July 2023
 -----------------------------
 


=====================================
configure.ac
=====================================
@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-AC_INIT(htscodecs, 1.5.1)
+AC_INIT(htscodecs, 1.5.2)
 
 # Some functions benefit from -O3 optimisation, so if the user didn't
 # explicitly set any compiler flags, we'll plump for O3.
@@ -61,7 +61,7 @@ AM_EXTRA_RECURSIVE_TARGETS([fuzz])
 #       libhtscodecs.so.1.1.0
 
 VERS_CURRENT=3
-VERS_REVISION=3
+VERS_REVISION=4
 VERS_AGE=1
 AC_SUBST(VERS_CURRENT)
 AC_SUBST(VERS_REVISION)


=====================================
htscodecs/arith_dynamic.c
=====================================
@@ -98,10 +98,11 @@ static
 unsigned char *arith_compress_O0(unsigned char *in, unsigned int in_size,
                                  unsigned char *out, unsigned int *out_size) {
     int i, bound = arith_compress_bound(in_size,0)-5; // -5 for order/size
+    unsigned char *out_free = NULL;
 
     if (!out) {
         *out_size = bound;
-        out = malloc(*out_size);
+        out_free = out = malloc(*out_size);
     }
     if (!out || bound > *out_size)
         return NULL;
@@ -118,12 +119,16 @@ unsigned char *arith_compress_O0(unsigned char *in, unsigned int in_size,
 
     RangeCoder rc;
     RC_SetOutput(&rc, (char *)out+1);
+    RC_SetOutputEnd(&rc, (char *)out + *out_size);
     RC_StartEncode(&rc);
 
     for (i = 0; i < in_size; i++)
         SIMPLE_MODEL(256, _encodeSymbol)(&byte_model, &rc, in[i]);
 
-    RC_FinishEncode(&rc);
+    if (RC_FinishEncode(&rc) < 0) {
+        free(out_free);
+        return NULL;
+    }
 
     // Finalise block size and return it
     *out_size = RC_OutSize(&rc)+1;
@@ -141,8 +146,9 @@ unsigned char *arith_uncompress_O0(unsigned char *in, unsigned int in_size,
     SIMPLE_MODEL(256,_) byte_model;
     SIMPLE_MODEL(256,_init)(&byte_model, m);
 
+    unsigned char *out_free = NULL;
     if (!out)
-        out = malloc(out_sz);
+        out_free = out = malloc(out_sz);
     if (!out)
         return NULL;
 
@@ -152,7 +158,10 @@ unsigned char *arith_uncompress_O0(unsigned char *in, unsigned int in_size,
     for (i = 0; i < out_sz; i++)
         out[i] = SIMPLE_MODEL(256, _decodeSymbol)(&byte_model, &rc);
 
-    RC_FinishDecode(&rc);
+    if (RC_FinishDecode(&rc) < 0) {
+        free(out_free);
+        return NULL;
+    }
     
     return out;
 }
@@ -192,6 +201,7 @@ unsigned char *arith_compress_O1(unsigned char *in, unsigned int in_size,
 
     RangeCoder rc;
     RC_SetOutput(&rc, (char *)out+1);
+    RC_SetOutputEnd(&rc, (char *)out + *out_size);
     RC_StartEncode(&rc);
 
     uint8_t last = 0;
@@ -200,7 +210,11 @@ unsigned char *arith_compress_O1(unsigned char *in, unsigned int in_size,
         last = in[i];
     }
 
-    RC_FinishEncode(&rc);
+    if (RC_FinishEncode(&rc) < 0) {
+        free(out_free);
+        htscodecs_tls_free(byte_model);
+        return NULL;
+    }
 
     // Finalise block size and return it
     *out_size = RC_OutSize(&rc)+1;
@@ -241,7 +255,11 @@ unsigned char *arith_uncompress_O1(unsigned char *in, unsigned int in_size,
         last = out[i];
     }
 
-    RC_FinishDecode(&rc);
+    if (RC_FinishDecode(&rc) < 0) {
+        htscodecs_tls_free(byte_model);
+        free(out_free);
+        return NULL;
+    }
     
     htscodecs_tls_free(byte_model);
     return out;
@@ -259,10 +277,11 @@ unsigned char *arith_compress_O2(unsigned char *in, unsigned int in_size,
 
     int i, j;
     int bound = arith_compress_bound(in_size,0)-5; // -5 for order/size
+    unsigned char *out_free = NULL;
 
     if (!out) {
         *out_size = bound;
-        out = malloc(*out_size);
+        out_free = out = malloc(*out_size);
     }
     if (!out || bound > *out_size)
         return NULL;
@@ -285,6 +304,7 @@ unsigned char *arith_compress_O2(unsigned char *in, unsigned int in_size,
 
     RangeCoder rc;
     RC_SetOutput(&rc, (char *)out+1);
+    RC_SetOutputEnd(&rc, (char *)out + *out_size);
     RC_StartEncode(&rc);
 
     unsigned char last1 = 0, last2 = 0;
@@ -295,7 +315,10 @@ unsigned char *arith_compress_O2(unsigned char *in, unsigned int in_size,
     }
 
     free(byte_model);
-    RC_FinishEncode(&rc);
+    if (RC_FinishEncode(&rc) < 0) {
+        free(out_free);
+        return NULL;
+    }
 
     // Finalise block size and return it
     *out_size = RC_OutSize(&rc)+1;
@@ -310,9 +333,10 @@ unsigned char *arith_compress_O2(unsigned char *in, unsigned int in_size,
     int i, j;
     int bound = arith_compress_bound(in_size,0)-5; // -5 for order/size
 
+    unsigned char *out_free = NULL;
     if (!out) {
         *out_size = bound;
-        out = malloc(*out_size);
+        out_free = out = malloc(*out_size);
     }
     if (!out || bound > *out_size)
         return NULL;
@@ -338,6 +362,7 @@ unsigned char *arith_compress_O2(unsigned char *in, unsigned int in_size,
 
     RangeCoder rc;
     RC_SetOutput(&rc, (char *)out+1);
+    RC_SetOutputEnd(&rc, (char *)out + *out_size);
     RC_StartEncode(&rc);
 
     unsigned char last1 = 0, last2 = 0;
@@ -355,7 +380,10 @@ unsigned char *arith_compress_O2(unsigned char *in, unsigned int in_size,
     }
 
     free(byte_model);
-    RC_FinishEncode(&rc);
+    if (RC_FinishEncode(&rc) < 0) {
+        free(out_free);
+        return NULL;
+    }
 
     // Finalise block size and return it
     *out_size = RC_OutSize(&rc)+1;
@@ -375,8 +403,9 @@ unsigned char *arith_uncompress_O2(unsigned char *in, unsigned int in_size,
         for (j = 0; j < 256; j++)
             SIMPLE_MODEL(256,_init)(&byte_model[i*256+j], m);
     
+    unsigned char *out_free = NULL;
     if (!out)
-        out = malloc(out_sz);
+        out_free = out = malloc(out_sz);
     if (!out)
         return NULL;
 
@@ -391,7 +420,10 @@ unsigned char *arith_uncompress_O2(unsigned char *in, unsigned int in_size,
     }
 
     free(byte_model);
-    RC_FinishDecode(&rc);
+    if (RC_FinishDecode(&rc) < 0) {
+        free(out_free);
+        return NULL;
+    }
     
     return out;
 }
@@ -440,6 +472,7 @@ unsigned char *arith_compress_O0_RLE(unsigned char *in, unsigned int in_size,
 
     RangeCoder rc;
     RC_SetOutput(&rc, (char *)out+1);
+    RC_SetOutputEnd(&rc, (char *)out + *out_size);
     RC_StartEncode(&rc);
 
     unsigned char last = 0;
@@ -466,7 +499,11 @@ unsigned char *arith_compress_O0_RLE(unsigned char *in, unsigned int in_size,
         } while (run);
     }
 
-    RC_FinishEncode(&rc);
+    if (RC_FinishEncode(&rc) < 0) {
+        htscodecs_tls_free(run_model);
+        free(out_free);
+        return NULL;
+    }
 
     // Finalise block size and return it
     *out_size = RC_OutSize(&rc)+1;
@@ -524,7 +561,11 @@ unsigned char *arith_uncompress_O0_RLE(unsigned char *in, unsigned int in_size,
             out[++i] = last;
     }
 
-    RC_FinishDecode(&rc);
+    if (RC_FinishDecode(&rc) < 0) {
+        htscodecs_tls_free(run_model);
+        free(out_free);
+        return NULL;
+    }
 
     htscodecs_tls_free(run_model);
     return out;
@@ -571,6 +612,7 @@ unsigned char *arith_compress_O1_RLE(unsigned char *in, unsigned int in_size,
 
     RangeCoder rc;
     RC_SetOutput(&rc, (char *)out+1);
+    RC_SetOutputEnd(&rc, (char *)out + *out_size);
     RC_StartEncode(&rc);
 
     unsigned char last = 0;
@@ -597,7 +639,12 @@ unsigned char *arith_compress_O1_RLE(unsigned char *in, unsigned int in_size,
         } while (run);
     }
 
-    RC_FinishEncode(&rc);
+    if (RC_FinishEncode(&rc) < 0) {
+        htscodecs_tls_free(byte_model);
+        htscodecs_tls_free(run_model);
+        free(out_free);
+        return NULL;
+    }
 
     // Finalise block size and return it
     *out_size = RC_OutSize(&rc)+1;
@@ -663,7 +710,12 @@ unsigned char *arith_uncompress_O1_RLE(unsigned char *in, unsigned int in_size,
             out[++i] = last;
     }
 
-    RC_FinishDecode(&rc);
+    if (RC_FinishDecode(&rc) < 0) {
+        htscodecs_tls_free(byte_model);
+        htscodecs_tls_free(run_model);
+        free(out_free);
+        return NULL;
+    }
 
     htscodecs_tls_free(byte_model);
     htscodecs_tls_free(run_model);


=====================================
htscodecs/c_range_coder.h
=====================================
@@ -31,13 +31,18 @@ typedef struct {
     uc *in_buf;
     uc *out_buf;
     uc *in_end;
+    uc *out_end;
+    int err;
 } RangeCoder;
 
 static inline void RC_SetInput(RangeCoder *rc, char *in, char *in_end) {
     rc->out_buf = rc->in_buf = (uc *)in;
     rc->in_end = (uc *)in_end;
 }
-static inline void RC_SetOutput(RangeCoder *rc, char *out) { rc->in_buf = rc->out_buf = (uc *)out; }
+
+// NB: call RC_SetOutput first, and then RC_SetOutputEnd
+static inline void RC_SetOutput(RangeCoder *rc, char *out) { rc->in_buf = rc->out_buf = (uc *)out; rc->out_end = NULL;}
+static inline void RC_SetOutputEnd(RangeCoder *rc, char *out_end) { rc->out_end = (uc *)out_end; }
 static inline char *RC_GetInput(RangeCoder *rc) { return (char *)rc->in_buf; }
 static inline char *RC_GetOutput(RangeCoder *rc) { return (char *)rc->out_buf; }
 static inline size_t RC_OutSize(RangeCoder *rc) { return rc->out_buf - rc->in_buf; }
@@ -51,6 +56,7 @@ static inline void RC_StartEncode(RangeCoder *rc)
     rc->Carry = 0;
     rc->Cache = 0;
     rc->code  = 0;
+    rc->err   = 0;
 }
 
 static inline void RC_StartDecode(RangeCoder *rc)
@@ -61,6 +67,7 @@ static inline void RC_StartDecode(RangeCoder *rc)
     rc->Carry = 0;
     rc->Cache = 0;
     rc->code  = 0;
+    rc->err   = 0;
     if (rc->in_buf+5 > rc->in_end) {
         rc->in_buf = rc->in_end; // prevent decode
         return;
@@ -68,6 +75,31 @@ static inline void RC_StartDecode(RangeCoder *rc)
     DO(5) rc->code = (rc->code<<8) | *rc->in_buf++;
 }
 
+static inline void RC_ShiftLowCheck(RangeCoder *rc) {
+    if (rc->low < Thres || rc->Carry) {
+        if (rc->out_end && rc->FFNum >= rc->out_end - rc->out_buf) {
+            rc->err = -1;
+            return;
+        }
+
+        *rc->out_buf++ = rc->Cache + rc->Carry;
+
+        // Flush any stored FFs
+        while (rc->FFNum) {
+            *rc->out_buf++ = rc->Carry-1; // (Carry-1)&255;
+            rc->FFNum--;
+        }
+
+        // Take copy of top byte ready for next flush
+        rc->Cache = rc->low >> 24;
+        rc->Carry = 0;
+    } else {
+        // Low if FFxx xxxx.  Bump FF count and shift in as before
+        rc->FFNum++;
+    }
+    rc->low = rc->low<<8;
+}
+
 static inline void RC_ShiftLow(RangeCoder *rc) {
     if (rc->low < Thres || rc->Carry) {
         *rc->out_buf++ = rc->Cache + rc->Carry;
@@ -88,12 +120,15 @@ static inline void RC_ShiftLow(RangeCoder *rc) {
     rc->low = rc->low<<8;
 }
 
-static inline void RC_FinishEncode(RangeCoder *rc) 
+static inline int RC_FinishEncode(RangeCoder *rc)
 { 
-    DO(5) RC_ShiftLow(rc);
+    DO(5) RC_ShiftLowCheck(rc);
+    return rc->err;
 }
 
-static inline void RC_FinishDecode(RangeCoder *rc) {}
+static inline int RC_FinishDecode(RangeCoder *rc) {
+    return rc->err;
+}
 
 static inline void RC_Encode (RangeCoder *rc, uint32_t cumFreq, uint32_t freq, uint32_t totFreq) 
 {
@@ -105,7 +140,7 @@ static inline void RC_Encode (RangeCoder *rc, uint32_t cumFreq, uint32_t freq, u
 
     while (rc->range < TOP) {
         rc->range <<= 8;
-        RC_ShiftLow(rc);
+        RC_ShiftLowCheck(rc);
     }
 }
 
@@ -119,8 +154,10 @@ static inline void RC_Decode (RangeCoder *rc, uint32_t cumFreq, uint32_t freq, u
     rc->code -= cumFreq * rc->range;
     rc->range *= freq;
     while (rc->range < TOP) {
-        if (rc->in_buf >= rc->in_end)
-            return; // FIXME: could signal error, instead of caller just generating nonsense
+        if (rc->in_buf >= rc->in_end) {
+            rc->err = -1;
+            return;
+        }
         rc->code = (rc->code<<8) + *rc->in_buf++;
         rc->range <<= 8;
     }


=====================================
htscodecs/fqzcomp_qual.c
=====================================
@@ -1018,11 +1018,6 @@ unsigned char *compress_block_fqz2f(int vers,
     int comp_idx = 0;
     RangeCoder rc;
 
-    unsigned char *comp = (unsigned char *)malloc(in_size*1.1+100000);
-    unsigned char *compe = comp + (size_t)(in_size*1.1+100000);
-    if (!comp)
-        return NULL;
-
     // Pick and store params
     if (!gp) {
         gp = &local_gp;
@@ -1031,6 +1026,36 @@ unsigned char *compress_block_fqz2f(int vers,
         free_params = 1;
     }
 
+    // Worst case scenario assuming random input data and no way to compress
+    // is NBytes*growth for some small growth factor (arith_dynamic uses 1.05),
+    // plus fixed overheads for the header / params.  Growth can be high
+    // here as we're modelling things and pathological cases may trigger a
+    // bad probability model.
+    //
+    // Per read is 4-byte len if not fixed length (but less if avg smaller)
+    //             up to 1 byte for selection state (log2(max_sel) bits)
+    //             1-bit for reverse flag
+    //             1-bit for dup-last flag (but then no quals)
+    // Per qual is 1-byte (assuming QMAX==256)
+    //
+    // Header size is total guess, as depends on params, but it's almost
+    // always tiny, so a few K extra should be sufficient.
+    //
+    // => Total of (s->num_records*4.25 + in_size)*growth + hdr
+    int sel_bits = 0, sel = gp->max_sel;
+    while (sel) {
+        sel_bits++;
+        sel >>= 1;
+    }
+    double len_sz = gp->p[0].fixed_len ? 0.25 : 4.25;
+    len_sz += sel_bits / 8.0;
+    size_t comp_sz = (s->num_records*len_sz + in_size)*1.1 + 10000;
+
+    unsigned char *comp = (unsigned char *)malloc(comp_sz);
+    unsigned char *compe = comp + (size_t)comp_sz;
+    if (!comp)
+        return NULL;
+
     //dump_params(gp);
     comp_idx = var_put_u32(comp, compe, in_size);
     comp_idx += fqz_store_parameters(gp, comp+comp_idx);
@@ -1054,6 +1079,7 @@ unsigned char *compress_block_fqz2f(int vers,
         return NULL;
 
     RC_SetOutput(&rc, (char *)comp+comp_idx);
+    RC_SetOutputEnd(&rc, (char *)comp+comp_sz);
     RC_StartEncode(&rc);
 
     // For CRAM3.1, reverse upfront if needed
@@ -1151,7 +1177,12 @@ unsigned char *compress_block_fqz2f(int vers,
 #endif
     }
 
-    RC_FinishEncode(&rc);
+    if (RC_FinishEncode(&rc) < 0) {
+        free(comp);
+        comp = NULL;
+        *out_size = 0;
+        goto err;
+    }
 
     // For CRAM3.1, undo our earlier reversal step
     rec = state.rec;
@@ -1186,6 +1217,7 @@ unsigned char *compress_block_fqz2f(int vers,
     *out_size = comp_idx + RC_OutSize(&rc);
     //fprintf(stderr, "%d -> %d\n", (int)in_size, (int)*out_size);
 
+ err:
     fqz_destroy_models(&model);
     if (free_params)
         fqz_free_parameters(gp);
@@ -1550,7 +1582,9 @@ unsigned char *uncompress_block_fqz2f(fqz_slice *s,
         }
     }
 
-    RC_FinishDecode(&rc);
+    if (RC_FinishDecode(&rc) < 0)
+        goto err;
+
     fqz_destroy_models(&model);
     free(rev_a);
     free(len_a);


=====================================
htscodecs/htscodecs.h
=====================================
@@ -43,7 +43,7 @@
  * Note currently this needs manually editing as it isn't automatically
  * updated by autoconf.
  */
-#define HTSCODECS_VERSION 100501
+#define HTSCODECS_VERSION 100502
 
 /*
  * A const string form of the HTSCODECS_VERSION define.


=====================================
htscodecs/rANS_static.c
=====================================
@@ -96,7 +96,7 @@ unsigned char *rans_compress_O0(unsigned char *in, unsigned int in_size,
         free(out_buf);
         return NULL;
     }
-    tr = ((uint64_t)TOTFREQ<<31)/in_size + (1<<30)/in_size;
+    tr = in_size ? ((uint64_t)TOTFREQ<<31)/in_size + (1<<30)/in_size : 0;
 
  normalise_harder:
     // Normalise so T[i] == TOTFREQ


=====================================
htscodecs/rANS_static16_int.h
=====================================
@@ -294,8 +294,6 @@ static inline int encode_freq_d(uint8_t *cp, uint32_t *F0, uint32_t *F) {
                 dz++;
                 *cp++ = 0;
             }
-        } else {
-            assert(F[j] == 0);
         }
     }
     
@@ -313,7 +311,7 @@ static inline int encode_freq_d(uint8_t *cp, uint32_t *F0, uint32_t *F) {
 // Returns the desired TF_SHIFT; 10 or 12 bit, or -1 on error.
 static inline int encode_freq1(uint8_t *in, uint32_t in_size, int Nway,
                                RansEncSymbol syms[256][256], uint8_t **cp_p) {
-    int tab_size = 0, i, j, z;
+    int i, j, z;
     uint8_t *out = *cp_p, *cp = out;
 
     // Compute O1 frequency statistics
@@ -413,9 +411,6 @@ static inline int encode_freq1(uint8_t *in, uint32_t in_size, int Nway,
         free(c_freq);
     }
 
-    tab_size = cp - out;
-    assert(tab_size < 257*257*3);
-
     *cp_p = cp;
     htscodecs_tls_free(F);
     return shift;


=====================================
htscodecs/rANS_static32x16pr_avx2.c
=====================================
@@ -526,7 +526,6 @@ unsigned char *rans_uncompress_O0_32x16_avx2(unsigned char *in,
         Rv2 = _mm256_add_epi32(
                   _mm256_mullo_epi32(
                       _mm256_srli_epi32(Rv2,TF_SHIFT), fv2), bv2);
-
 #ifdef __clang__
         // Protect against running off the end of in buffer.
         // We copy it to a worst-case local buffer when near the end.
@@ -649,6 +648,7 @@ unsigned char *rans_uncompress_O0_32x16_avx2(unsigned char *in,
         Yv3 = _mm256_or_si256(Yv3, Vv3);
         Vv4 = _mm256_permutevar8x32_epi32(Vv4, idx4);
         Yv4 = _mm256_or_si256(Yv4, Vv4);
+        sp += _mm_popcnt_u32(imask4);
 
 #ifndef __clang__
         // 26% faster here than above for gcc10, but former location is
@@ -663,8 +663,6 @@ unsigned char *rans_uncompress_O0_32x16_avx2(unsigned char *in,
         }
 #endif
 
-        sp += _mm_popcnt_u32(imask4);
-
         // R[z] = c ? Y[z] : R[z];
         Rv3 = _mm256_blendv_epi8(Rv3, Yv3, renorm_mask3);
         Rv4 = _mm256_blendv_epi8(Rv4, Yv4, renorm_mask4);


=====================================
htscodecs/rANS_static32x16pr_sse4.c
=====================================
@@ -1414,8 +1414,10 @@ unsigned char *rans_uncompress_O1_32x16_sse4(unsigned char *in,
             uint32_t S = s3[l[z]][m];
             unsigned char c = S & 0xff;
             out[i4[z]++] = c;
-            R[z] = (S>>(TF_SHIFT_O1+8)) * (R[z]>>TF_SHIFT_O1) +
-                ((S>>8) & ((1u<<TF_SHIFT_O1)-1));
+            int f = (S>>(TF_SHIFT_O1+8));
+            if (f == 0)
+                f = 4096;
+            R[z] = f * (R[z]>>TF_SHIFT_O1) + ((S>>8) & ((1u<<TF_SHIFT_O1)-1));
             RansDecRenormSafe(&R[z], &ptr, ptr_end);
             l[z] = c;
         }


=====================================
htscodecs/rANS_static4x16pr.c
=====================================
@@ -1018,7 +1018,7 @@ unsigned char *(*rans_dec_func(int do_simd, int order))
 static inline int have_neon() {
 #if defined(__linux__) && defined(__arm__)
     return (getauxval(AT_HWCAP) & HWCAP_NEON) != 0;
-#elif defined(__linux__) && defined(__aarch64__)
+#elif defined(__linux__) && defined(__aarch64__) && defined(HWCAP_ASIMD)
     return (getauxval(AT_HWCAP) & HWCAP_ASIMD) != 0;
 #elif defined(__APPLE__)
     return 1;
@@ -1026,7 +1026,7 @@ static inline int have_neon() {
     u_long cap;
     if (elf_aux_info(AT_HWCAP, &cap, sizeof cap) != 0) return 0;
     return (cap & HWCAP_NEON) != 0;
-#elif defined(__FreeBSD__) && defined(__aarch64__)
+#elif defined(__FreeBSD__) && defined(__aarch64__) && defined(HWCAP_ASIMD)
     u_long cap;
     if (elf_aux_info(AT_HWCAP, &cap, sizeof cap) != 0) return 0;
     return (cap & HWCAP_ASIMD) != 0;
@@ -1267,7 +1267,8 @@ unsigned char *rans_compress_to_4x16(unsigned char *in, unsigned int in_size,
         out[0] = RANS_ORDER_CAT;
         c_meta_len = 1;
         c_meta_len += var_put_u32(&out[1], out_end, in_size);
-        memcpy(out+c_meta_len, in, in_size);
+        if (in_size)
+            memcpy(out+c_meta_len, in, in_size);
         *out_size = c_meta_len + in_size;
         return out;
     }
@@ -1380,7 +1381,8 @@ unsigned char *rans_compress_to_4x16(unsigned char *in, unsigned int in_size,
     if (*out_size >= in_size) {
         out[0] &= ~3;
         out[0] |= RANS_ORDER_CAT | no_size;
-        memcpy(out+c_meta_len, in, in_size);
+        if (in_size)
+            memcpy(out+c_meta_len, in, in_size);
         *out_size = in_size;
     }
 


=====================================
htscodecs/tokenise_name3.c
=====================================
@@ -756,6 +756,8 @@ static int encode_name(name_context *ctx, char *name, int len, int mode) {
 
     for (; i < len; i++) {
         if (ntok >= ctx->max_tok) {
+            if (ctx->max_tok >= MAX_TOKENS)
+                return -1;
             memset(&ctx->desc[ctx->max_tok << 4], 0, 16*sizeof(ctx->desc[0]));
             memset(&ctx->token_dcount[ctx->max_tok], 0, sizeof(int));
             memset(&ctx->token_icount[ctx->max_tok], 0, sizeof(int));
@@ -968,6 +970,8 @@ static int encode_name(name_context *ctx, char *name, int len, int mode) {
     fprintf(stderr, "Tok %d (end)\n", N_END);
 #endif
     if (ntok >= ctx->max_tok) {
+        if (ctx->max_tok >= MAX_TOKENS)
+            return -1;
         memset(&ctx->desc[ctx->max_tok << 4], 0, 16*sizeof(ctx->desc[0]));
         memset(&ctx->token_dcount[ctx->max_tok], 0, sizeof(int));
         memset(&ctx->token_icount[ctx->max_tok], 0, sizeof(int));
@@ -1464,11 +1468,17 @@ uint8_t *tok3_encode_names(char *blk, int len, int level, int use_arith,
 
     // Encode name
     for (i = j = 0; i < len; j=++i) {
-        while (i < len && blk[i] > '\n')
+        while (i < len && (signed char)blk[i] >= ' ') // non-ASCII check
             i++;
         if (i >= len)
             break;
 
+        if (blk[i] != '\0' && blk[i] != '\n') {
+            // Names must be 7-bit ASCII printable
+            free_context(ctx);
+            return NULL;
+        }
+
         blk[i] = '\0';
         // try both 0 and 1 and pick best?
         if (encode_name(ctx, &blk[j], i-j, 1) < 0) {


=====================================
htscodecs/varint.h
=====================================
@@ -115,14 +115,14 @@ int var_put_u64(uint8_t *cp, const uint8_t *endp, uint64_t i) {
         *cp++ = ((i>> 7) & 0x7f) | 128;
         *cp++ =   i      & 0x7f;
         return 4;
-    } else if (i < (1LL<<35)) {
+    } else if (i < (1ULL<<35)) {
         *cp++ = ((i>>28) & 0x7f) | 128;
         *cp++ = ((i>>21) & 0x7f) | 128;
         *cp++ = ((i>>14) & 0x7f) | 128;
         *cp++ = ((i>> 7) & 0x7f) | 128;
         *cp++ =   i      & 0x7f;
         return 5;
-    } else if (i < (1LL<<42)) {
+    } else if (i < (1ULL<<42)) {
         *cp++ = ((i>>35) & 0x7f) | 128;
         *cp++ = ((i>>28) & 0x7f) | 128;
         *cp++ = ((i>>21) & 0x7f) | 128;
@@ -130,7 +130,7 @@ int var_put_u64(uint8_t *cp, const uint8_t *endp, uint64_t i) {
         *cp++ = ((i>> 7) & 0x7f) | 128;
         *cp++ =   i      & 0x7f;
         return 6;
-    } else if (i < (1LL<<49)) {
+    } else if (i < (1ULL<<49)) {
         *cp++ = ((i>>42) & 0x7f) | 128;
         *cp++ = ((i>>35) & 0x7f) | 128;
         *cp++ = ((i>>28) & 0x7f) | 128;
@@ -139,7 +139,7 @@ int var_put_u64(uint8_t *cp, const uint8_t *endp, uint64_t i) {
         *cp++ = ((i>> 7) & 0x7f) | 128;
         *cp++ =   i      & 0x7f;
         return 7;
-    } else if (i < (1LL<<56)) {
+    } else if (i < (1ULL<<56)) {
         *cp++ = ((i>>49) & 0x7f) | 128;
         *cp++ = ((i>>42) & 0x7f) | 128;
         *cp++ = ((i>>35) & 0x7f) | 128;
@@ -149,7 +149,7 @@ int var_put_u64(uint8_t *cp, const uint8_t *endp, uint64_t i) {
         *cp++ = ((i>> 7) & 0x7f) | 128;
         *cp++ =   i      & 0x7f;
         return 8;
-    } else if (i < (1LL<<63)) {
+    } else if (i < (1ULL<<63)) {
         *cp++ = ((i>>56) & 0x7f) | 128;
         *cp++ = ((i>>49) & 0x7f) | 128;
         *cp++ = ((i>>42) & 0x7f) | 128;
@@ -241,7 +241,7 @@ int var_get_u64(uint8_t *cp, const uint8_t *endp, uint64_t *i) {
     uint8_t *op = cp, c;
     uint64_t j = 0;
 
-    if (!endp || endp - cp >= 10) {
+    if (!endp || endp - cp >= 11) {
         int n = 10;
         do {
             c = *cp++;


=====================================
tests/arith_dynamic_test.c
=====================================
@@ -266,12 +266,13 @@ int main(int argc, char **argv) {
                 bytes += out_size;
             }
         } else {
-            for (;;) {
+            int loop = 0;
+            for (;;loop++) {
                 uint32_t in_size, out_size;
                 unsigned char *out;
 
                 in_size = fread(in_buf, 1, BLK_SIZE, infp);
-                if (in_size <= 0)
+                if (loop && in_size <= 0)
                     break;
 
                 if (in_size < 4)


=====================================
tests/rANS_static4x16pr_test.c
=====================================
@@ -309,12 +309,13 @@ int main(int argc, char **argv) {
                 bytes += out_size;
             }
         } else {
-            for (;;) {
+            int loop = 0;
+            for (;;loop++) {
                 uint32_t in_size, out_size;
                 unsigned char *out;
 
                 in_size = fread(in_buf, 1, blk_size, infp);
-                if (in_size <= 0)
+                if (loop && in_size <= 0)
                     break;
 
                 if (in_size < 4)


=====================================
tests/rANS_static_test.c
=====================================
@@ -259,12 +259,13 @@ int main(int argc, char **argv) {
                 bytes += out_size;
             }
         } else {
-            for (;;) {
+            int loop=0;
+            for (;;loop++) {
                 uint32_t in_size, out_size;
                 unsigned char *out;
 
                 in_size = fread(in_buf, 1, BLK_SIZE, infp);
-                if (in_size <= 0)
+                if (loop && in_size <= 0)
                     break;
 
                 out = rans_compress(in_buf, in_size, &out_size,


=====================================
tests/tokenise_name3_test.c
=====================================
@@ -146,6 +146,10 @@ static int encode(int argc, char **argv) {
             int out_len;
             uint8_t *out = tok3_encode_names(blk, len, level, use_arith,
                                              &out_len, &last_start);
+            if (!out) {
+                fprintf(stderr, "Couldn't encode names\n");
+                exit(1);
+            }
             if (write(1, &out_len, 4) < 4) exit(1);
             if (write(1, out, out_len) < out_len) exit(1);   // encoded data
             free(out);



View it on GitLab: https://salsa.debian.org/med-team/htscodecs/-/commit/d6a42009c114be20e2de3f72842e487310c7b1c8

-- 
View it on GitLab: https://salsa.debian.org/med-team/htscodecs/-/commit/d6a42009c114be20e2de3f72842e487310c7b1c8
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20231023/ea86737b/attachment-0001.htm>


More information about the debian-med-commit mailing list