rbutil: Update embedded 'mspack' library from 0.10.1alpha to 0.11alpha

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]> Sat, 4 Jul 2026 21:56:05 -0400
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit a82396b0be56128db0be8cae34a47f980d4123d9
Author: Solomon Peachy <[email protected]>
Date:   Sat Jul 4 21:39:31 2026 -0400

    rbutil:  Update embedded 'mspack' library from 0.10.1alpha to 0.11alpha
    
    Change-Id: I37210d1dc2c5cecdf8256f9e0294dcbd8516e8c8

diff --git a/utils/rbutilqt/mspack/README.ROCKBOX b/utils/rbutilqt/mspack/README.ROCKBOX
index 220691af2c..d854566104 100644
--- a/utils/rbutilqt/mspack/README.ROCKBOX
+++ b/utils/rbutilqt/mspack/README.ROCKBOX
@@ -1,6 +1,6 @@
 This folder contains the mspack project for MS files compression/decompression.
 These files are distributed under the LGPL.
 
-The source files have been last synced with libmspack-0.10.1alpha
-https://www.cabextract.org.uk/libmspack/ on June 8, 2020
+The source files have been last synced with libmspack-0.11alpha
+https://www.cabextract.org.uk/libmspack/ released on Feb 5, 2023
 
diff --git a/utils/rbutilqt/mspack/cabd.c b/utils/rbutilqt/mspack/cabd.c
index ae66769b24..a3dc303d2c 100644
--- a/utils/rbutilqt/mspack/cabd.c
+++ b/utils/rbutilqt/mspack/cabd.c
@@ -1,5 +1,5 @@
 /* This file is part of libmspack.
- * (C) 2003-2018 Stuart Caie.
+ * (C) 2003-2023 Stuart Caie.
  *
  * libmspack is free software; you can redistribute it and/or modify it under
  * the terms of the GNU Lesser General Public License (LGPL) version 2.1
@@ -76,7 +76,8 @@ static int cabd_read_headers(
   struct mspack_system *sys, struct mspack_file *fh,
   struct mscabd_cabinet_p *cab, off_t offset, int salvage, int quiet);
 static char *cabd_read_string(
-  struct mspack_system *sys, struct mspack_file *fh, int *error);
+  struct mspack_system *sys, struct mspack_file *fh, int permit_empty,
+  int *error);
 
 static struct mscabd_cabinet *cabd_search(
   struct mscab_decompressor *base, const char *filename);
@@ -394,17 +395,17 @@ static int cabd_read_headers(struct mspack_system *sys,
 
   /* read name and info of preceeding cabinet in set, if present */
   if (cab->base.flags & cfheadPREV_CABINET) {
-    cab->base.prevname = cabd_read_string(sys, fh, &err);
+    cab->base.prevname = cabd_read_string(sys, fh, 0, &err);
     if (err) return err;
-    cab->base.previnfo = cabd_read_string(sys, fh, &err);
+    cab->base.previnfo = cabd_read_string(sys, fh, 1, &err);
     if (err) return err;
   }
 
   /* read name and info of next cabinet in set, if present */
   if (cab->base.flags & cfheadNEXT_CABINET) {
-    cab->base.nextname = cabd_read_string(sys, fh, &err);
+    cab->base.nextname = cabd_read_string(sys, fh, 0, &err);
     if (err) return err;
-    cab->base.nextinfo = cabd_read_string(sys, fh, &err);
+    cab->base.nextinfo = cabd_read_string(sys, fh, 1, &err);
     if (err) return err;
   }
 
@@ -508,7 +509,7 @@ static int cabd_read_headers(struct mspack_system *sys,
     file->date_y = (x >> 9) + 1980;
 
     /* get filename */
-    file->filename = cabd_read_string(sys, fh, &err);
+    file->filename = cabd_read_string(sys, fh, 0, &err);
 
     /* if folder index or filename are bad, either skip it or fail */
     if (err || !file->folder) {
@@ -535,7 +536,8 @@ static int cabd_read_headers(struct mspack_system *sys,
 }
 
 static char *cabd_read_string(struct mspack_system *sys,
-                              struct mspack_file *fh, int *error)
+                              struct mspack_file *fh, int permit_empty,
+                              int *error)
 {
   off_t base = sys->tell(fh);
   char buf[256], *str;
@@ -549,8 +551,8 @@ static char *cabd_read_string(struct mspack_system *sys,
 
   /* search for a null terminator in the buffer */
   for (i = 0, ok = 0; i < len; i++) if (!buf[i]) { ok = 1; break; }
-  /* reject empty strings */
-  if (i == 0) ok = 0;
+  /* optionally reject empty strings */
+  if (i == 0 && !permit_empty) ok = 0;
 
   if (!ok) {
     *error = MSPACK_ERR_DATAFORMAT;
@@ -651,10 +653,10 @@ static int cabd_find(struct mscab_decompressor_p *self, unsigned char *buf,
   unsigned int cablen_u32 = 0, foffset_u32 = 0;
   int false_cabs = 0;
 
-#if !LARGEFILE_SUPPORT
+#if SIZEOF_OFF_T < 8
   /* detect 32-bit off_t overflow */
   if (flen < 0) {
-    sys->message(fh, largefile_msg);
+    sys->message(fh, "library not compiled to support large files.");
     return MSPACK_ERR_OK;
   }
 #endif
@@ -753,10 +755,10 @@ static int cabd_find(struct mscab_decompressor_p *self, unsigned char *buf,
             /* cause the search to restart after this cab's data. */
             offset = caboff + (off_t) cablen_u32;
 
-#if !LARGEFILE_SUPPORT
+#if SIZEOF_OFF_T < 8
             /* detect 32-bit off_t overflow */
             if (offset < caboff) {
-              sys->message(fh, largefile_msg);
+              sys->message(fh, "library not compiled to support large files.");
               return MSPACK_ERR_OK;
             }
 #endif        
@@ -1012,7 +1014,7 @@ static int cabd_extract(struct mscab_decompressor *base,
   struct mscabd_folder_p *fol;
   struct mspack_system *sys;
   struct mspack_file *fh;
-  off_t filelen;
+  unsigned int filelen;
 
   if (!self) return MSPACK_ERR_ARGS;
   if (!file) return self->error = MSPACK_ERR_ARGS;
@@ -1029,7 +1031,7 @@ static int cabd_extract(struct mscab_decompressor *base,
    * or in salvage mode reduce file length so it fits 2GB limit
    */
   filelen = file->length;
-  if (filelen > CAB_LENGTHMAX || (file->offset + filelen) > CAB_LENGTHMAX) {
+  if (filelen > (CAB_LENGTHMAX - file->offset)) {
     if (self->salvage) {
       filelen = CAB_LENGTHMAX - file->offset;
     }
@@ -1049,8 +1051,8 @@ static int cabd_extract(struct mscab_decompressor *base,
    * In salvage mode, don't assume block sizes, just try decoding
    */
   if (!self->salvage) {
-    off_t maxlen = fol->base.num_blocks * CAB_BLOCKMAX;
-    if ((file->offset + filelen) > maxlen) {
+    unsigned int maxlen = fol->base.num_blocks * CAB_BLOCKMAX;
+    if (file->offset > maxlen || filelen > (maxlen - file->offset)) {
       sys->message(NULL, "ERROR; file \"%s\" cannot be extracted, "
                    "cabinet set is incomplete", file->filename);
       return self->error = MSPACK_ERR_DECRUNCH;
@@ -1398,7 +1400,7 @@ static unsigned int cabd_checksum(unsigned char *data, unsigned int bytes,
   unsigned int len, ul = 0;
 
   for (len = bytes >> 2; len--; data += 4) {
-    cksum ^= ((data[0]) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24));
+    cksum ^= EndGetI32(data);
   }
 
   switch (bytes & 3) {
diff --git a/utils/rbutilqt/mspack/chm.h b/utils/rbutilqt/mspack/chm.h
index 4b19f1505a..2642a82caf 100644
--- a/utils/rbutilqt/mspack/chm.h
+++ b/utils/rbutilqt/mspack/chm.h
@@ -1,5 +1,5 @@
 /* This file is part of libmspack.
- * (C) 2003-2004 Stuart Caie.
+ * (C) 2003-2023 Stuart Caie.
  *
  * libmspack is free software; you can redistribute it and/or modify it under
  * the terms of the GNU Lesser General Public License (LGPL) version 2.1
@@ -104,7 +104,8 @@ struct mschm_compressor_p {
 /* CHM decompression definitions */
 struct mschmd_decompress_state {
   struct mschmd_header *chm;         /* CHM file being decompressed          */
-  off_t offset;                      /* uncompressed offset within folder    */
+  off_t length;                      /* uncompressed length of LZX stream    */
+  off_t offset;                      /* uncompressed offset within stream    */
   off_t inoffset;                    /* offset in input file                 */
   struct lzxd_stream *state;         /* LZX decompressor state               */
   struct mspack_system sys;          /* special I/O code for decompressor    */
diff --git a/utils/rbutilqt/mspack/chmd.c b/utils/rbutilqt/mspack/chmd.c
index 6c8481db14..e860e95903 100644
--- a/utils/rbutilqt/mspack/chmd.c
+++ b/utils/rbutilqt/mspack/chmd.c
@@ -1,5 +1,5 @@
 /* This file is part of libmspack.
- * (C) 2003-2018 Stuart Caie.
+ * (C) 2003-2023 Stuart Caie.
  *
  * libmspack is free software; you can redistribute it and/or modify it under
  * the terms of the GNU Lesser General Public License (LGPL) version 2.1
@@ -58,6 +58,8 @@ static int chmd_error(
 static int read_off64(
   off_t *var, unsigned char *mem, struct mspack_system *sys,
   struct mspack_file *fh);
+static off_t read_encint(
+  const unsigned char **p, const unsigned char *end, int *err);
 
 /* filenames of the system files used for decompression.
  * Content and ControlData are essential.
@@ -249,24 +251,15 @@ static const unsigned char guids[32] = {
   0x9E, 0x0C, 0x00, 0xA0, 0xC9, 0x22, 0xE6, 0xEC
 };
 
-/* reads an encoded integer into a variable; 7 bits of data per byte,
- * the high bit is used to indicate that there is another byte */
-#define READ_ENCINT(var) do {                   \
-    (var) = 0;                                  \
-    do {                                        \
-        if (p >= end) goto chunk_end;           \
-        (var) = ((var) << 7) | (*p & 0x7F);     \
-    } while (*p++ & 0x80);                      \
-} while (0)
-
 static int chmd_read_headers(struct mspack_system *sys, struct mspack_file *fh,
                              struct mschmd_header *chm, int entire)
 {
-  unsigned int section, name_len, x, errors, num_chunks;
-  unsigned char buf[0x54], *chunk = NULL, *name, *p, *end;
+  unsigned int errors, num_chunks;
+  unsigned char buf[0x54], *chunk = NULL;
+  const unsigned char *name, *p, *end;
   struct mschmd_file *fi, *link = NULL;
-  off_t offset, length;
-  int num_entries;
+  off_t offset_hs0, filelen;
+  int num_entries, err = 0;
 
   /* initialise pointers */
   chm->files         = NULL;
@@ -312,7 +305,7 @@ static int chmd_read_headers(struct mspack_system *sys, struct mspack_file *fh,
   /* chmhst3_OffsetCS0 does not exist in version 1 or 2 CHM files.
    * The offset will be corrected later, once HS1 is read.
    */
-  if (read_off64(&offset,           &buf[chmhst_OffsetHS0],  sys, fh) ||
+  if (read_off64(&offset_hs0,       &buf[chmhst_OffsetHS0],  sys, fh) ||
       read_off64(&chm->dir_offset,  &buf[chmhst_OffsetHS1],  sys, fh) ||
       read_off64(&chm->sec0.offset, &buf[chmhst3_OffsetCS0], sys, fh))
   {
@@ -320,7 +313,7 @@ static int chmd_read_headers(struct mspack_system *sys, struct mspack_file *fh,
   }
 
   /* seek to header section 0 */
-  if (sys->seek(fh, offset, MSPACK_SYS_SEEK_START)) {
+  if (sys->seek(fh, offset_hs0, MSPACK_SYS_SEEK_START)) {
     return MSPACK_ERR_SEEK;
   }
 
@@ -332,6 +325,18 @@ static int chmd_read_headers(struct mspack_system *sys, struct mspack_file *fh,
     return MSPACK_ERR_DATAFORMAT;
   }
 
+  /* compare declared CHM file size against actual size */
+  if (!mspack_sys_filelen(sys, fh, &filelen)) {
+    if (chm->length > filelen) {
+      sys->message(fh, "WARNING; file possibly truncated by %" LD " bytes",
+                   chm->length - filelen);
+    }
+    else if (chm->length < filelen) {
+      sys->message(fh, "WARNING; possible %" LD " extra bytes at end of file",
+                   filelen - chm->length);
+    }
+  }
+
   /* seek to header section 1 */
   if (sys->seek(fh, chm->dir_offset, MSPACK_SYS_SEEK_START)) {
     return MSPACK_ERR_SEEK;
@@ -412,12 +417,13 @@ static int chmd_read_headers(struct mspack_system *sys, struct mspack_file *fh,
   }
 
   /* seek to the first PMGL chunk, and reduce the number of chunks to read */
-  if ((x = chm->first_pmgl) != 0) {
-    if (sys->seek(fh,(off_t) (x * chm->chunk_size), MSPACK_SYS_SEEK_CUR)) {
+  if (chm->first_pmgl != 0) {
+    off_t pmgl_offset = (off_t) chm->first_pmgl * (off_t) chm->chunk_size;
+    if (sys->seek(fh, pmgl_offset, MSPACK_SYS_SEEK_CUR)) {
       return MSPACK_ERR_SEEK;
     }
   }
-  num_chunks = chm->last_pmgl - x + 1;
+  num_chunks = chm->last_pmgl - chm->first_pmgl + 1;
 
   if (!(chunk = (unsigned char *) sys->alloc(sys, (size_t)chm->chunk_size))) {
     return MSPACK_ERR_NOMEMORY;
@@ -449,12 +455,15 @@ static int chmd_read_headers(struct mspack_system *sys, struct mspack_file *fh,
     num_entries = EndGetI16(end);
 
     while (num_entries--) {
-      READ_ENCINT(name_len);
-      if (name_len > (unsigned int) (end - p)) goto chunk_end;
+      unsigned int name_len, section;
+      off_t offset, length;
+      name_len = read_encint(&p, end, &err);
+      if (err || (name_len > (unsigned int) (end - p))) goto encint_err;
       name = p; p += name_len;
-      READ_ENCINT(section);
-      READ_ENCINT(offset);
-      READ_ENCINT(length);
+      section = read_encint(&p, end, &err);
+      offset = read_encint(&p, end, &err);
+      length = read_encint(&p, end, &err);
+      if (err) goto encint_err;
 
       /* ignore blank or one-char (e.g. "/") filenames we'd return as blank */
       if (name_len < 2 || !name[0] || !name[1]) continue;
@@ -482,7 +491,7 @@ static int chmd_read_headers(struct mspack_system *sys, struct mspack_file *fh,
                                      : (struct mschmd_section *) (&chm->sec1));
       fi->offset   = offset;
       fi->length   = length;
-      sys->copy(name, fi->filename, (size_t) name_len);
+      sys->copy((unsigned char *) name, fi->filename, (size_t) name_len);
       fi->filename[name_len] = '\0';
 
       if (name[0] == ':' && name[1] == ':') {
@@ -510,10 +519,10 @@ static int chmd_read_headers(struct mspack_system *sys, struct mspack_file *fh,
     }
 
     /* this is reached either when num_entries runs out, or if
-     * reading data from the chunk reached a premature end of chunk */
-  chunk_end:
+     * an ENCINT is badly encoded */
+  encint_err:
     if (num_entries >= 0) {
-      D(("chunk ended before all entries could be read"))
+      D(("bad encint before all entries could be read"))
       errors++;
     }
 
@@ -572,7 +581,10 @@ static int chmd_fast_find(struct mschm_decompressor *base,
             }
 
             /* found result. loop around for next chunk if this is PMGI */
-            if (chunk[3] == 0x4C) break; else READ_ENCINT(n);
+            if (chunk[3] == 0x4C) break;
+
+            n = read_encint(&p, end, &err);
+            if (err) goto encint_err;
         }
     }
     else {
@@ -599,11 +611,12 @@ static int chmd_fast_find(struct mschm_decompressor *base,
 
     /* if we found a file, read it */
     if (result > 0) {
-        READ_ENCINT(sec);
+        sec = read_encint(&p, end, &err);
         f_ptr->section  = (sec == 0) ? (struct mschmd_section *) &chm->sec0
                                      : (struct mschmd_section *) &chm->sec1;
-        READ_ENCINT(f_ptr->offset);
-        READ_ENCINT(f_ptr->length);
+        f_ptr->offset = read_encint(&p, end, &err);
+        f_ptr->length = read_encint(&p, end, &err);
+        if (err) goto encint_err;
     }
     else if (result < 0) {
         err = MSPACK_ERR_DATAFORMAT;
@@ -612,8 +625,8 @@ static int chmd_fast_find(struct mschm_decompressor *base,
     sys->close(fh);
     return self->error = err;
 
- chunk_end:
-    D(("read beyond end of chunk entries"))
+ encint_err:
+    D(("bad encint in PGMI/PGML chunk"))
     sys->close(fh);
     return self->error = MSPACK_ERR_DATAFORMAT;
 }
@@ -697,7 +710,7 @@ static int search_chunk(struct mschmd_header *chm,
     const unsigned char *start, *end, *p;
     unsigned int qr_size, num_entries, qr_entries, qr_density, name_len;
     unsigned int L, R, M, fname_len, entries_off, is_pmgl;
-    int cmp;
+    int cmp, err = 0;
 
     fname_len = strlen(filename);
 
@@ -755,8 +768,8 @@ static int search_chunk(struct mschmd_header *chm,
 
             /* compare filename with entry QR points to */
             p = &chunk[entries_off + (M ? EndGetI16(start - (M << 1)) : 0)];
-            READ_ENCINT(name_len);
-            if (name_len > (unsigned int) (end - p)) goto chunk_end;
+            name_len = read_encint(&p, end, &err);
+            if (err || (name_len > (unsigned int) (end - p))) goto encint_err;
             cmp = compare(filename, (char *)p, fname_len, name_len);
 
             if (cmp == 0) break;
@@ -792,8 +805,8 @@ static int search_chunk(struct mschmd_header *chm,
      */
     *result = NULL;
     while (num_entries-- > 0) {
-        READ_ENCINT(name_len);
-        if (name_len > (unsigned int) (end - p)) goto chunk_end;
+        name_len = read_encint(&p, end, &err);
+        if (err || (name_len > (unsigned int) (end - p))) goto encint_err;
         cmp = compare(filename, (char *)p, fname_len, name_len);
         p += name_len;
 
@@ -810,21 +823,21 @@ static int search_chunk(struct mschmd_header *chm,
 
         /* read and ignore the rest of this entry */
         if (is_pmgl) {
-            READ_ENCINT(R); /* skip section */
-            READ_ENCINT(R); /* skip offset */
-            READ_ENCINT(R); /* skip length */
+            while (p < end && (*p++ & 0x80)); /* skip section ENCINT */
+            while (p < end && (*p++ & 0x80)); /* skip offset ENCINT */
+            while (p < end && (*p++ & 0x80)); /* skip length ENCINT */
         }
         else {
             *result = p; /* store potential final result */
-            READ_ENCINT(R); /* skip chunk number */
+            while (p < end && (*p++ & 0x80)); /* skip chunk number ENCINT */
         }
     }
 
      /* PMGL? not found. PMGI? maybe found */
      return (is_pmgl) ? 0 : (*result ? 1 : 0);
 
- chunk_end:
-    D(("reached end of chunk data while searching"))
+ encint_err:
+    D(("bad encint while searching"))
     return -1;
 }
 
@@ -938,14 +951,19 @@ static int chmd_extract(struct mschm_decompressor *base,
   switch (file->section->id) {
   case 0: /* Uncompressed section file */
     /* simple seek + copy */
-    if (sys->seek(self->d->infh, file->section->chm->sec0.offset
-                  + file->offset, MSPACK_SYS_SEEK_START))
+    if (sys->seek(self->d->infh, chm->sec0.offset + file->offset,
+                  MSPACK_SYS_SEEK_START))
     {
       self->error = MSPACK_ERR_SEEK;
     }
     else {
       unsigned char buf[512];
       off_t length = file->length;
+      off_t maxlen = chm->length - sys->tell(self->d->infh);
+      if (length > maxlen) {
+        sys->message(fh, "WARNING; file is %" LD " bytes longer than CHM file",
+                     length - maxlen);
+      }
       while (length > 0) {
         int run = sizeof(buf);
         if ((off_t)run > length) run = (int)length;
@@ -963,7 +981,7 @@ static int chmd_extract(struct mschm_decompressor *base,
     break;
 
   case 1: /* MSCompressed section file */
-    /* (re)initialise compression state if we it is not yet initialised,
+    /* (re)initialise compression state if not yet initialised,
      * or we have advanced too far and have to backtrack
      */
     if (!self->d->state || (file->offset < self->d->offset)) {
@@ -974,6 +992,12 @@ static int chmd_extract(struct mschm_decompressor *base,
       if (chmd_init_decomp(self, file)) break;
     }
 
+    /* check file offset is not impossible */
+    if (file->offset > self->d->length) {
+        self->error = MSPACK_ERR_DECRUNCH;
+        break;
+    }
+
     /* seek to input data */
     if (sys->seek(self->d->infh, self->d->inoffset, MSPACK_SYS_SEEK_START)) {
       self->error = MSPACK_ERR_SEEK;
@@ -988,8 +1012,15 @@ static int chmd_extract(struct mschm_decompressor *base,
 
     /* if getting to the correct offset was error free, unpack file */
     if (!self->error) {
+      off_t length = file->length;
+      off_t maxlen = self->d->length - file->offset;
+      if (length > maxlen) {
+        sys->message(fh, "WARNING; file is %" LD " bytes longer than "
+                     "compressed section", length - maxlen);
+        length = maxlen + 1; /* should decompress but still error out */
+      }
       self->d->outfh = fh;
-      self->error = lzxd_decompress(self->d->state, file->length);
+      self->error = lzxd_decompress(self->d->state, length);
     }
 
     /* save offset in input source stream, in case there is a section 0
@@ -1052,8 +1083,8 @@ static int chmd_init_decomp(struct mschm_decompressor_p *self,
   if (err) return self->error = err;
 
   /* read ControlData */
-  if (sec->control->length < lzxcd_SIZEOF) {
-    D(("ControlData file is too short"))
+  if (sec->control->length != lzxcd_SIZEOF) {
+    D(("ControlData file is wrong size"))
     return self->error = MSPACK_ERR_DATAFORMAT;
   }
   if (!(data = read_sys_file(self, sec->control))) {
@@ -1125,8 +1156,8 @@ static int chmd_init_decomp(struct mschm_decompressor_p *self,
     entry = 0;
     offset = 0;
     err = read_spaninfo(self, sec, &length);
+    if (err) return self->error = err;
   }
-  if (err) return self->error = err;
 
   /* get offset of compressed data stream:
    * = offset of uncompressed section from start of file
@@ -1136,6 +1167,7 @@ static int chmd_init_decomp(struct mschm_decompressor_p *self,
 
   /* set start offset and overall remaining stream length */
   self->d->offset = entry * LZX_FRAME_SIZE;
+  self->d->length = length;
   length -= self->d->offset;
 
   /* initialise LZX stream */
@@ -1172,6 +1204,11 @@ static int read_reset_table(struct mschm_decompressor_p *self,
         D(("ResetTable file is too short"))
         return 0;
     }
+    if (sec->rtable->length > 1000000) { /* arbitrary upper limit */
+        D(("ResetTable >1MB (%"LD"), report if genuine", sec->rtable->length))
+        return 0;
+    }
+
     if (!(data = read_sys_file(self, sec->rtable))) {
         D(("can't read reset table"))
         return 0;
@@ -1246,6 +1283,12 @@ static int read_spaninfo(struct mschm_decompressor_p *self,
         return MSPACK_ERR_DATAFORMAT;
     }
 
+    /* unconditionally set length here, because gcc -Wuninitialized isn't
+     * clever enough to recognise that read_sys_file() will always set
+     * self->error to a non-zero value if it returns NULL, and gcc warnings
+     * spook humans (even false positives) */
+    *length_ptr = 0;
+
     /* read the SpanInfo file */
     if (!(data = read_sys_file(self, sec->spaninfo))) {
         D(("can't read SpanInfo file"))
@@ -1364,14 +1407,51 @@ static int chmd_error(struct mschm_decompressor *base) {
 static int read_off64(off_t *var, unsigned char *mem,
                       struct mspack_system *sys, struct mspack_file *fh)
 {
-#if LARGEFILE_SUPPORT
+#if SIZEOF_OFF_T >= 8
     *var = EndGetI64(mem);
 #else
-    *var = EndGetI32(mem);
-    if ((*var & 0x80000000) || EndGetI32(mem+4)) {
-        sys->message(fh, (char *)largefile_msg);
+    if ((mem[3] & 0x80) | mem[4] | mem[5] | mem[6] | mem[7]) {
+        sys->message(fh, "library not compiled to support large files.");
         return 1;
     }
+    *var = EndGetI32(mem);
 #endif
     return 0;
 }
+
+#if SIZEOF_OFF_T >= 8
+  /* 63 bits allowed: 9 * 7 bits/byte, last byte must be 0x00-0x7F */
+# define ENCINT_MAX_BYTES 9
+# define ENCINT_BAD_LAST_BYTE 0x80
+#else
+  /* 31 bits allowed: 5 * 7 bits/byte, last byte must be 0x00-0x07 */
+# define ENCINT_MAX_BYTES 5
+# define ENCINT_BAD_LAST_BYTE 0xF1
+#endif
+
+/***************************************
+ * READ_ENCINT
+ ***************************************
+ * Reads an ENCINT from memory. If running on a system with a 32-bit off_t,
+ * ENCINTs up to 0x7FFFFFFF are accepted, values beyond that are an error.
+ */
+static off_t read_encint(const unsigned char **p, const unsigned char *end,
+                         int *err)
+{
+    off_t result = 0;
+    unsigned char c = 0x80;
+    int i = 0;
+    while ((c & 0x80) && (i++ < ENCINT_MAX_BYTES)) {
+        if (*p >= end) {
+            *err = 1;
+            return 0;
+        }
+        c = *(*p)++;
+        result = (result << 7) | (c & 0x7F);
+    }
+    if (i == ENCINT_MAX_BYTES && (c & ENCINT_BAD_LAST_BYTE)) {
+        *err = 1;
+        return 0;
+    }
+    return result;
+}
diff --git a/utils/rbutilqt/mspack/kwajd.c b/utils/rbutilqt/mspack/kwajd.c
index 24e0b0613b..2f40508fa7 100644
--- a/utils/rbutilqt/mspack/kwajd.c
+++ b/utils/rbutilqt/mspack/kwajd.c
@@ -1,5 +1,5 @@
 /* This file is part of libmspack.
- * (C) 2003-2011 Stuart Caie.
+ * (C) 2003-2023 Stuart Caie.
  *
  * KWAJ is a format very similar to SZDD. KWAJ method 3 (LZH) was
  * written by Jeff Johnson.
@@ -97,27 +97,30 @@ static struct mskwajd_header *kwajd_open(struct mskwaj_decompressor *base,
     struct mskwajd_header *hdr;
     struct mspack_system *sys;
     struct mspack_file *fh;
+    int err;
 
     if (!self) return NULL;
     sys = self->system;
 
-    fh  = sys->open(sys, filename, MSPACK_SYS_OPEN_READ);
-    hdr = (struct mskwajd_header *) sys->alloc(sys, sizeof(struct mskwajd_header_p));
-    if (fh && hdr) {
-        ((struct mskwajd_header_p *) hdr)->fh = fh;
-        self->error = kwajd_read_headers(sys, fh, hdr);
-    }
-    else {
-        if (!fh)  self->error = MSPACK_ERR_OPEN;
-        if (!hdr) self->error = MSPACK_ERR_NOMEMORY;
+    fh = sys->open(sys, filename, MSPACK_SYS_OPEN_READ);
+    if (!fh) {
+        self->error = MSPACK_ERR_OPEN;
+        return NULL;
     }
-    
-    if (self->error) {
-        if (fh) sys->close(fh);
-        sys->free(hdr);
-        hdr = NULL;
+
+    hdr = (struct mskwajd_header *) sys->alloc(sys, sizeof(struct mskwajd_header_p));
+    if (!hdr) {
+        sys->close(fh);
+        self->error = MSPACK_ERR_NOMEMORY;
+        return NULL;
     }
 
+    ((struct mskwajd_header_p *) hdr)->fh = fh;
+    if ((err = kwajd_read_headers(sys, fh, hdr))) {
+        kwajd_close(base, hdr);
+        self->error = err;
+        return NULL;
+    }
     return hdr;
 }
 
@@ -138,6 +141,8 @@ static void kwajd_close(struct mskwaj_decompressor *base,
     self->system->close(hdr_p->fh);
 
     /* free the memory associated */
+    self->system->free(hdr->filename);
+    self->system->free(hdr->extra);
     self->system->free(hdr);
 
     self->error = MSPACK_ERR_OK;
@@ -200,7 +205,7 @@ static int kwajd_read_headers(struct mspack_system *sys,
     if (hdr->headers & (MSKWAJ_HDR_HASFILENAME | MSKWAJ_HDR_HASFILEEXT)) {
         int len;
         /* allocate memory for maximum length filename */
-        char *fn = (char *) sys->alloc(sys, (size_t) 13);
+        char *fn = (char *) sys->alloc(sys, 13);
         if (!(hdr->filename = fn)) return MSPACK_ERR_NOMEMORY;
 
         /* copy filename if present */
@@ -236,7 +241,7 @@ static int kwajd_read_headers(struct mspack_system *sys,
     if (hdr->headers & MSKWAJ_HDR_HASEXTRATEXT) {
         if (sys->read(fh, &buf[0], 2) != 2) return MSPACK_ERR_READ;
         i = EndGetI16(&buf[0]);
-        hdr->extra = (char *) sys->alloc(sys, (size_t)i+1);
+        hdr->extra = (char *) sys->alloc(sys, i+1);
         if (! hdr->extra) return MSPACK_ERR_NOMEMORY;
         if (sys->read(fh, hdr->extra, i) != i) return MSPACK_ERR_READ;
         hdr->extra[i] = '\0';
@@ -280,7 +285,7 @@ static int kwajd_extract(struct mskwaj_decompressor *base,
         hdr->comp_type == MSKWAJ_COMP_XOR)
     {
         /* NONE is a straight copy. XOR is a copy xored with 0xFF */
-        unsigned char *buf = (unsigned char *) sys->alloc(sys, (size_t) KWAJ_INPUT_SIZE);
+        unsigned char *buf = (unsigned char *) sys->alloc(sys, KWAJ_INPUT_SIZE);
         if (buf) {
             int read, i;
             while ((read = sys->read(fh, buf, KWAJ_INPUT_SIZE)) > 0) {
@@ -301,7 +306,7 @@ static int kwajd_extract(struct mskwaj_decompressor *base,
     }
     else if (hdr->comp_type == MSKWAJ_COMP_SZDD) {
         self->error = lzss_decompress(sys, fh, outfh, KWAJ_INPUT_SIZE,
-                                      LZSS_MODE_EXPAND);
+                                      LZSS_MODE_QBASIC);
     }
     else if (hdr->comp_type == MSKWAJ_COMP_LZH) {
         struct kwajd_stream *lzh = lzh_init(sys, fh, outfh);
@@ -435,17 +440,14 @@ static struct kwajd_stream *lzh_init(struct mspack_system *sys,
 
 static int lzh_decompress(struct kwajd_stream *lzh)
 {
-    register unsigned int bit_buffer;
-    register int bits_left, i;
-    register unsigned short sym;
-    unsigned char *i_ptr, *i_end, lit_run = 0;
-    int j, pos = 0, len, offset, err;
-    unsigned int types[6];
+    DECLARE_HUFF_VARS;
+    unsigned int types[6], i, j, pos = 0, len, offset, lit_run = 0;
+    int err;
 
     /* reset global state */
     INIT_BITS;
     RESTORE_BITS;
-    memset(&lzh->window[0], LZSS_WINDOW_FILL, (size_t) LZSS_WINDOW_SIZE);
+    memset(&lzh->window[0], LZSS_WINDOW_FILL, LZSS_WINDOW_SIZE);
 
     /* read 6 encoding types (for byte alignment) but only 5 are needed */
     for (i = 0; i < 6; i++) READ_BITS_SAFE(types[i], 4);
@@ -501,9 +503,7 @@ static int lzh_read_lens(struct kwajd_stream *lzh,
                          unsigned int type, unsigned int numsyms,
                          unsigned char *lens)
 {
-    register unsigned int bit_buffer;
-    register int bits_left;
-    unsigned char *i_ptr, *i_end;
+    DECLARE_BIT_VARS;
     unsigned int i, c, sel;
     int err;
 
diff --git a/utils/rbutilqt/mspack/lzx.h b/utils/rbutilqt/mspack/lzx.h
index a6152f622b..281fe5f0fb 100644
--- a/utils/rbutilqt/mspack/lzx.h
+++ b/utils/rbutilqt/mspack/lzx.h
@@ -67,7 +67,6 @@ struct lzxd_stream {
   unsigned int   block_remaining; /* uncompressed bytes still left to decode */
 
   signed int     intel_filesize;  /* magic header value used for transform   */
-  signed int     intel_curpos;    /* current offset in transform space       */
 
   unsigned char  intel_started;   /* has intel E8 decoding started?          */
   unsigned char  block_type;      /* type of the current block               */
diff --git a/utils/rbutilqt/mspack/lzxd.c b/utils/rbutilqt/mspack/lzxd.c
index 88cfd90c2a..565d5f08e9 100644
--- a/utils/rbutilqt/mspack/lzxd.c
+++ b/utils/rbutilqt/mspack/lzxd.c
@@ -1,5 +1,5 @@
 /* This file is part of libmspack.
- * (C) 2003-2013 Stuart Caie.
+ * (C) 2003-2023 Stuart Caie.
  *
  * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted
  * by Microsoft Corporation.
@@ -138,12 +138,7 @@
 static int lzxd_read_lens(struct lzxd_stream *lzx, unsigned char *lens,
                           unsigned int first, unsigned int last)
 {
-  /* bit buffer and huffman symbol decode variables */
-  register unsigned int bit_buffer;
-  register int bits_left, i;
-  register unsigned short sym;
-  unsigned char *i_ptr, *i_end;
-
+  DECLARE_HUFF_VARS;
   unsigned int x, y;
   int z;
 
@@ -315,8 +310,8 @@ struct lzxd_stream *lzxd_init(struct mspack_system *system,
   }
 
   /* allocate decompression window and input buffer */
-  lzx->window = (unsigned char *) system->alloc(system, (size_t) window_size);
-  lzx->inbuf  = (unsigned char *) system->alloc(system, (size_t) input_buffer_size);
+  lzx->window = (unsigned char *) system->alloc(system, window_size);
+  lzx->inbuf  = (unsigned char *) system->alloc(system, input_buffer_size);
   if (!lzx->window || !lzx->inbuf) {
     system->free(lzx->window);
     system->free(lzx->inbuf);
@@ -339,7 +334,6 @@ struct lzxd_stream *lzxd_init(struct mspack_system *system,
   lzx->frame           = 0;
   lzx->reset_interval  = reset_interval;
   lzx->intel_filesize  = 0;
-  lzx->intel_curpos    = 0;
   lzx->intel_started   = 0;
   lzx->error           = MSPACK_ERR_OK;
   lzx->num_offsets     = position_slots[window_bits - 15] << 3;
@@ -392,17 +386,10 @@ void lzxd_set_output_length(struct lzxd_stream *lzx, off_t out_bytes) {
 }
 
 int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
-  /* bitstream and huffman reading variables */
-  register unsigned int bit_buffer;
-  register int bits_left, i=0;
-  unsigned char *i_ptr, *i_end;
-  register unsigned short sym;
-
-  int match_length, length_footer, extra, verbatim_bits, bytes_todo;
-  int this_run, main_element, aligned_bits, j, warned = 0;
-  unsigned char *window, *runsrc, *rundest, buf[12];
-  unsigned int frame_size=0, end_frame, match_offset, window_posn;
-  unsigned int R0, R1, R2;
+  DECLARE_HUFF_VARS;
+  unsigned char *window, *runsrc, *rundest, buf[12], warned = 0;
+  unsigned int frame_size, end_frame, window_posn, R0, R1, R2;
+  int bytes_todo, this_run, i, j;
 
   /* easy answers */
   if (!lzx || (out_bytes < 0)) return MSPACK_ERR_ARGS;
@@ -524,9 +511,9 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
             READ_IF_NEEDED;
             *rundest++ = *i_ptr++;
           }
-          R0 = buf[0] | (buf[1] << 8) | (buf[2]  << 16) | (buf[3]  << 24);
-          R1 = buf[4] | (buf[5] << 8) | (buf[6]  << 16) | (buf[7]  << 24);
-          R2 = buf[8] | (buf[9] << 8) | (buf[10] << 16) | (buf[11] << 24);
+          R0 = EndGetI32(&buf[0]);
+          R1 = EndGetI32(&buf[4]);
+          R2 = EndGetI32(&buf[8]);
           break;
 
         default:
@@ -546,8 +533,12 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
 
       /* decode at least this_run bytes */
       switch (lzx->block_type) {
+      case LZX_BLOCKTYPE_ALIGNED:
       case LZX_BLOCKTYPE_VERBATIM:
         while (this_run > 0) {
+	  int main_element, length_footer, verbatim_bits, aligned_bits, extra;
+	  int match_length;
+	  unsigned int match_offset;
           READ_HUFFSYM(MAINTREE, main_element);
           if (main_element < LZX_NUM_CHARS) {
             /* literal: 0 to LZX_NUM_CHARS-1 */
@@ -572,137 +563,24 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
 
             /* get match offset */
             switch ((match_offset = (main_element >> 3))) {
-            case 0: match_offset = R0;                                  break;
-            case 1: match_offset = R1; R1=R0;        R0 = match_offset; break;
-            case 2: match_offset = R2; R2=R0;        R0 = match_offset; break;
-            case 3: match_offset = 1;  R2=R1; R1=R0; R0 = match_offset; break;
-            default:
-              extra = (match_offset >= 36) ? 17 : extra_bits[match_offset];
-              READ_BITS(verbatim_bits, extra);
-              match_offset = position_base[match_offset] - 2 + verbatim_bits;
-              R2 = R1; R1 = R0; R0 = match_offset;
-            }
-
-            /* LZX DELTA uses max match length to signal even longer match */
-            if (match_length == LZX_MAX_MATCH && lzx->is_delta) {
-                int extra_len = 0;
-                ENSURE_BITS(3); /* 4 entry huffman tree */
-                if (PEEK_BITS(1) == 0) {
-                    REMOVE_BITS(1); /* '0' -> 8 extra length bits */
-                    READ_BITS(extra_len, 8);
-                }
-                else if (PEEK_BITS(2) == 2) {
-                    REMOVE_BITS(2); /* '10' -> 10 extra length bits + 0x100 */
-                    READ_BITS(extra_len, 10);
-                    extra_len += 0x100;
-                }
-                else if (PEEK_BITS(3) == 6) {
-                    REMOVE_BITS(3); /* '110' -> 12 extra length bits + 0x500 */
-                    READ_BITS(extra_len, 12);
-                    extra_len += 0x500;
-                }
-                else {
-                    REMOVE_BITS(3); /* '111' -> 15 extra length bits */
-                    READ_BITS(extra_len, 15);
-                }
-                match_length += extra_len;
-            }
-
-            if ((window_posn + match_length) > lzx->window_size) {
-              D(("match ran over window wrap"))
-              return lzx->error = MSPACK_ERR_DECRUNCH;
-            }
-            
-            /* copy match */
-            rundest = &window[window_posn];
-            i = match_length;
-            /* does match offset wrap the window? */
-            if (match_offset > window_posn) {
-              if (match_offset > lzx->offset &&
-                  (match_offset - window_posn) > lzx->ref_data_size)
-              {
-                D(("match offset beyond LZX stream"))
-                return lzx->error = MSPACK_ERR_DECRUNCH;
-              }
-              /* j = length from match offset to end of window */
-              j = match_offset - window_posn;
-              if (j > (int) lzx->window_size) {
-                D(("match offset beyond window boundaries"))
-                return lzx->error = MSPACK_ERR_DECRUNCH;
-              }
-              runsrc = &window[lzx->window_size - j];
-              if (j < i) {
-                /* if match goes over the window edge, do two copy runs */
-                i -= j; while (j-- > 0) *rundest++ = *runsrc++;
-                runsrc = window;
-              }
-              while (i-- > 0) *rundest++ = *runsrc++;
-            }
-            else {
-              runsrc = rundest - match_offset;
-              while (i-- > 0) *rundest++ = *runsrc++;
-            }
-
-            this_run    -= match_length;
-            window_posn += match_length;
-          }
-        } /* while (this_run > 0) */
-        break;
-
-      case LZX_BLOCKTYPE_ALIGNED:
-        while (this_run > 0) {
-          READ_HUFFSYM(MAINTREE, main_element);
-          if (main_element < LZX_NUM_CHARS) {
-            /* literal: 0 to LZX_NUM_CHARS-1 */
-            window[window_posn++] = main_element;
-            this_run--;
-          }
-          else {
-            /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
-            main_element -= LZX_NUM_CHARS;
-
-            /* get match length */
-            match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
-            if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
-              if (lzx->LENGTH_empty) {
-                D(("LENGTH symbol needed but tree is empty"))
-                return lzx->error = MSPACK_ERR_DECRUNCH;
-              } 
-              READ_HUFFSYM(LENGTH, length_footer);
-              match_length += length_footer;
-            }
-            match_length += LZX_MIN_MATCH;
-
-            /* get match offset */
-            switch ((match_offset = (main_element >> 3))) {
-            case 0: match_offset = R0;                             break;
-            case 1: match_offset = R1; R1 = R0; R0 = match_offset; break;
-            case 2: match_offset = R2; R2 = R0; R0 = match_offset; break;
+            case 0: match_offset = R0; break;
+            case 1: match_offset = R1; R1=R0; R0 = match_offset; break;
+            case 2: match_offset = R2; R2=R0; R0 = match_offset; break;
             default:
               extra = (match_offset >= 36) ? 17 : extra_bits[match_offset];
               match_offset = position_base[match_offset] - 2;
-              if (extra > 3) {
-                /* verbatim and aligned bits */
-                extra -= 3;
-                READ_BITS(verbatim_bits, extra);
-                match_offset += (verbatim_bits << 3);
-                READ_HUFFSYM(ALIGNED, aligned_bits);
-                match_offset += aligned_bits;
-              }
-              else if (extra == 3) {
-                /* aligned bits only */
+              if (extra >= 3 && lzx->block_type == LZX_BLOCKTYPE_ALIGNED) {
+                if (extra > 3) {
+                  READ_BITS(verbatim_bits, extra - 3); /* 1-14 bits */
+                  match_offset += verbatim_bits << 3;
+                }
                 READ_HUFFSYM(ALIGNED, aligned_bits);
                 match_offset += aligned_bits;
               }
-              else if (extra > 0) { /* extra==1, extra==2 */
-                /* verbatim bits only */
-                READ_BITS(verbatim_bits, extra);
+              else if (extra) {
+                READ_BITS(verbatim_bits, extra); /* 1-17 bits */
                 match_offset += verbatim_bits;
               }
-              else /* extra == 0 */ {
-                /* ??? not defined in LZX specification! */
-                match_offset = 1;
-              }
               /* update repeated offset LRU queue */
               R2 = R1; R1 = R0; R0 = match_offset;
             }
@@ -742,7 +620,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
             i = match_length;
             /* does match offset wrap the window? */
             if (match_offset > window_posn) {
-              if (match_offset > lzx->offset &&
+	      if ((off_t)match_offset > lzx->offset &&
                   (match_offset - window_posn) > lzx->ref_data_size)
               {
                 D(("match offset beyond LZX stream"))
@@ -784,7 +662,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
           }
           else {
             if (i > this_run) i = this_run;
-            lzx->sys->copy(i_ptr, rundest, (size_t) i);
+            lzx->sys->copy(i_ptr, rundest, i);
             rundest  += i;
             i_ptr    += i;
             this_run -= i;
@@ -827,11 +705,11 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
 
     /* does this intel block _really_ need decoding? */
     if (lzx->intel_started && lzx->intel_filesize &&
-        (lzx->frame <= 32768) && (frame_size > 10))
+        (lzx->frame < 32768) && (frame_size > 10))
     {
       unsigned char *data    = &lzx->e8_buf[0];
       unsigned char *dataend = &lzx->e8_buf[frame_size - 10];
-      signed int curpos      = lzx->intel_curpos;
+      signed int curpos      = (int) lzx->offset;
       signed int filesize    = lzx->intel_filesize;
       signed int abs_off, rel_off;
 
@@ -841,7 +719,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
 
       while (data < dataend) {
         if (*data++ != 0xE8) { curpos++; continue; }
-        abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
+        abs_off = EndGetI32(data);
         if ((abs_off >= -curpos) && (abs_off < filesize)) {
           rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
           data[0] = (unsigned char) rel_off;
@@ -852,11 +730,9 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
         data += 4;
         curpos += 5;
       }
-      lzx->intel_curpos += frame_size;
     }
     else {
       lzx->o_ptr = &lzx->window[lzx->frame_posn];
-      if (lzx->intel_filesize) lzx->intel_curpos += frame_size;
     }
     lzx->o_end = &lzx->o_ptr[frame_size];
 
diff --git a/utils/rbutilqt/mspack/mszipd.c b/utils/rbutilqt/mspack/mszipd.c
index c1b02b1207..aaf4ffe19c 100644
--- a/utils/rbutilqt/mspack/mszipd.c
+++ b/utils/rbutilqt/mspack/mszipd.c
@@ -1,5 +1,5 @@
 /* This file is part of libmspack.
- * (C) 2003-2010 Stuart Caie.
+ * (C) 2003-2023 Stuart Caie.
  *
  * The deflate method was created by Phil Katz. MSZIP is equivalent to the
  * deflate method.
@@ -89,10 +89,7 @@ static const unsigned char bitlen_order[19] = {
 #define INF_ERR_HUFFSYM     (-14) /* out of bits decoding huffman symbol     */
 
 static int zip_read_lens(struct mszipd_stream *zip) {
-  /* for the bit buffer and huffman decoding */
-  register unsigned int bit_buffer;
-  register int bits_left;
-  unsigned char *i_ptr, *i_end;
+  DECLARE_BIT_VARS;
 
   /* bitlen Huffman codes -- immediate lookup, 7 bit max code length */
   unsigned short bl_table[(1 << 7)];
@@ -155,13 +152,9 @@ static int zip_read_lens(struct mszipd_stream *zip) {
 
 /* a clean implementation of RFC 1951 / inflate */
 static int inflate(struct mszipd_stream *zip) {
-  unsigned int last_block, block_type, distance, length, this_run, i;
-
-  /* for the bit buffer and huffman decoding */
-  register unsigned int bit_buffer;
-  register int bits_left;
-  register unsigned short sym;
-  unsigned char *i_ptr, *i_end;
+  DECLARE_HUFF_VARS;
+  unsigned int last_block, block_type, distance, length, this_run;
+  int i;
 
   RESTORE_BITS;
 
@@ -359,7 +352,7 @@ struct mszipd_stream *mszipd_init(struct mspack_system *system,
   }
 
   /* allocate input buffer */
-  zip->inbuf  = (unsigned char *) system->alloc(system, (size_t) input_buffer_size);
+  zip->inbuf  = (unsigned char *) system->alloc(system, input_buffer_size);
   if (!zip->inbuf) {
     system->free(zip);
     return NULL;
@@ -467,11 +460,7 @@ int mszipd_decompress(struct mszipd_stream *zip, off_t out_bytes) {
 }
 
 int mszipd_decompress_kwaj(struct mszipd_stream *zip) {
-    /* for the bit buffer */
-    register unsigned int bit_buffer;
-    register int bits_left;
-    unsigned char *i_ptr, *i_end;
-
+    DECLARE_BIT_VARS;
     int i, error, block_len;
 
     /* unpack blocks until block_len == 0 */
diff --git a/utils/rbutilqt/mspack/qtmd.c b/utils/rbutilqt/mspack/qtmd.c
index 58e4787b7f..13658032b0 100644
--- a/utils/rbutilqt/mspack/qtmd.c
+++ b/utils/rbutilqt/mspack/qtmd.c
@@ -1,5 +1,5 @@
 /* This file is part of libmspack.
- * (C) 2003-2004 Stuart Caie.
+ * (C) 2003-2023 Stuart Caie.
  *
  * The Quantum method was created by David Stafford, adapted by Microsoft
  * Corporation.
@@ -254,14 +254,12 @@ struct qtmd_stream *qtmd_init(struct mspack_system *system,
 }
 
 int qtmd_decompress(struct qtmd_stream *qtm, off_t out_bytes) {
+  DECLARE_BIT_VARS;
   unsigned int frame_todo, frame_end, window_posn, match_offset, range;
-  unsigned char *window, *i_ptr, *i_end, *runsrc, *rundest;
+  unsigned char *window, *runsrc, *rundest;
   int i, j, selector, extra, sym, match_length;
   unsigned short H, L, C, symf;
 
-  register unsigned int bit_buffer;
-  register unsigned char bits_left;
-
   /* easy answers */
   if (!qtm || (out_bytes < 0)) return MSPACK_ERR_ARGS;
   if (qtm->error) return qtm->error;
diff --git a/utils/rbutilqt/mspack/readbits.h b/utils/rbutilqt/mspack/readbits.h
index 9b237a3693..846e8454f7 100644
--- a/utils/rbutilqt/mspack/readbits.h
+++ b/utils/rbutilqt/mspack/readbits.h
@@ -13,6 +13,7 @@
 /* this header defines macros that read data streams by
  * the individual bits
  *
+ * DECLARE_BIT_VARS  declares local variables
  * INIT_BITS         initialises bitstream state in state structure
  * STORE_BITS        stores bitstream state in state structure
  * RESTORE_BITS      restores bitstream state from state structure
@@ -92,13 +93,20 @@
 # endif
 #endif
 
+typedef unsigned int bitbuf_type;
+
 #if HAVE_LIMITS_H
 # include <limits.h>
 #endif
 #ifndef CHAR_BIT
 # define CHAR_BIT (8)
 #endif
-#define BITBUF_WIDTH (sizeof(bit_buffer) * CHAR_BIT)
+#define BITBUF_WIDTH (sizeof(bitbuf_type) * CHAR_BIT)
+
+#define DECLARE_BIT_VARS \
+   unsigned char *i_ptr, *i_end; \
+   register bitbuf_type bit_buffer; \
+   register int bits_left
 
 #define INIT_BITS do {                          \
     BITS_VAR->i_ptr      = &BITS_VAR->inbuf[0]; \
@@ -136,7 +144,7 @@
     unsigned char needed = (bits), bitrun;                      \
     (val) = 0;                                                  \
     while (needed > 0) {                                        \
-        if (bits_left <= (BITBUF_WIDTH - 16)) READ_BYTES;       \
+        if (bits_left <= (int)(BITBUF_WIDTH - 16)) READ_BYTES;	\
         bitrun = (bits_left < needed) ? bits_left : needed;     \
         (val) = ((val) << bitrun) | PEEK_BITS(bitrun);          \
         REMOVE_BITS(bitrun);                                    \
@@ -148,12 +156,13 @@
 # define PEEK_BITS(nbits)   (bit_buffer >> (BITBUF_WIDTH - (nbits)))
 # define REMOVE_BITS(nbits) ((bit_buffer <<= (nbits)), (bits_left -= (nbits)))
 # define INJECT_BITS(bitdata,nbits) ((bit_buffer |= \
-    (bitdata) << (BITBUF_WIDTH - (nbits) - bits_left)), (bits_left += (nbits)))
+    (bitbuf_type)(bitdata) << (BITBUF_WIDTH - (nbits) - bits_left)), \
+    (bits_left += (nbits)))
 #else /* BITS_ORDER_LSB */
-# define PEEK_BITS(nbits)   (bit_buffer & ((1 << (nbits))-1))
+# define PEEK_BITS(nbits)   (bit_buffer & ((bitbuf_type)(1 << (nbits))-1))
 # define REMOVE_BITS(nbits) ((bit_buffer >>= (nbits)), (bits_left -= (nbits)))
 # define INJECT_BITS(bitdata,nbits) ((bit_buffer |= \
-    (bitdata) << bits_left), (bits_left += (nbits)))
+    (bitbuf_type)(bitdata) << bits_left), (bits_left += (nbits)))
 #endif
 
 #ifdef BITS_LSB_TABLE
diff --git a/utils/rbutilqt/mspack/readhuff.h b/utils/rbutilqt/mspack/readhuff.h
index 4d94225789..f6e449f1d2 100644
--- a/utils/rbutilqt/mspack/readhuff.h
+++ b/utils/rbutilqt/mspack/readhuff.h
@@ -28,35 +28,40 @@
 # define HUFF_MAXBITS 16
 #endif
 
+#define DECLARE_HUFF_VARS \
+   DECLARE_BIT_VARS; \
+   register int huff_idx; \
+   register unsigned short huff_sym
+
 /* Decodes the next huffman symbol from the input bitstream into var.
  * Do not use this macro on a table unless build_decode_table() succeeded.
  */
-#define READ_HUFFSYM(tbl, var) do {                     \
-    ENSURE_BITS(HUFF_MAXBITS);                          \
-    sym = HUFF_TABLE(tbl, PEEK_BITS(TABLEBITS(tbl)));   \
-    if (sym >= MAXSYMBOLS(tbl)) HUFF_TRAVERSE(tbl);     \
-    (var) = sym;                                        \
-    i = HUFF_LEN(tbl, sym);                             \
-    REMOVE_BITS(i);                                     \
+#define READ_HUFFSYM(tbl, var) do {                                 \
+    ENSURE_BITS(HUFF_MAXBITS);                                      \
+    huff_sym = HUFF_TABLE(tbl, PEEK_BITS(TABLEBITS(tbl)));          \
+    if (huff_sym >= MAXSYMBOLS(tbl)) HUFF_TRAVERSE(tbl);            \
+    (var) = huff_sym;                                               \
+    huff_idx = HUFF_LEN(tbl, huff_sym);                             \
+    REMOVE_BITS(huff_idx);                                          \
 } while (0)
 
 #ifdef BITS_ORDER_LSB
-# define HUFF_TRAVERSE(tbl) do {                        \
-    i = TABLEBITS(tbl) - 1;                             \
-    do {                                                \
-        if (i++ > HUFF_MAXBITS) HUFF_ERROR;             \
-        sym = HUFF_TABLE(tbl,                           \
-            (sym << 1) | ((bit_buffer >> i) & 1));      \
-    } while (sym >= MAXSYMBOLS(tbl));                   \
+# define HUFF_TRAVERSE(tbl) do {                                    \
+    huff_idx = TABLEBITS(tbl) - 1;                                  \
+    do {                                                            \
+        if (huff_idx++ > HUFF_MAXBITS) HUFF_ERROR;                  \
+        huff_sym = HUFF_TABLE(tbl,                                  \
+            (huff_sym << 1) | ((bit_buffer >> huff_idx) & 1));      \
+    } while (huff_sym >= MAXSYMBOLS(tbl));                          \
 } while (0)
 #else
-#define HUFF_TRAVERSE(tbl) do {                         \
-    i = 1 << (BITBUF_WIDTH - TABLEBITS(tbl));           \
-    do {                                                \
-        if ((i >>= 1) == 0) HUFF_ERROR;                 \
-        sym = HUFF_TABLE(tbl,                           \
-            (sym << 1) | ((bit_buffer & i) ? 1 : 0));   \
-    } while (sym >= MAXSYMBOLS(tbl));                   \
+#define HUFF_TRAVERSE(tbl) do {                                     \
+    huff_idx = 1 << (BITBUF_WIDTH - TABLEBITS(tbl));                \
+    do {                                                            \
+        if ((huff_idx >>= 1) == 0) HUFF_ERROR;                      \
+        huff_sym = HUFF_TABLE(tbl,                                  \
+            (huff_sym << 1) | ((bit_buffer & huff_idx) ? 1 : 0));   \
+    } while (huff_sym >= MAXSYMBOLS(tbl));                          \
 } while (0)
 #endif
 
diff --git a/utils/rbutilqt/mspack/system-mspack.c b/utils/rbutilqt/mspack/system-mspack.c
index 9d4886a8db..3d8d1eef8f 100644
--- a/utils/rbutilqt/mspack/system-mspack.c
+++ b/utils/rbutilqt/mspack/system-mspack.c
@@ -13,11 +13,6 @@
 
 #include "system-mspack.h"
 
-#ifndef LARGEFILE_SUPPORT
-const char *largefile_msg = "library not compiled to support large files.";
-#endif
-
-
 int mspack_version(int entity) {
   switch (entity) {
    /* CHM decoder version 1 -> 2 changes:
diff --git a/utils/rbutilqt/mspack/system-mspack.h b/utils/rbutilqt/mspack/system-mspack.h
index a0e6cf3ca8..2d9ae1747f 100644
--- a/utils/rbutilqt/mspack/system-mspack.h
+++ b/utils/rbutilqt/mspack/system-mspack.h
@@ -72,19 +72,19 @@ extern const char *largefile_msg;
 
 /* endian-neutral reading of little-endian data */
 #define __egi32(a,n) ( ((((unsigned char *) a)[n+3]) << 24) | \
-		       ((((unsigned char *) a)[n+2]) << 16) | \
-		       ((((unsigned char *) a)[n+1]) <<  8) | \
-		       ((((unsigned char *) a)[n+0])))
-#define EndGetI64(a) ((((unsigned long long int) __egi32(a,4)) << 32) | \
-		      ((unsigned int) __egi32(a,0)))
+                      ((((unsigned char *) a)[n+2]) << 16) | \
+                      ((((unsigned char *) a)[n+1]) <<  8) | \
+                      ((((unsigned char *) a)[n+0])))
+#define	EndGetI64(a) ((((unsigned long long int) __egi32(a,4)) << 32) | \
+                     ((unsigned int) __egi32(a,0)))
 #define EndGetI32(a) __egi32(a,0)
 #define EndGetI16(a) ((((a)[1])<<8)|((a)[0]))
 
 /* endian-neutral reading of big-endian data */
 #define EndGetM32(a) (((((unsigned char *) a)[0]) << 24) | \
-		      ((((unsigned char *) a)[1]) << 16) | \
-		      ((((unsigned char *) a)[2]) <<  8) | \
-		      ((((unsigned char *) a)[3])))
+                     ((((unsigned char *) a)[1]) << 16) | \
+                     ((((unsigned char *) a)[2]) <<  8) | \
+                     ((((unsigned char *) a)[3])))
 #define EndGetM16(a) ((((a)[0])<<8)|((a)[1]))
 
 extern struct mspack_system *mspack_default_system;
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs