ClamAV is an open source (GPLv2) anti-virus toolkit.
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.
 
 
 
 
 
 
clamav/libclamav/lzma_iface.c

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;
}