From a82396b0be56128db0be8cae34a47f980d4123d9 Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Sat, 4 Jul 2026 21:39:31 -0400 Subject: [PATCH] rbutil: Update embedded 'mspack' library from 0.10.1alpha to 0.11alpha Change-Id: I37210d1dc2c5cecdf8256f9e0294dcbd8516e8c8 --- utils/rbutilqt/mspack/README.ROCKBOX | 4 +- utils/rbutilqt/mspack/cabd.c | 40 +++--- utils/rbutilqt/mspack/chm.h | 5 +- utils/rbutilqt/mspack/chmd.c | 194 ++++++++++++++++++-------- utils/rbutilqt/mspack/kwajd.c | 60 ++++---- utils/rbutilqt/mspack/lzx.h | 1 - utils/rbutilqt/mspack/lzxd.c | 184 ++++-------------------- utils/rbutilqt/mspack/mszipd.c | 25 +--- utils/rbutilqt/mspack/qtmd.c | 8 +- utils/rbutilqt/mspack/readbits.h | 19 ++- utils/rbutilqt/mspack/readhuff.h | 47 ++++--- utils/rbutilqt/mspack/system-mspack.c | 5 - utils/rbutilqt/mspack/system-mspack.h | 16 +-- 13 files changed, 281 insertions(+), 327 deletions(-) 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; - } - - if (self->error) { - if (fh) sys->close(fh); - sys->free(hdr); - hdr = NULL; + fh = sys->open(sys, filename, MSPACK_SYS_OPEN_READ); + if (!fh) { + self->error = MSPACK_ERR_OPEN; + return 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); + 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 == 3) { - /* aligned bits only */ - 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 #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;