mirror of https://github.com/Cisco-Talos/clamav
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.4 KiB
129 lines
3.4 KiB
/*
|
|
* Copyright (C) 2007 Sourcefire Inc.
|
|
* Author: aCaB <acab@clamav.net>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*/
|
|
|
|
/* a cleaner state interface to LZMA */
|
|
|
|
|
|
#include "lzma_iface.h"
|
|
#include "LzmaStateDecode.h"
|
|
#include "cltypes.h"
|
|
|
|
/* we don't need zlib, and zlib defines Byte, that lzma also defines.
|
|
* Enabling prefixes for zlib types avoids problems, and since
|
|
* we don't call any zlib functions here avoids unresolved symbols too */
|
|
#define Z_PREFIX
|
|
#include "others.h"
|
|
|
|
struct CLI_LZMA_tag {
|
|
CLzmaDecoderState state;
|
|
unsigned char *next_in;
|
|
SizeT avail_in;
|
|
unsigned char *next_out;
|
|
SizeT avail_out;
|
|
int initted;
|
|
uint64_t usize;
|
|
};
|
|
|
|
int cli_LzmaInit(CLI_LZMA **Lp, uint64_t size_override) {
|
|
CLI_LZMA *L = *Lp;
|
|
|
|
if(!L) {
|
|
*Lp = L = cli_calloc(sizeof(*L), 1);
|
|
if(!L) {
|
|
return CL_EMEM;
|
|
}
|
|
}
|
|
|
|
L->initted = 0;
|
|
if(size_override) L->usize=size_override;
|
|
|
|
if (!L->next_in || L->avail_in < LZMA_PROPERTIES_SIZE + 8) return LZMA_RESULT_OK;
|
|
if (LzmaDecodeProperties(&L->state.Properties, L->next_in, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
|
|
return LZMA_RESULT_DATA_ERROR;
|
|
|
|
L->next_in += LZMA_PROPERTIES_SIZE;
|
|
L->avail_in -= LZMA_PROPERTIES_SIZE;
|
|
|
|
if (!L->usize) {
|
|
L->usize=(uint64_t)cli_readint32(L->next_in) + ((uint64_t)cli_readint32(L->next_in+4)<<32);
|
|
L->next_in += 8;
|
|
L->avail_in -= 8;
|
|
}
|
|
|
|
if (!(L->state.Probs = (CProb *)cli_malloc(LzmaGetNumProbs(&L->state.Properties) * sizeof(CProb))))
|
|
return LZMA_RESULT_DATA_ERROR;
|
|
|
|
if (!(L->state.Dictionary = (unsigned char *)cli_malloc(L->state.Properties.DictionarySize))) {
|
|
free(L->state.Probs);
|
|
return LZMA_RESULT_DATA_ERROR;
|
|
}
|
|
|
|
L->initted = 1;
|
|
|
|
LzmaDecoderInit(&L->state);
|
|
return LZMA_RESULT_OK;
|
|
}
|
|
|
|
void cli_LzmaShutdown(CLI_LZMA **Lp) {
|
|
CLI_LZMA *L;
|
|
|
|
if(!Lp) return;
|
|
L = *Lp;
|
|
if(L->initted) {
|
|
if(L->state.Probs) free(L->state.Probs);
|
|
if(L->state.Dictionary) free(L->state.Dictionary);
|
|
}
|
|
free(L);
|
|
*Lp = NULL;
|
|
return;
|
|
}
|
|
|
|
int cli_LzmaDecode(CLI_LZMA **Lp, struct stream_state* state) {
|
|
int res;
|
|
SizeT processed_in, processed_out;
|
|
CLI_LZMA* L = *Lp;
|
|
|
|
if(L) {
|
|
L->avail_in = state->avail_in;
|
|
L->next_in = state->next_in;
|
|
L->avail_out = state->avail_out;
|
|
L->next_out = state->next_out;
|
|
}
|
|
|
|
if (!L || !L->initted) {
|
|
if(cli_LzmaInit(Lp, 0) != LZMA_RESULT_OK)
|
|
return LZMA_RESULT_DATA_ERROR;
|
|
L = *Lp;
|
|
}
|
|
|
|
|
|
res = LzmaDecode(&L->state, L->next_in, L->avail_in, &processed_in, L->next_out, L->avail_out, &processed_out, (L->avail_in==0));
|
|
|
|
L->next_in += processed_in;
|
|
L->avail_in -= processed_in;
|
|
L->next_out += processed_out;
|
|
L->avail_out -= processed_out;
|
|
|
|
state->avail_in = L->avail_in;
|
|
state->next_in = L->next_in;
|
|
state->avail_out = L->avail_out;
|
|
state->next_out = L->next_out;
|
|
|
|
return res;
|
|
}
|
|
|