|
| 1 | +2023-02-03 Stuart Caie <kyzer@cabextract.org.uk> |
| 2 | + |
| 3 | + * configure.ac: do AC_CHECK_SIZEOF([off_t]) test only after |
| 4 | + AC_SYS_LARGEFILE, because the latter can alter the size of off_t. |
| 5 | + |
| 6 | + * cabd_extract(): file->offset and file->length are unsigned ints, |
| 7 | + both of them and their sum are checked to be <= CAB_LENGTHMAX. But |
| 8 | + recent code stuffs file->length into an off_t and checks that instead. |
| 9 | + On 32-bit architectures, if file->length > 2GiB then the off_t is |
| 10 | + negative, evading the check. Ultimately this causes the decompression |
| 11 | + functions to return MSPACK_ERR_ARGS as they already guard against |
| 12 | + being asked to decompress a negative number of bytes. |
| 13 | + |
| 14 | +2023-02-01 Stuart Caie <kyzer@cabextract.org.uk> |
| 15 | + |
| 16 | + * readbits.h, readhuff.h, cabd.c, kwajd.c, lzxd.c, mszipd.c, qtmd.c: |
| 17 | + ensure bit operations (including intermediary ones) are considered |
| 18 | + as unsigned int, so UBSan is happy. |
| 19 | + |
| 20 | +2023-01-31 Stuart Caie <kyzer@cabextract.org.uk> |
| 21 | + |
| 22 | + * chmd.c: replace READ_ENCINT() macro with stricter read_encint() |
| 23 | + function that reads no more than 63 or 31 bits so ENCINTs can never |
| 24 | + be negative. |
| 25 | + |
| 26 | + I'd prefer to use unsigned types, but off_t is used for file offsets |
| 27 | + and lengths to match the environment's file I/O, so changing it is |
| 28 | + tricky and would change the current public API. |
| 29 | + |
| 30 | + Additionally, UBSan complains about shifting a 1 into a signed |
| 31 | + type's MSB. https://www.cs.utah.edu/~regehr/papers/tosem15.pdf |
| 32 | + notes that this is legal in ANSI C and "fairly benign (and well- |
| 33 | + defined until C99)", but C99 made it undefined for no good reason. |
| 34 | + I don't agree with this, but I don't want someone else using a C99 |
| 35 | + compiler to end up miscompiling the code. |
| 36 | + |
| 37 | + * chmd_read_headers(): the CHM's internally declared file length is |
| 38 | + compared against its actual file length and a warning is printed if |
| 39 | + they don't match. |
| 40 | + |
| 41 | + * chmd_extract(): files in the uncompressed section will print a |
| 42 | + warning if their declared length goes beyond the declared end of the |
| 43 | + CHM file. This may not match the actual CHM file length. You will |
| 44 | + still get seek or read errors if a file's offset or length go beyond |
| 45 | + the actual CHM file length. |
| 46 | + |
| 47 | + Files in the compressed section will now cause a decrunch error if |
| 48 | + their declared offset goes beyond the uncompressed length of the |
| 49 | + section. If their offset is OK but their declared length goes beyond |
| 50 | + the end, they will print a warning and then decompress as much as |
| 51 | + possible before causing an error. |
| 52 | + |
| 53 | +2023-01-02 Stuart Caie <kyzer@cabextract.org.uk> |
| 54 | + |
| 55 | + * kwajd_extract(): KWAJ compression method #2 is the QBasic variant |
| 56 | + of the SZDD compression algorithm. Thanks to Jason Summers for finding |
| 57 | + this and providing examples. |
| 58 | + |
| 59 | +2021-07-20 Stuart Caie <kyzer@cabextract.org.uk> |
| 60 | + |
| 61 | + * lzxd_decompress(): simplified the code that decodes match_offset. |
| 62 | + Thanks to Jasper St. Pierre for prompting me to look at it. |
| 63 | + |
| 64 | +2020-12-30 Stuart Caie <kyzer@cabextract.org.uk> |
| 65 | + |
| 66 | + * cabd_read_string(): libmspack no longer rejects CAB files with |
| 67 | + empty previnfo/nextinfo strings. Thanks to Simon Tatham for the |
| 68 | + patch, and for noting that WiX v4 currently generates such files. |
| 69 | + |
| 70 | +2020-08-10 Stuart Caie <kyzer@cabextract.org.uk> |
| 71 | + |
| 72 | + * lzxd_decompress(): merged the code for decoding aligned and |
| 73 | + verbatim blocks, also verified there is no significant performance |
| 74 | + penalty. |
| 75 | + |
| 76 | +2020-08-07 Stuart Caie <kyzer@cabextract.org.uk> |
| 77 | + |
| 78 | + * read_sys_file(): in a CHM file, the ControlData and ResetTable |
| 79 | + files are loaded entirely into memory, regardless of file size. |
| 80 | + This is not in the spirit of letting users control memory usage. |
| 81 | + |
| 82 | + ControlData previously had to be at least 28 bytes (in case a new, |
| 83 | + larger version of the file ever appeared), but is now rejected |
| 84 | + if not exactly 28 bytes. |
| 85 | + |
| 86 | + ResetTable can theoretically be huge; the longest LZX stream of |
| 87 | + 16 exabytes could have a 4 petabyte ResetTable. Practically, the |
| 88 | + largest seen in the wild is 46 kilobytes (PHP manuals). I picked |
| 89 | + an arbitrary upper limit of 1MB; please get in contact if you |
| 90 | + know of any CHM files in the wild that are largest than this. |
| 91 | + |
| 92 | + Thanks to seviezhou on Github for reporting this. |
| 93 | + |
| 94 | +2020-04-13 Stuart Caie <kyzer@cabextract.org.uk> |
| 95 | + |
| 96 | + * system.h: clear up libmspack's large file support. |
| 97 | + |
| 98 | + To support large files, do this: |
| 99 | + |
| 100 | + 1. add any defines that your compiler needs to enable large file |
| 101 | + support. It may be supported by default. |
| 102 | + 2. Define HAVE_FSEEKO if fseeko() and ftello() are available. |
| 103 | + 3. Define SIZEOF_OFF_T to the value of sizeof(off_t); it must be a |
| 104 | + literal value because sizeof() can't be used in preprocessor tests. |
| 105 | + |
| 106 | + libmspack uses the off_t datatype for all file offsets. If off_t is |
| 107 | + less than 64 bits, libmspack will return an error when processing |
| 108 | + CHM files with offsets beyond 2GB, and won't search for CAB headers |
| 109 | + beyond 2GB into a file. In both cases, it prints a warning message |
| 110 | + that the library doesn't support large files. |
| 111 | + |
| 112 | +2020-04-13 Stuart Caie <kyzer@cabextract.org.uk> |
| 113 | + |
| 114 | + * macros.h: new header for the D(), LD/LU and EndGet???() macros. |
| 115 | + Use this instead of system.h. |
| 116 | + |
| 117 | + * system.h: if MSPACK_NO_DEFAULT_SYSTEM is defined, define |
| 118 | + inline versions of the only standard C functions used in |
| 119 | + mspack (strlen, memcmp, memset), so that no standard C library |
| 120 | + functions are needed at all. |
| 121 | + |
| 122 | +2020-01-08 Stuart Caie <kyzer@cabextract.org.uk> |
| 123 | + |
| 124 | + * lzxd_decompress(): do not apply the E8 transformation on the |
| 125 | + 32769th LZX frame! Thanks to Cezary Sliwa for discovering this |
| 126 | + bug and providing an example cab file (which is |
| 127 | + http://download.windowsupdate.com/d/msdownload/update/driver/ |
| 128 | + drvs/2019/11/016c7f3e-809d-4720-893b- |
| 129 | + e0d74f10c39d_35e12507628e8dc8ae5fb3332835f4253d2dab23.cab) |
| 130 | + |
| 131 | + * cabd_compare: use EXPAND.EXE instead of EXTRACT.EXE when |
| 132 | + testing files in a directory called 'expand'. The example |
| 133 | + cab file above is extracted wrongly by EXTRACT.EXE, but |
| 134 | + correctly by EXPAND.EXE because they take different approaches |
| 135 | + to E8 transformations: |
| 136 | + |
| 137 | + - EXTRACT.EXE writes "E8E8E8E8E8E8' to the last 6 bytes of |
| 138 | + frame, looks for E8 bytes up to the last 6 bytes, then restores |
| 139 | + the last 6 bytes, leaving partial transforms of 1-3 bytes if |
| 140 | + E8 byte is found near the end of the frame |
| 141 | + |
| 142 | + - EXPAND.EXE looks for E8 bytes up to the last 10 bytes of a |
| 143 | + frame, therefore the last 6 bytes are never altered and all |
| 144 | + transforms are 4 bytes |
| 145 | + |
1 | 146 | 2019-02-18 Stuart Caie <kyzer@cabextract.org.uk> |
2 | 147 |
|
3 | 148 | * chmd_read_headers(): a CHM file name beginning "::" but shorter |
|
0 commit comments