libmspack 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/README.md +75 -0
  7. data/Rakefile +22 -0
  8. data/UNLICENSE +24 -0
  9. data/ext/Rakefile +16 -0
  10. data/ext/i386-windows/libmspack.dll +0 -0
  11. data/ext/libmspack/AUTHORS +12 -0
  12. data/ext/libmspack/COPYING.LIB +504 -0
  13. data/ext/libmspack/ChangeLog +491 -0
  14. data/ext/libmspack/Makefile.am +100 -0
  15. data/ext/libmspack/NEWS +0 -0
  16. data/ext/libmspack/README +130 -0
  17. data/ext/libmspack/TODO +8 -0
  18. data/ext/libmspack/cleanup.sh +9 -0
  19. data/ext/libmspack/configure.ac +50 -0
  20. data/ext/libmspack/debian/changelog +6 -0
  21. data/ext/libmspack/debian/control +14 -0
  22. data/ext/libmspack/debian/rules +101 -0
  23. data/ext/libmspack/doc/Doxyfile.in +22 -0
  24. data/ext/libmspack/doc/Makefile.in +14 -0
  25. data/ext/libmspack/doc/szdd_kwaj_format.html +331 -0
  26. data/ext/libmspack/libmspack.pc.in +10 -0
  27. data/ext/libmspack/mspack/cab.h +127 -0
  28. data/ext/libmspack/mspack/cabc.c +24 -0
  29. data/ext/libmspack/mspack/cabd.c +1444 -0
  30. data/ext/libmspack/mspack/chm.h +122 -0
  31. data/ext/libmspack/mspack/chmc.c +24 -0
  32. data/ext/libmspack/mspack/chmd.c +1392 -0
  33. data/ext/libmspack/mspack/crc32.c +95 -0
  34. data/ext/libmspack/mspack/crc32.h +17 -0
  35. data/ext/libmspack/mspack/des.h +15 -0
  36. data/ext/libmspack/mspack/hlp.h +33 -0
  37. data/ext/libmspack/mspack/hlpc.c +24 -0
  38. data/ext/libmspack/mspack/hlpd.c +24 -0
  39. data/ext/libmspack/mspack/kwaj.h +118 -0
  40. data/ext/libmspack/mspack/kwajc.c +24 -0
  41. data/ext/libmspack/mspack/kwajd.c +561 -0
  42. data/ext/libmspack/mspack/lit.h +35 -0
  43. data/ext/libmspack/mspack/litc.c +24 -0
  44. data/ext/libmspack/mspack/litd.c +24 -0
  45. data/ext/libmspack/mspack/lzss.h +66 -0
  46. data/ext/libmspack/mspack/lzssd.c +93 -0
  47. data/ext/libmspack/mspack/lzx.h +221 -0
  48. data/ext/libmspack/mspack/lzxc.c +18 -0
  49. data/ext/libmspack/mspack/lzxd.c +895 -0
  50. data/ext/libmspack/mspack/mspack.def +28 -0
  51. data/ext/libmspack/mspack/mspack.h +2353 -0
  52. data/ext/libmspack/mspack/mszip.h +126 -0
  53. data/ext/libmspack/mspack/mszipc.c +18 -0
  54. data/ext/libmspack/mspack/mszipd.c +514 -0
  55. data/ext/libmspack/mspack/oab.h +60 -0
  56. data/ext/libmspack/mspack/oabc.c +24 -0
  57. data/ext/libmspack/mspack/oabd.c +408 -0
  58. data/ext/libmspack/mspack/qtm.h +128 -0
  59. data/ext/libmspack/mspack/qtmc.c +18 -0
  60. data/ext/libmspack/mspack/qtmd.c +489 -0
  61. data/ext/libmspack/mspack/readbits.h +207 -0
  62. data/ext/libmspack/mspack/readhuff.h +173 -0
  63. data/ext/libmspack/mspack/sha.h +15 -0
  64. data/ext/libmspack/mspack/system.c +239 -0
  65. data/ext/libmspack/mspack/system.h +124 -0
  66. data/ext/libmspack/mspack/szdd.h +39 -0
  67. data/ext/libmspack/mspack/szddc.c +24 -0
  68. data/ext/libmspack/mspack/szddd.c +247 -0
  69. data/ext/libmspack/rebuild.sh +8 -0
  70. data/ext/libmspack/test/cabd_c10 +19 -0
  71. data/ext/libmspack/test/cabd_compare +34 -0
  72. data/ext/libmspack/test/cabd_md5.c +161 -0
  73. data/ext/libmspack/test/cabd_memory.c +179 -0
  74. data/ext/libmspack/test/cabd_test.c +386 -0
  75. data/ext/libmspack/test/cabrip.c +81 -0
  76. data/ext/libmspack/test/chmd_compare +38 -0
  77. data/ext/libmspack/test/chmd_find.c +95 -0
  78. data/ext/libmspack/test/chmd_md5.c +67 -0
  79. data/ext/libmspack/test/chmd_order.c +144 -0
  80. data/ext/libmspack/test/chminfo.c +284 -0
  81. data/ext/libmspack/test/chmx.c +216 -0
  82. data/ext/libmspack/test/error.h +22 -0
  83. data/ext/libmspack/test/expand.c +79 -0
  84. data/ext/libmspack/test/md5.c +457 -0
  85. data/ext/libmspack/test/md5.h +165 -0
  86. data/ext/libmspack/test/md5_fh.h +123 -0
  87. data/ext/libmspack/test/msdecompile_md5 +24 -0
  88. data/ext/libmspack/test/msexpand_md5 +39 -0
  89. data/ext/libmspack/test/multifh.c +435 -0
  90. data/ext/libmspack/test/oabx.c +41 -0
  91. data/ext/libmspack/test/test_files/cabd/1.pl +84 -0
  92. data/ext/libmspack/test/test_files/cabd/2.pl +75 -0
  93. data/ext/libmspack/test/test_files/cabd/bad_folderindex.cab +0 -0
  94. data/ext/libmspack/test/test_files/cabd/bad_nofiles.cab +0 -0
  95. data/ext/libmspack/test/test_files/cabd/bad_nofolders.cab +0 -0
  96. data/ext/libmspack/test/test_files/cabd/bad_signature.cab +0 -0
  97. data/ext/libmspack/test/test_files/cabd/multi_basic_pt1.cab +0 -0
  98. data/ext/libmspack/test/test_files/cabd/multi_basic_pt2.cab +0 -0
  99. data/ext/libmspack/test/test_files/cabd/multi_basic_pt3.cab +0 -0
  100. data/ext/libmspack/test/test_files/cabd/multi_basic_pt4.cab +0 -0
  101. data/ext/libmspack/test/test_files/cabd/multi_basic_pt5.cab +0 -0
  102. data/ext/libmspack/test/test_files/cabd/normal_255c_filename.cab +0 -0
  103. data/ext/libmspack/test/test_files/cabd/normal_2files_1folder.cab +0 -0
  104. data/ext/libmspack/test/test_files/cabd/partial_nodata.cab +0 -0
  105. data/ext/libmspack/test/test_files/cabd/partial_nofiles.cab +0 -0
  106. data/ext/libmspack/test/test_files/cabd/partial_nofolder.cab +0 -0
  107. data/ext/libmspack/test/test_files/cabd/partial_shortextheader.cab +0 -0
  108. data/ext/libmspack/test/test_files/cabd/partial_shortfile1.cab +0 -0
  109. data/ext/libmspack/test/test_files/cabd/partial_shortfile2.cab +0 -0
  110. data/ext/libmspack/test/test_files/cabd/partial_shortfolder.cab +0 -0
  111. data/ext/libmspack/test/test_files/cabd/partial_shortheader.cab +0 -0
  112. data/ext/libmspack/test/test_files/cabd/partial_str_nofname.cab +0 -0
  113. data/ext/libmspack/test/test_files/cabd/partial_str_noninfo.cab +0 -0
  114. data/ext/libmspack/test/test_files/cabd/partial_str_nonname.cab +0 -0
  115. data/ext/libmspack/test/test_files/cabd/partial_str_nopinfo.cab +0 -0
  116. data/ext/libmspack/test/test_files/cabd/partial_str_nopname.cab +0 -0
  117. data/ext/libmspack/test/test_files/cabd/partial_str_shortfname.cab +0 -0
  118. data/ext/libmspack/test/test_files/cabd/partial_str_shortninfo.cab +0 -0
  119. data/ext/libmspack/test/test_files/cabd/partial_str_shortnname.cab +0 -0
  120. data/ext/libmspack/test/test_files/cabd/partial_str_shortpinfo.cab +0 -0
  121. data/ext/libmspack/test/test_files/cabd/partial_str_shortpname.cab +0 -0
  122. data/ext/libmspack/test/test_files/cabd/reserve_---.cab +0 -0
  123. data/ext/libmspack/test/test_files/cabd/reserve_--D.cab +0 -0
  124. data/ext/libmspack/test/test_files/cabd/reserve_-F-.cab +0 -0
  125. data/ext/libmspack/test/test_files/cabd/reserve_-FD.cab +0 -0
  126. data/ext/libmspack/test/test_files/cabd/reserve_H--.cab +0 -0
  127. data/ext/libmspack/test/test_files/cabd/reserve_H-D.cab +0 -0
  128. data/ext/libmspack/test/test_files/cabd/reserve_HF-.cab +0 -0
  129. data/ext/libmspack/test/test_files/cabd/reserve_HFD.cab +0 -0
  130. data/ext/libmspack/test/test_files/cabd/search_basic.cab +0 -0
  131. data/ext/libmspack/test/test_files/cabd/search_tricky1.cab +0 -0
  132. data/ext/libmspack/winbuild.sh +26 -0
  133. data/ext/x86_64-windows/libmspack.dll +0 -0
  134. data/lib/libmspack/constants.rb +9 -0
  135. data/lib/libmspack/exceptions.rb +12 -0
  136. data/lib/libmspack/mscab.rb +722 -0
  137. data/lib/libmspack/mschm.rb +301 -0
  138. data/lib/libmspack/mshlp.rb +15 -0
  139. data/lib/libmspack/mskwaj.rb +124 -0
  140. data/lib/libmspack/mslit.rb +18 -0
  141. data/lib/libmspack/msoab.rb +36 -0
  142. data/lib/libmspack/mspack.rb +208 -0
  143. data/lib/libmspack/msszdd.rb +81 -0
  144. data/lib/libmspack/system.rb +84 -0
  145. data/lib/libmspack/version.rb +4 -0
  146. data/lib/libmspack.rb +121 -0
  147. data/libmspack.gemspec +33 -0
  148. data/spec/libmspack_spec.rb +26 -0
  149. data/spec/spec_helper.rb +5 -0
  150. 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
+ }