-
Notifications
You must be signed in to change notification settings - Fork 0
/
unpgzmod.c
39 lines (38 loc) · 988 Bytes
/
unpgzmod.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "unpgzmod.h"
#include "crc32mod.h"
#include "SysToolX.h"
#include "zlibpuff/puff.h"
BYTE *GZUnpack(BYTE *p, DWORD sz) {
gzf_head *gh;
gzf_tail *gt;
DWORD us, ps;
BYTE *u;
int c;
u = NULL;
// minimal gz file headers size
sz -= min(sz, (sizeof(gh[0]) + sizeof(gt[0])));
gh = (gzf_head *) p;
// sanity check
if (p && sz && (gh->magic == GZ_MAGIC) && (gh->ctype == GZ_DEFLATE)) {
// TODO: maybe add full support for gh->flags and gh->flagx (skip additional fields) ?
p += sizeof(gh[0]);
us = 0;
ps = sz;
c = puff(NULL, &us, p, &ps);
gt = (gzf_tail *) &p[ps];
// sanity check
if ((c >= 0) && (ps <= sz) && (us > 0) && (gt->usize == us)) {
u = (BYTE *) GetMem(us + sizeof(us));
if (u) {
*((DWORD *) u) = us;
puff(&u[sizeof(us)], &us, p, &ps);
// sanity check
if (CRC32Buffer(&u[sizeof(us)], us) != gt->crc32) {
FreeMem(u);
u = NULL;
}
}
}
}
return(u);
}