18
18
* MA 02110-1301, USA.
21
/* a cleaner state interface to LZMA */
21
/* zlib-alike state interface to LZMA */
24
#include "clamav-config.h"
24
27
#include "lzma_iface.h"
25
#include "LzmaStateDecode.h"
28
/* we don't need zlib, and zlib defines Byte, that lzma also defines.
29
* Enabling prefixes for zlib types avoids problems, and since
30
* we don't call any zlib functions here avoids unresolved symbols too */
35
CLzmaDecoderState state;
36
unsigned char *next_in;
38
unsigned char *next_out;
44
int cli_LzmaInit(CLI_LZMA **Lp, uint64_t size_override) {
48
*Lp = L = cli_calloc(sizeof(*L), 1);
55
if(size_override) L->usize=size_override;
57
if (!L->next_in || L->avail_in < LZMA_PROPERTIES_SIZE + 8) return LZMA_RESULT_OK;
58
if (LzmaDecodeProperties(&L->state.Properties, L->next_in, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
59
return LZMA_RESULT_DATA_ERROR;
61
L->next_in += LZMA_PROPERTIES_SIZE;
62
L->avail_in -= LZMA_PROPERTIES_SIZE;
65
L->usize=(uint64_t)cli_readint32(L->next_in) + ((uint64_t)cli_readint32(L->next_in+4)<<32);
29
void *__lzma_wrap_alloc(void *unused, size_t size) {
31
return cli_malloc(size);
33
void __lzma_wrap_free(void *unused, void *freeme) {
37
static ISzAlloc g_Alloc = { __lzma_wrap_alloc, __lzma_wrap_free };
40
static unsigned char lzma_getbyte(struct CLI_LZMA *L, int *fail) {
42
if(!L->next_in || !L->avail_in) {
70
if (!(L->state.Probs = (CProb *)cli_malloc(LzmaGetNumProbs(&L->state.Properties) * sizeof(CProb))))
71
return LZMA_RESULT_DATA_ERROR;
73
if (!(L->state.Dictionary = (unsigned char *)cli_malloc(L->state.Properties.DictionarySize))) {
75
return LZMA_RESULT_DATA_ERROR;
80
LzmaDecoderInit(&L->state);
81
return LZMA_RESULT_OK;
84
void cli_LzmaShutdown(CLI_LZMA **Lp) {
90
if(L->state.Probs) free(L->state.Probs);
91
if(L->state.Dictionary) free(L->state.Dictionary);
98
int cli_LzmaDecode(CLI_LZMA **Lp, struct stream_state* state) {
100
SizeT processed_in, processed_out;
104
L->avail_in = state->avail_in;
105
L->next_in = state->next_in;
106
L->avail_out = state->avail_out;
107
L->next_out = state->next_out;
110
if (!L || !L->initted) {
111
if(cli_LzmaInit(Lp, 0) != LZMA_RESULT_OK)
112
return LZMA_RESULT_DATA_ERROR;
117
res = LzmaDecode(&L->state, L->next_in, L->avail_in, &processed_in, L->next_out, L->avail_out, &processed_out, (L->avail_in==0));
119
L->next_in += processed_in;
120
L->avail_in -= processed_in;
121
L->next_out += processed_out;
122
L->avail_out -= processed_out;
124
state->avail_in = L->avail_in;
125
state->next_in = L->next_in;
126
state->avail_out = L->avail_out;
127
state->next_out = L->next_out;
132
int cli_LzmaInitUPX(CLI_LZMA **Lp, uint32_t dictsz) {
136
*Lp = L = cli_calloc(sizeof(*L), 1);
138
return LZMA_RESULT_DATA_ERROR;
142
L->state.Properties.pb = 2; /* FIXME: these */
143
L->state.Properties.lp = 0; /* values may */
144
L->state.Properties.lc = 3; /* not be static */
146
L->state.Properties.DictionarySize = dictsz;
148
if (!(L->state.Probs = (CProb *)cli_malloc(LzmaGetNumProbs(&L->state.Properties) * sizeof(CProb))))
149
return LZMA_RESULT_DATA_ERROR;
151
if (!(L->state.Dictionary = (unsigned char *)cli_malloc(L->state.Properties.DictionarySize))) {
152
free(L->state.Probs);
153
return LZMA_RESULT_DATA_ERROR;
158
LzmaDecoderInit(&L->state);
159
return LZMA_RESULT_OK;
54
int cli_LzmaInit(struct CLI_LZMA *L, uint64_t size_override) {
58
L->p_cnt = LZMA_PROPS_SIZE;
60
L->usize = size_override;
64
} else if(size_override)
65
cli_warnmsg("cli_LzmaInit: ignoring late size override\n");
67
if(L->freeme) return LZMA_RESULT_OK;
70
L->header[LZMA_PROPS_SIZE - L->p_cnt] = lzma_getbyte(L, &fail);
71
if(fail) return LZMA_RESULT_OK;
76
uint64_t c = (uint64_t)lzma_getbyte(L, &fail);
77
if(fail) return LZMA_RESULT_OK;
78
L->usize = c << (8 * (8 - L->s_cnt));
82
LzmaDec_Construct(&L->state);
83
if(LzmaDec_Allocate(&L->state, L->header, LZMA_PROPS_SIZE, &g_Alloc) != SZ_OK)
84
return LZMA_RESULT_DATA_ERROR;
85
LzmaDec_Init(&L->state);
88
return LZMA_RESULT_OK;
92
void cli_LzmaShutdown(struct CLI_LZMA *L) {
94
LzmaDec_Free(&L->state, &g_Alloc);
99
int cli_LzmaDecode(struct CLI_LZMA *L) {
101
SizeT outbytes, inbytes;
103
ELzmaFinishMode finish;
105
if(!L->freeme) return cli_LzmaInit(L, 0);
107
inbytes = L->avail_in;
108
if(~L->usize && L->avail_out > L->usize) {
110
finish = LZMA_FINISH_END;
112
outbytes = L->avail_out;
113
finish = LZMA_FINISH_ANY;
115
res = LzmaDec_DecodeToBuf(&L->state, L->next_out, &outbytes, L->next_in, &inbytes, finish, &status);
116
L->avail_in -= inbytes;
117
L->next_in += inbytes;
118
L->avail_out -= outbytes;
119
L->next_out += outbytes;
120
if(~L->usize) L->usize -= outbytes;
122
return LZMA_RESULT_DATA_ERROR;
123
if(!L->usize || status == LZMA_STATUS_FINISHED_WITH_MARK)
124
return LZMA_STREAM_END;
125
return LZMA_RESULT_OK;