libmspack 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +5 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/README.md +75 -0
- data/Rakefile +22 -0
- data/UNLICENSE +24 -0
- data/ext/Rakefile +16 -0
- data/ext/i386-windows/libmspack.dll +0 -0
- data/ext/libmspack/AUTHORS +12 -0
- data/ext/libmspack/COPYING.LIB +504 -0
- data/ext/libmspack/ChangeLog +491 -0
- data/ext/libmspack/Makefile.am +100 -0
- data/ext/libmspack/NEWS +0 -0
- data/ext/libmspack/README +130 -0
- data/ext/libmspack/TODO +8 -0
- data/ext/libmspack/cleanup.sh +9 -0
- data/ext/libmspack/configure.ac +50 -0
- data/ext/libmspack/debian/changelog +6 -0
- data/ext/libmspack/debian/control +14 -0
- data/ext/libmspack/debian/rules +101 -0
- data/ext/libmspack/doc/Doxyfile.in +22 -0
- data/ext/libmspack/doc/Makefile.in +14 -0
- data/ext/libmspack/doc/szdd_kwaj_format.html +331 -0
- data/ext/libmspack/libmspack.pc.in +10 -0
- data/ext/libmspack/mspack/cab.h +127 -0
- data/ext/libmspack/mspack/cabc.c +24 -0
- data/ext/libmspack/mspack/cabd.c +1444 -0
- data/ext/libmspack/mspack/chm.h +122 -0
- data/ext/libmspack/mspack/chmc.c +24 -0
- data/ext/libmspack/mspack/chmd.c +1392 -0
- data/ext/libmspack/mspack/crc32.c +95 -0
- data/ext/libmspack/mspack/crc32.h +17 -0
- data/ext/libmspack/mspack/des.h +15 -0
- data/ext/libmspack/mspack/hlp.h +33 -0
- data/ext/libmspack/mspack/hlpc.c +24 -0
- data/ext/libmspack/mspack/hlpd.c +24 -0
- data/ext/libmspack/mspack/kwaj.h +118 -0
- data/ext/libmspack/mspack/kwajc.c +24 -0
- data/ext/libmspack/mspack/kwajd.c +561 -0
- data/ext/libmspack/mspack/lit.h +35 -0
- data/ext/libmspack/mspack/litc.c +24 -0
- data/ext/libmspack/mspack/litd.c +24 -0
- data/ext/libmspack/mspack/lzss.h +66 -0
- data/ext/libmspack/mspack/lzssd.c +93 -0
- data/ext/libmspack/mspack/lzx.h +221 -0
- data/ext/libmspack/mspack/lzxc.c +18 -0
- data/ext/libmspack/mspack/lzxd.c +895 -0
- data/ext/libmspack/mspack/mspack.def +28 -0
- data/ext/libmspack/mspack/mspack.h +2353 -0
- data/ext/libmspack/mspack/mszip.h +126 -0
- data/ext/libmspack/mspack/mszipc.c +18 -0
- data/ext/libmspack/mspack/mszipd.c +514 -0
- data/ext/libmspack/mspack/oab.h +60 -0
- data/ext/libmspack/mspack/oabc.c +24 -0
- data/ext/libmspack/mspack/oabd.c +408 -0
- data/ext/libmspack/mspack/qtm.h +128 -0
- data/ext/libmspack/mspack/qtmc.c +18 -0
- data/ext/libmspack/mspack/qtmd.c +489 -0
- data/ext/libmspack/mspack/readbits.h +207 -0
- data/ext/libmspack/mspack/readhuff.h +173 -0
- data/ext/libmspack/mspack/sha.h +15 -0
- data/ext/libmspack/mspack/system.c +239 -0
- data/ext/libmspack/mspack/system.h +124 -0
- data/ext/libmspack/mspack/szdd.h +39 -0
- data/ext/libmspack/mspack/szddc.c +24 -0
- data/ext/libmspack/mspack/szddd.c +247 -0
- data/ext/libmspack/rebuild.sh +8 -0
- data/ext/libmspack/test/cabd_c10 +19 -0
- data/ext/libmspack/test/cabd_compare +34 -0
- data/ext/libmspack/test/cabd_md5.c +161 -0
- data/ext/libmspack/test/cabd_memory.c +179 -0
- data/ext/libmspack/test/cabd_test.c +386 -0
- data/ext/libmspack/test/cabrip.c +81 -0
- data/ext/libmspack/test/chmd_compare +38 -0
- data/ext/libmspack/test/chmd_find.c +95 -0
- data/ext/libmspack/test/chmd_md5.c +67 -0
- data/ext/libmspack/test/chmd_order.c +144 -0
- data/ext/libmspack/test/chminfo.c +284 -0
- data/ext/libmspack/test/chmx.c +216 -0
- data/ext/libmspack/test/error.h +22 -0
- data/ext/libmspack/test/expand.c +79 -0
- data/ext/libmspack/test/md5.c +457 -0
- data/ext/libmspack/test/md5.h +165 -0
- data/ext/libmspack/test/md5_fh.h +123 -0
- data/ext/libmspack/test/msdecompile_md5 +24 -0
- data/ext/libmspack/test/msexpand_md5 +39 -0
- data/ext/libmspack/test/multifh.c +435 -0
- data/ext/libmspack/test/oabx.c +41 -0
- data/ext/libmspack/test/test_files/cabd/1.pl +84 -0
- data/ext/libmspack/test/test_files/cabd/2.pl +75 -0
- data/ext/libmspack/test/test_files/cabd/bad_folderindex.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_nofiles.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_nofolders.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_signature.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt1.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt2.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt3.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt4.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt5.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/normal_255c_filename.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/normal_2files_1folder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nodata.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nofiles.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nofolder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortextheader.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfile1.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfile2.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfolder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortheader.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nofname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_noninfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nonname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nopinfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nopname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortfname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortninfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortnname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortpinfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortpname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_---.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_--D.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_-F-.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_-FD.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_H--.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_H-D.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_HF-.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_HFD.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/search_basic.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/search_tricky1.cab +0 -0
- data/ext/libmspack/winbuild.sh +26 -0
- data/ext/x86_64-windows/libmspack.dll +0 -0
- data/lib/libmspack/constants.rb +9 -0
- data/lib/libmspack/exceptions.rb +12 -0
- data/lib/libmspack/mscab.rb +722 -0
- data/lib/libmspack/mschm.rb +301 -0
- data/lib/libmspack/mshlp.rb +15 -0
- data/lib/libmspack/mskwaj.rb +124 -0
- data/lib/libmspack/mslit.rb +18 -0
- data/lib/libmspack/msoab.rb +36 -0
- data/lib/libmspack/mspack.rb +208 -0
- data/lib/libmspack/msszdd.rb +81 -0
- data/lib/libmspack/system.rb +84 -0
- data/lib/libmspack/version.rb +4 -0
- data/lib/libmspack.rb +121 -0
- data/libmspack.gemspec +33 -0
- data/spec/libmspack_spec.rb +26 -0
- data/spec/spec_helper.rb +5 -0
- metadata +309 -0
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/* cabinet decompression regression test suite */
|
|
2
|
+
|
|
3
|
+
#ifdef HAVE_CONFIG_H
|
|
4
|
+
#include <config.h>
|
|
5
|
+
#endif
|
|
6
|
+
|
|
7
|
+
#include <stdio.h>
|
|
8
|
+
#include <stdlib.h>
|
|
9
|
+
#include <string.h>
|
|
10
|
+
#include <mspack.h>
|
|
11
|
+
|
|
12
|
+
unsigned int test_count = 0;
|
|
13
|
+
|
|
14
|
+
#define TEST(x) do {\
|
|
15
|
+
test_count++; \
|
|
16
|
+
if (!(x)) {printf("%s:%d FAILED %s\n",__FUNCTION__,__LINE__,#x);exit(1);} \
|
|
17
|
+
} while (0)
|
|
18
|
+
|
|
19
|
+
/* open where cab file doesn't exist */
|
|
20
|
+
void cabd_open_test_01() {
|
|
21
|
+
struct mscab_decompressor *cabd;
|
|
22
|
+
struct mscabd_cabinet *cab;
|
|
23
|
+
|
|
24
|
+
cabd = mspack_create_cab_decompressor(NULL);
|
|
25
|
+
TEST(cabd != NULL);
|
|
26
|
+
|
|
27
|
+
cab = cabd->open(cabd, "!!!FILE_WHICH_DOES_NOT_EXIST");
|
|
28
|
+
TEST(cab == NULL);
|
|
29
|
+
TEST(cabd->last_error(cabd) == MSPACK_ERR_OPEN);
|
|
30
|
+
|
|
31
|
+
mspack_destroy_cab_decompressor(cabd);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* normal cab file with 2 files and one folder.
|
|
35
|
+
* check ALL headers are read correctly */
|
|
36
|
+
void cabd_open_test_02() {
|
|
37
|
+
struct mscab_decompressor *cabd;
|
|
38
|
+
struct mscabd_cabinet *cab;
|
|
39
|
+
struct mscabd_folder *folder;
|
|
40
|
+
struct mscabd_file *file;
|
|
41
|
+
|
|
42
|
+
cabd = mspack_create_cab_decompressor(NULL);
|
|
43
|
+
TEST(cabd != NULL);
|
|
44
|
+
|
|
45
|
+
cab = cabd->open(cabd, "test_files/cabd/normal_2files_1folder.cab");
|
|
46
|
+
TEST(cab != NULL);
|
|
47
|
+
|
|
48
|
+
TEST(cab->next == NULL);
|
|
49
|
+
TEST(cab->base_offset == 0);
|
|
50
|
+
TEST(cab->length == 253);
|
|
51
|
+
TEST(cab->prevcab == NULL); TEST(cab->nextcab == NULL);
|
|
52
|
+
TEST(cab->prevname == NULL); TEST(cab->nextname == NULL);
|
|
53
|
+
TEST(cab->previnfo == NULL); TEST(cab->nextinfo == NULL);
|
|
54
|
+
TEST(cab->set_id = 1570); TEST(cab->set_index == 0);
|
|
55
|
+
TEST(cab->header_resv == 0);
|
|
56
|
+
TEST(cab->flags == 0);
|
|
57
|
+
|
|
58
|
+
folder = cab->folders;
|
|
59
|
+
TEST(folder != NULL);
|
|
60
|
+
TEST(folder->next == NULL);
|
|
61
|
+
TEST(folder->comp_type == 0);
|
|
62
|
+
TEST(folder->num_blocks == 1);
|
|
63
|
+
|
|
64
|
+
file = cab->files;
|
|
65
|
+
TEST(file != NULL);
|
|
66
|
+
TEST(strcmp(file->filename, "hello.c") == 0);
|
|
67
|
+
TEST(file->length == 77);
|
|
68
|
+
TEST(file->attribs == 0x20);
|
|
69
|
+
TEST(file->time_h == 11);TEST(file->time_m == 13);TEST(file->time_s == 52);
|
|
70
|
+
TEST(file->date_d == 12);TEST(file->date_m == 3);TEST(file->date_y == 1997);
|
|
71
|
+
TEST(file->folder == folder); TEST(file->offset == 0);
|
|
72
|
+
|
|
73
|
+
file = file->next;
|
|
74
|
+
TEST(file != NULL);
|
|
75
|
+
TEST(strcmp(file->filename, "welcome.c") == 0);
|
|
76
|
+
TEST(file->length == 74);
|
|
77
|
+
TEST(file->attribs == 0x20);
|
|
78
|
+
TEST(file->time_h == 11);TEST(file->time_m == 15);TEST(file->time_s == 14);
|
|
79
|
+
TEST(file->date_d == 12);TEST(file->date_m == 3);TEST(file->date_y == 1997);
|
|
80
|
+
TEST(file->folder == folder); TEST(file->offset == 77);
|
|
81
|
+
|
|
82
|
+
cabd->close(cabd, cab);
|
|
83
|
+
mspack_destroy_cab_decompressor(cabd);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* cabs with reserve headers set, ensure they all load correctly */
|
|
87
|
+
void cabd_open_test_03() {
|
|
88
|
+
struct mscab_decompressor *cabd;
|
|
89
|
+
struct mscabd_cabinet *cab;
|
|
90
|
+
unsigned int i;
|
|
91
|
+
const char *files[] = {
|
|
92
|
+
"test_files/cabd/reserve_---.cab",
|
|
93
|
+
"test_files/cabd/reserve_--D.cab",
|
|
94
|
+
"test_files/cabd/reserve_-F-.cab",
|
|
95
|
+
"test_files/cabd/reserve_-FD.cab",
|
|
96
|
+
"test_files/cabd/reserve_H--.cab",
|
|
97
|
+
"test_files/cabd/reserve_H-D.cab",
|
|
98
|
+
"test_files/cabd/reserve_HF-.cab",
|
|
99
|
+
"test_files/cabd/reserve_HFD.cab"
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
cabd = mspack_create_cab_decompressor(NULL);
|
|
103
|
+
TEST(cabd != NULL);
|
|
104
|
+
|
|
105
|
+
for (i = 0; i < (sizeof(files)/sizeof(char *)); i++) {
|
|
106
|
+
cab = cabd->open(cabd, files[i]);
|
|
107
|
+
TEST(cab != NULL);
|
|
108
|
+
TEST(cab->files != NULL);
|
|
109
|
+
TEST(cab->files->next != NULL);
|
|
110
|
+
TEST(strcmp(cab->files->filename, "test1.txt") == 0);
|
|
111
|
+
TEST(strcmp(cab->files->next->filename, "test2.txt") == 0);
|
|
112
|
+
cabd->close(cabd, cab);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
mspack_destroy_cab_decompressor(cabd);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* some bad cabs, should not load */
|
|
119
|
+
void cabd_open_test_04() {
|
|
120
|
+
struct mscab_decompressor *cabd;
|
|
121
|
+
struct mscabd_cabinet *cab;
|
|
122
|
+
|
|
123
|
+
cabd = mspack_create_cab_decompressor(NULL);
|
|
124
|
+
TEST(cabd != NULL);
|
|
125
|
+
|
|
126
|
+
/* cab has enough data for a header, but does not contain real cab data
|
|
127
|
+
* result should be MSPACK_ERR_SIGNATURE */
|
|
128
|
+
cab = cabd->open(cabd, "test_files/cabd/bad_signature.cab");
|
|
129
|
+
TEST(cab == NULL);
|
|
130
|
+
|
|
131
|
+
/* cab has 0 folders */
|
|
132
|
+
cab = cabd->open(cabd, "test_files/cabd/bad_nofolders.cab");
|
|
133
|
+
TEST(cab == NULL);
|
|
134
|
+
|
|
135
|
+
/* cab has 0 files */
|
|
136
|
+
cab = cabd->open(cabd, "test_files/cabd/bad_nofiles.cab");
|
|
137
|
+
TEST(cab == NULL);
|
|
138
|
+
|
|
139
|
+
/* second file in the cab has a folder index for a non-existant folder */
|
|
140
|
+
cab = cabd->open(cabd, "test_files/cabd/bad_folderindex.cab");
|
|
141
|
+
TEST(cab == NULL);
|
|
142
|
+
|
|
143
|
+
mspack_destroy_cab_decompressor(cabd);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* cabs which have been cut short
|
|
147
|
+
* result should be MSPACK_ERR_READ for missing headers or
|
|
148
|
+
* MSPACK_ERR_DATAFORMAT for missing/partial strings.
|
|
149
|
+
* If only data blocks are missing, the cab should open()
|
|
150
|
+
*/
|
|
151
|
+
void cabd_open_test_05() {
|
|
152
|
+
struct mscab_decompressor *cabd;
|
|
153
|
+
struct mscabd_cabinet *cab;
|
|
154
|
+
unsigned int i;
|
|
155
|
+
const char *files[] = {
|
|
156
|
+
"test_files/cabd/partial_shortheader.cab",
|
|
157
|
+
"test_files/cabd/partial_shortextheader.cab",
|
|
158
|
+
"test_files/cabd/partial_nofolder.cab",
|
|
159
|
+
"test_files/cabd/partial_shortfolder.cab",
|
|
160
|
+
"test_files/cabd/partial_nofiles.cab",
|
|
161
|
+
"test_files/cabd/partial_shortfile1.cab",
|
|
162
|
+
"test_files/cabd/partial_shortfile2.cab"
|
|
163
|
+
};
|
|
164
|
+
const char *str_files[] = {
|
|
165
|
+
"test_files/cabd/partial_str_nopname.cab",
|
|
166
|
+
"test_files/cabd/partial_str_shortpname.cab",
|
|
167
|
+
"test_files/cabd/partial_str_nopinfo.cab",
|
|
168
|
+
"test_files/cabd/partial_str_shortpinfo.cab",
|
|
169
|
+
"test_files/cabd/partial_str_nonname.cab",
|
|
170
|
+
"test_files/cabd/partial_str_shortnname.cab",
|
|
171
|
+
"test_files/cabd/partial_str_noninfo.cab",
|
|
172
|
+
"test_files/cabd/partial_str_shortninfo.cab",
|
|
173
|
+
"test_files/cabd/partial_str_nofname.cab",
|
|
174
|
+
"test_files/cabd/partial_str_shortfname.cab",
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
cabd = mspack_create_cab_decompressor(NULL);
|
|
178
|
+
TEST(cabd != NULL);
|
|
179
|
+
|
|
180
|
+
for (i = 0; i < (sizeof(files)/sizeof(char *)); i++) {
|
|
181
|
+
cab = cabd->open(cabd, files[i]);
|
|
182
|
+
TEST(cab == NULL);
|
|
183
|
+
TEST(cabd->last_error(cabd) == MSPACK_ERR_READ);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
for (i = 0; i < (sizeof(str_files)/sizeof(char *)); i++) {
|
|
187
|
+
cab = cabd->open(cabd, str_files[i]);
|
|
188
|
+
TEST(cab == NULL);
|
|
189
|
+
TEST(cabd->last_error(cabd) == MSPACK_ERR_DATAFORMAT);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* lack of data blocks should NOT be a problem for merely reading */
|
|
193
|
+
cab = cabd->open(cabd, "test_files/cabd/partial_nodata.cab");
|
|
194
|
+
TEST(cab != NULL);
|
|
195
|
+
|
|
196
|
+
cabd->close(cabd, cab);
|
|
197
|
+
mspack_destroy_cab_decompressor(cabd);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* open cab with 255 character filename (maximum allowed) */
|
|
201
|
+
void cabd_open_test_06() {
|
|
202
|
+
struct mscab_decompressor *cabd;
|
|
203
|
+
struct mscabd_cabinet *cab;
|
|
204
|
+
|
|
205
|
+
cabd = mspack_create_cab_decompressor(NULL);
|
|
206
|
+
TEST(cabd != NULL);
|
|
207
|
+
|
|
208
|
+
cab = cabd->open(cabd, "test_files/cabd/normal_255c_filename.cab");
|
|
209
|
+
TEST(cab != NULL);
|
|
210
|
+
|
|
211
|
+
cabd->close(cabd, cab);
|
|
212
|
+
mspack_destroy_cab_decompressor(cabd);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
/* open where search file doesn't exist */
|
|
217
|
+
void cabd_search_test_01() {
|
|
218
|
+
struct mscab_decompressor *cabd;
|
|
219
|
+
struct mscabd_cabinet *cab;
|
|
220
|
+
|
|
221
|
+
cabd = mspack_create_cab_decompressor(NULL);
|
|
222
|
+
TEST(cabd != NULL);
|
|
223
|
+
|
|
224
|
+
cab = cabd->search(cabd, "!!!FILE_WHICH_DOES_NOT_EXIST");
|
|
225
|
+
TEST(cab == NULL);
|
|
226
|
+
TEST(cabd->last_error(cabd) == MSPACK_ERR_OPEN);
|
|
227
|
+
|
|
228
|
+
mspack_destroy_cab_decompressor(cabd);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/* search file using 1-byte buffer */
|
|
232
|
+
void cabd_search_test_02() {
|
|
233
|
+
struct mscab_decompressor *cabd;
|
|
234
|
+
struct mscabd_cabinet *cab;
|
|
235
|
+
|
|
236
|
+
cabd = mspack_create_cab_decompressor(NULL);
|
|
237
|
+
TEST(cabd != NULL);
|
|
238
|
+
|
|
239
|
+
cabd->set_param(cabd, MSCABD_PARAM_SEARCHBUF, 1);
|
|
240
|
+
cab = cabd->search(cabd, "test_files/cabd/search_basic.cab");
|
|
241
|
+
cabd->set_param(cabd, MSCABD_PARAM_SEARCHBUF, 32768);
|
|
242
|
+
|
|
243
|
+
TEST(cab != NULL);
|
|
244
|
+
TEST(cab->files != NULL);
|
|
245
|
+
TEST(cab->base_offset == 6);
|
|
246
|
+
TEST(cab->files->next != NULL);
|
|
247
|
+
TEST(strcmp(cab->files->filename, "hello.c") == 0);
|
|
248
|
+
TEST(strcmp(cab->files->next->filename, "welcome.c") == 0);
|
|
249
|
+
|
|
250
|
+
TEST(cab->next != NULL);
|
|
251
|
+
TEST(cab->next->base_offset == 265);
|
|
252
|
+
TEST(cab->next->files != NULL);
|
|
253
|
+
TEST(cab->next->files->next != NULL);
|
|
254
|
+
TEST(strcmp(cab->next->files->filename, "hello.c") == 0);
|
|
255
|
+
TEST(strcmp(cab->next->files->next->filename, "welcome.c") == 0);
|
|
256
|
+
|
|
257
|
+
TEST(cab->next->next == NULL);
|
|
258
|
+
|
|
259
|
+
cabd->close(cabd, cab);
|
|
260
|
+
mspack_destroy_cab_decompressor(cabd);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/* tricky searches */
|
|
264
|
+
void cabd_search_test_03() {
|
|
265
|
+
struct mscab_decompressor *cabd;
|
|
266
|
+
struct mscabd_cabinet *cab;
|
|
267
|
+
|
|
268
|
+
cabd = mspack_create_cab_decompressor(NULL);
|
|
269
|
+
TEST(cabd != NULL);
|
|
270
|
+
|
|
271
|
+
/* there is only ONE cab in this file. it is prepended by 4 bytes, "MSCF"
|
|
272
|
+
* (heh) and reserved fields in the real cab are filled in so the fake one
|
|
273
|
+
* looks real to the scanner but not the real reader
|
|
274
|
+
*/
|
|
275
|
+
cab = cabd->search(cabd, "test_files/cabd/search_tricky1.cab");
|
|
276
|
+
TEST(cab != NULL);
|
|
277
|
+
TEST(cab->next == NULL);
|
|
278
|
+
TEST(cab->files != NULL);
|
|
279
|
+
TEST(cab->base_offset == 4);
|
|
280
|
+
TEST(cab->files->next != NULL);
|
|
281
|
+
TEST(strcmp(cab->files->filename, "hello.c") == 0);
|
|
282
|
+
TEST(strcmp(cab->files->next->filename, "welcome.c") == 0);
|
|
283
|
+
|
|
284
|
+
cabd->close(cabd, cab);
|
|
285
|
+
mspack_destroy_cab_decompressor(cabd);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* basic parameter failures */
|
|
289
|
+
void cabd_merge_test_01() {
|
|
290
|
+
struct mscab_decompressor *cabd;
|
|
291
|
+
struct mscabd_cabinet *cab1, *cab2;
|
|
292
|
+
|
|
293
|
+
cabd = mspack_create_cab_decompressor(NULL);
|
|
294
|
+
TEST(cabd != NULL);
|
|
295
|
+
|
|
296
|
+
cab1 = cabd->open(cabd, "test_files/cabd/multi_basic_pt1.cab");
|
|
297
|
+
cab2 = cabd->open(cabd, "test_files/cabd/multi_basic_pt2.cab");
|
|
298
|
+
TEST(cab1 != NULL);
|
|
299
|
+
TEST(cab2 != NULL);
|
|
300
|
+
TEST(cabd->append(cabd, cab1, NULL) != MSPACK_ERR_OK);
|
|
301
|
+
TEST(cabd->append(cabd, NULL, cab1) != MSPACK_ERR_OK);
|
|
302
|
+
TEST(cabd->append(cabd, cab1, cab1) != MSPACK_ERR_OK);
|
|
303
|
+
TEST(cabd->prepend(cabd, cab1, NULL) != MSPACK_ERR_OK);
|
|
304
|
+
TEST(cabd->prepend(cabd, NULL, cab1) != MSPACK_ERR_OK);
|
|
305
|
+
TEST(cabd->prepend(cabd, cab1, cab1) != MSPACK_ERR_OK);
|
|
306
|
+
|
|
307
|
+
/* merge cabs, then try merging again every other way */
|
|
308
|
+
TEST(cabd->append(cabd, cab1, cab2) == MSPACK_ERR_OK);
|
|
309
|
+
TEST(cabd->append(cabd, cab2, cab1) != MSPACK_ERR_OK);
|
|
310
|
+
TEST(cabd->prepend(cabd, cab1, cab2) != MSPACK_ERR_OK);
|
|
311
|
+
TEST(cabd->prepend(cabd, cab2, cab1) != MSPACK_ERR_OK);
|
|
312
|
+
TEST(cabd->append(cabd, cab1, cab2) != MSPACK_ERR_OK);
|
|
313
|
+
|
|
314
|
+
cabd->close(cabd, cab1);
|
|
315
|
+
mspack_destroy_cab_decompressor(cabd);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/* test merging a normal 5 part single folder cabinet set with slightly
|
|
319
|
+
* haphazard ordering. should still merge fine */
|
|
320
|
+
void cabd_merge_test_02() {
|
|
321
|
+
struct mscab_decompressor *cabd;
|
|
322
|
+
struct mscabd_cabinet *cab[5];
|
|
323
|
+
|
|
324
|
+
cabd = mspack_create_cab_decompressor(NULL);
|
|
325
|
+
TEST(cabd != NULL);
|
|
326
|
+
|
|
327
|
+
cab[0] = cabd->open(cabd, "test_files/cabd/multi_basic_pt1.cab");
|
|
328
|
+
cab[1] = cabd->open(cabd, "test_files/cabd/multi_basic_pt2.cab");
|
|
329
|
+
cab[2] = cabd->open(cabd, "test_files/cabd/multi_basic_pt3.cab");
|
|
330
|
+
cab[3] = cabd->open(cabd, "test_files/cabd/multi_basic_pt4.cab");
|
|
331
|
+
cab[4] = cabd->open(cabd, "test_files/cabd/multi_basic_pt5.cab");
|
|
332
|
+
TEST(cab[0] != NULL);
|
|
333
|
+
TEST(cab[1] != NULL);
|
|
334
|
+
TEST(cab[2] != NULL);
|
|
335
|
+
TEST(cab[3] != NULL);
|
|
336
|
+
TEST(cab[4] != NULL);
|
|
337
|
+
TEST(cabd->append(cabd, cab[0], cab[1]) == MSPACK_ERR_OK);
|
|
338
|
+
TEST(cabd->prepend(cabd, cab[2], cab[1]) == MSPACK_ERR_OK);
|
|
339
|
+
TEST(cabd->append(cabd, cab[3], cab[4]) == MSPACK_ERR_OK);
|
|
340
|
+
TEST(cabd->prepend(cabd, cab[3], cab[2]) == MSPACK_ERR_OK);
|
|
341
|
+
|
|
342
|
+
TEST(cab[0]->files != NULL);
|
|
343
|
+
TEST(cab[0]->files->next != NULL);
|
|
344
|
+
TEST(cab[0]->files->next->next != NULL);
|
|
345
|
+
TEST(cab[0]->files->next->next->next == NULL);
|
|
346
|
+
TEST(cab[0]->files == cab[1]->files);
|
|
347
|
+
TEST(cab[1]->files == cab[2]->files);
|
|
348
|
+
TEST(cab[2]->files == cab[3]->files);
|
|
349
|
+
TEST(cab[3]->files == cab[4]->files);
|
|
350
|
+
|
|
351
|
+
TEST(cab[0]->folders != NULL);
|
|
352
|
+
TEST(cab[0]->folders->next == NULL);
|
|
353
|
+
TEST(cab[0]->folders == cab[1]->folders);
|
|
354
|
+
TEST(cab[1]->folders == cab[2]->folders);
|
|
355
|
+
TEST(cab[2]->folders == cab[3]->folders);
|
|
356
|
+
TEST(cab[3]->folders == cab[4]->folders);
|
|
357
|
+
|
|
358
|
+
cabd->close(cabd, cab[0]);
|
|
359
|
+
mspack_destroy_cab_decompressor(cabd);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
int main() {
|
|
363
|
+
int selftest;
|
|
364
|
+
|
|
365
|
+
MSPACK_SYS_SELFTEST(selftest);
|
|
366
|
+
TEST(selftest == MSPACK_ERR_OK);
|
|
367
|
+
|
|
368
|
+
cabd_open_test_01();
|
|
369
|
+
cabd_open_test_02();
|
|
370
|
+
cabd_open_test_03();
|
|
371
|
+
cabd_open_test_04();
|
|
372
|
+
cabd_open_test_05();
|
|
373
|
+
cabd_open_test_06();
|
|
374
|
+
|
|
375
|
+
cabd_search_test_01();
|
|
376
|
+
cabd_search_test_02();
|
|
377
|
+
cabd_search_test_03();
|
|
378
|
+
|
|
379
|
+
cabd_merge_test_01();
|
|
380
|
+
cabd_merge_test_02();
|
|
381
|
+
|
|
382
|
+
/* extract() tests */
|
|
383
|
+
|
|
384
|
+
printf("ALL %d TESTS PASSED.\n", test_count);
|
|
385
|
+
return 0;
|
|
386
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#ifdef HAVE_CONFIG_H
|
|
2
|
+
#include <config.h>
|
|
3
|
+
#endif
|
|
4
|
+
|
|
5
|
+
#include <stdio.h>
|
|
6
|
+
#include <stdlib.h>
|
|
7
|
+
#include <sys/stat.h>
|
|
8
|
+
#include <mspack.h>
|
|
9
|
+
#include <system.h>
|
|
10
|
+
|
|
11
|
+
#define BUF_SIZE (1024*4096)
|
|
12
|
+
char buf[BUF_SIZE];
|
|
13
|
+
|
|
14
|
+
void rip(char *fname, off_t offset, unsigned int length) {
|
|
15
|
+
static unsigned int counter = 1;
|
|
16
|
+
struct stat st_buf;
|
|
17
|
+
char outname[13];
|
|
18
|
+
FILE *in, *out;
|
|
19
|
+
|
|
20
|
+
do {
|
|
21
|
+
snprintf(outname, 13, "%08u.cab", counter++);
|
|
22
|
+
} while (stat(outname, &st_buf) == 0);
|
|
23
|
+
|
|
24
|
+
printf("ripping %s offset %" LD " length %u to %s\n",
|
|
25
|
+
fname, offset, length, outname);
|
|
26
|
+
|
|
27
|
+
if ((in = fopen(fname, "rb"))) {
|
|
28
|
+
#ifdef HAVE_FSEEKO
|
|
29
|
+
if (!fseeko(in, offset, SEEK_SET)) {
|
|
30
|
+
#else
|
|
31
|
+
if (!fseek(in, offset, SEEK_SET)) {
|
|
32
|
+
#endif
|
|
33
|
+
if ((out = fopen(outname, "wb"))) {
|
|
34
|
+
while (length > 0) {
|
|
35
|
+
unsigned int run = BUF_SIZE;
|
|
36
|
+
if (run > length) run = length;
|
|
37
|
+
if (fread(&buf[0], 1, run, in) != run) {
|
|
38
|
+
perror(fname);
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
if (fwrite(&buf[0], 1, run, out) != run) {
|
|
42
|
+
perror(outname);
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
length -= run;
|
|
46
|
+
}
|
|
47
|
+
fclose(out);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
perror(outname);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
perror(fname);
|
|
55
|
+
}
|
|
56
|
+
fclose(in);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
perror(fname);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
int main(int argc, char *argv[]) {
|
|
64
|
+
struct mscab_decompressor *cabd;
|
|
65
|
+
struct mscabd_cabinet *cab, *c;
|
|
66
|
+
int err;
|
|
67
|
+
|
|
68
|
+
MSPACK_SYS_SELFTEST(err);
|
|
69
|
+
if (err) return 0;
|
|
70
|
+
|
|
71
|
+
if ((cabd = mspack_create_cab_decompressor(NULL))) {
|
|
72
|
+
for (argv++; *argv; argv++) {
|
|
73
|
+
if ((cab = cabd->search(cabd, *argv))) {
|
|
74
|
+
for (c = cab; c; c = c->next) rip(*argv, c->base_offset, c->length);
|
|
75
|
+
cabd->close(cabd, cab);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
mspack_destroy_cab_decompressor(cabd);
|
|
79
|
+
}
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Test if chmd_md5 expands chm files identically to Microsoft's HH.EXE -DECOMPILE
|
|
3
|
+
|
|
4
|
+
[ -d .cache ] || mkdir .cache
|
|
5
|
+
|
|
6
|
+
for chm in "$@"
|
|
7
|
+
do
|
|
8
|
+
echo "test $chm"
|
|
9
|
+
cached=`echo $chm | sed -e 's/\//-/g' -e 's/^/.cache\//'`
|
|
10
|
+
if [ ! -s $cached ]; then
|
|
11
|
+
./msdecompile_md5 $chm >.orig.out 2>.orig.err
|
|
12
|
+
if [ -s .orig.err ]; then
|
|
13
|
+
echo "FAIL $chm: MS errors" >&2
|
|
14
|
+
cat .orig.err >&2
|
|
15
|
+
else
|
|
16
|
+
sort -k2 .orig.out >$cached
|
|
17
|
+
fi
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
./chmd_md5 $chm >.test.out 2>.test.err
|
|
21
|
+
perl -pe 'if($.>1){$_=""if/^[0-9a-f]{32} \/[#\$]/;s{ /}{ }}' .test.out | sort -k2 >.test.sorted
|
|
22
|
+
if [ -s .test.err ]; then
|
|
23
|
+
echo "FAIL $chm: errors" >&2
|
|
24
|
+
cat .test.err >&2
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
if cmp $cached .test.sorted >/dev/null; then
|
|
28
|
+
echo "OK $chm"
|
|
29
|
+
else
|
|
30
|
+
if [ `diff $cached .test.sorted | grep -c '^<'` -gt 0 ]; then
|
|
31
|
+
echo "FAIL $chm: differences" >&2
|
|
32
|
+
diff -u $cached .test.sorted >&2
|
|
33
|
+
else
|
|
34
|
+
echo "OK $chm (better than hh.exe)"
|
|
35
|
+
fi
|
|
36
|
+
fi
|
|
37
|
+
done
|
|
38
|
+
rm -f .orig.out .orig.err .test.out .test.err .test.sorted
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/* chmd_find: tests fast-find functionality
|
|
2
|
+
*/
|
|
3
|
+
#ifdef HAVE_CONFIG_H
|
|
4
|
+
#include <config.h>
|
|
5
|
+
#endif
|
|
6
|
+
|
|
7
|
+
#include <stdio.h>
|
|
8
|
+
#include <stdlib.h>
|
|
9
|
+
#include <string.h>
|
|
10
|
+
#include <mspack.h>
|
|
11
|
+
|
|
12
|
+
#include <error.h>
|
|
13
|
+
#include <system.h>
|
|
14
|
+
|
|
15
|
+
void find(struct mschm_decompressor *chmd, struct mschmd_header *chm,
|
|
16
|
+
char *archive, char *filename, struct mschmd_file *compare)
|
|
17
|
+
{
|
|
18
|
+
struct mschmd_file result;
|
|
19
|
+
if (chmd->fast_find(chmd, chm, filename, &result, sizeof(result))) {
|
|
20
|
+
fprintf(stderr, "%s: find error on \"%s\": %s\n",
|
|
21
|
+
archive, filename, ERROR(chmd));
|
|
22
|
+
}
|
|
23
|
+
else if (!result.section) {
|
|
24
|
+
if (compare) {
|
|
25
|
+
fprintf(stderr, "%s: file \"%s\" not found\n", archive, filename);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
printf("%s: file \"%s\" not found\n", archive, filename);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
printf("%s\n", filename);
|
|
33
|
+
printf(" section: %d\n", result.section->id);
|
|
34
|
+
printf(" offset: %" LD "\n", result.offset);
|
|
35
|
+
printf(" length: %" LD "\n", result.length);
|
|
36
|
+
if (compare) {
|
|
37
|
+
if (result.section->id != compare->section->id) {
|
|
38
|
+
fprintf(stderr, "%s: found file \"%s\" section is wrong "
|
|
39
|
+
"(%d vs %d)\n", archive, filename,
|
|
40
|
+
result.section->id, compare->section->id);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (result.offset != compare->offset) {
|
|
44
|
+
fprintf(stderr, "%s: found file \"%s\" offset is wrong "
|
|
45
|
+
"(%" LD " vs %" LD ")\n", archive, filename,
|
|
46
|
+
result.offset, compare->offset);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (result.length != compare->length) {
|
|
50
|
+
fprintf(stderr, "%s: found file \"%s\" length is wrong "
|
|
51
|
+
"(%" LD " vs %" LD ")\n", archive, filename,
|
|
52
|
+
result.length, compare->length);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
int main(int argc, char *argv[]) {
|
|
59
|
+
struct mschm_decompressor *chmd;
|
|
60
|
+
struct mschmd_header *chm, *chm2;
|
|
61
|
+
unsigned int i;
|
|
62
|
+
|
|
63
|
+
if (argc < 2 || argc > 3) {
|
|
64
|
+
printf("Usage: %s <file.chm> [filename to find]\n", argv[0]);
|
|
65
|
+
return 1;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
MSPACK_SYS_SELFTEST(i);
|
|
69
|
+
if (i) return 0;
|
|
70
|
+
|
|
71
|
+
if ((chmd = mspack_create_chm_decompressor(NULL))) {
|
|
72
|
+
if ((chm = chmd->fast_open(chmd, argv[1]))) {
|
|
73
|
+
if (argv[2]) {
|
|
74
|
+
find(chmd, chm, argv[1], argv[2], NULL);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
if ((chm2 = chmd->open(chmd, argv[1]))) {
|
|
78
|
+
struct mschmd_file *file;
|
|
79
|
+
for (file = chm2->files; file; file = file->next) {
|
|
80
|
+
find(chmd, chm, argv[1], file->filename, file);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
printf("%s: can't open -- %s\n", argv[1], ERROR(chmd));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
chmd->close(chmd, chm);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
printf("%s: can't open -- %s\n", argv[1], ERROR(chmd));
|
|
91
|
+
}
|
|
92
|
+
mspack_destroy_chm_decompressor(chmd);
|
|
93
|
+
}
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#ifdef HAVE_CONFIG_H
|
|
2
|
+
#include <config.h>
|
|
3
|
+
#endif
|
|
4
|
+
|
|
5
|
+
#include <stdio.h>
|
|
6
|
+
#include <stdlib.h>
|
|
7
|
+
#include <string.h>
|
|
8
|
+
#include <mspack.h>
|
|
9
|
+
|
|
10
|
+
#include <md5_fh.h>
|
|
11
|
+
#include <error.h>
|
|
12
|
+
|
|
13
|
+
static int sortfunc(const void *a, const void *b) {
|
|
14
|
+
off_t diff =
|
|
15
|
+
((* ((struct mschmd_file **) a))->offset) -
|
|
16
|
+
((* ((struct mschmd_file **) b))->offset);
|
|
17
|
+
return (diff < 0) ? -1 : ((diff > 0) ? 1 : 0);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
int main(int argc, char *argv[]) {
|
|
21
|
+
struct mschm_decompressor *chmd;
|
|
22
|
+
struct mschmd_header *chm;
|
|
23
|
+
struct mschmd_file *file, **f;
|
|
24
|
+
unsigned int numf, i;
|
|
25
|
+
int err;
|
|
26
|
+
|
|
27
|
+
setbuf(stdout, NULL);
|
|
28
|
+
setbuf(stderr, NULL);
|
|
29
|
+
|
|
30
|
+
MSPACK_SYS_SELFTEST(err);
|
|
31
|
+
if (err) return 0;
|
|
32
|
+
|
|
33
|
+
if ((chmd = mspack_create_chm_decompressor(&read_files_write_md5))) {
|
|
34
|
+
for (argv++; *argv; argv++) {
|
|
35
|
+
printf("*** %s\n", *argv);
|
|
36
|
+
if ((chm = chmd->open(chmd, *argv))) {
|
|
37
|
+
|
|
38
|
+
/* extract in order of the offset into content section - faster */
|
|
39
|
+
for (numf=0, file=chm->files; file; file = file->next) numf++;
|
|
40
|
+
if ((f = (struct mschmd_file **) calloc(numf, sizeof(struct mschmd_file *)))) {
|
|
41
|
+
for (i=0, file=chm->files; file; file = file->next) f[i++] = file;
|
|
42
|
+
qsort(f, numf, sizeof(struct mschmd_file *), &sortfunc);
|
|
43
|
+
for (i = 0; i < numf; i++) {
|
|
44
|
+
if (chmd->extract(chmd, f[i], NULL)) {
|
|
45
|
+
fprintf(stderr, "%s: extract error on \"%s\": %s\n",
|
|
46
|
+
*argv, f[i]->filename, ERROR(chmd));
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
printf("%s %s\n", md5_string, f[i]->filename);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
free(f);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
chmd->close(chmd, chm);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
fprintf(stderr, "%s: can't open -- %s\n", *argv, ERROR(chmd));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
mspack_destroy_chm_decompressor(chmd);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
fprintf(stderr, "%s: can't make CHM decompressor\n", *argv);
|
|
65
|
+
}
|
|
66
|
+
return 0;
|
|
67
|
+
}
|