diff options
author | liblzma upstream <xz-devel@tukaani.org> | 2013-06-30 16:55:49 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2014-07-21 18:30:16 (GMT) |
commit | c289e63491982dd8aed7c6b6f54d390df91aaf95 (patch) | |
tree | 30ec0cd68d34ac054c6db4d007dbc8aa58f9da23 /liblzma/common/vli_decoder.c | |
download | CMake-c289e63491982dd8aed7c6b6f54d390df91aaf95.zip CMake-c289e63491982dd8aed7c6b6f54d390df91aaf95.tar.gz CMake-c289e63491982dd8aed7c6b6f54d390df91aaf95.tar.bz2 |
liblzma 5.0.5-gb69900ed (reduced)
Extract upstream liblzma using the following shell code.
url=http://git.tukaani.org/xz.git &&
v=5.0.5 &&
r=b69900ed &&
paths="
COPYING
src/common/common_w32res.rc
src/common/sysdefs.h
src/common/tuklib_integer.h
src/liblzma
" &&
mkdir liblzma-$v-g$r-reduced &&
git clone $url liblzma-git &&
date=$(cd liblzma-git && git log -n 1 --format='%cd' $r) &&
(cd liblzma-git && git archive --format=tar $r -- $paths) |
(cd liblzma-$v-g$r-reduced && tar xv &&
mv src/* . && rmdir src) &&
echo "g$r date: $date"
Diffstat (limited to 'liblzma/common/vli_decoder.c')
-rw-r--r-- | liblzma/common/vli_decoder.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/liblzma/common/vli_decoder.c b/liblzma/common/vli_decoder.c new file mode 100644 index 0000000..c181828 --- /dev/null +++ b/liblzma/common/vli_decoder.c @@ -0,0 +1,86 @@ +/////////////////////////////////////////////////////////////////////////////// +// +/// \file vli_decoder.c +/// \brief Decodes variable-length integers +// +// Author: Lasse Collin +// +// This file has been put into the public domain. +// You can do whatever you want with this file. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "common.h" + + +extern LZMA_API(lzma_ret) +lzma_vli_decode(lzma_vli *restrict vli, size_t *vli_pos, + const uint8_t *restrict in, size_t *restrict in_pos, + size_t in_size) +{ + // If we haven't been given vli_pos, work in single-call mode. + size_t vli_pos_internal = 0; + if (vli_pos == NULL) { + vli_pos = &vli_pos_internal; + *vli = 0; + + // If there's no input, use LZMA_DATA_ERROR. This way it is + // easy to decode VLIs from buffers that have known size, + // and get the correct error code in case the buffer is + // too short. + if (*in_pos >= in_size) + return LZMA_DATA_ERROR; + + } else { + // Initialize *vli when starting to decode a new integer. + if (*vli_pos == 0) + *vli = 0; + + // Validate the arguments. + if (*vli_pos >= LZMA_VLI_BYTES_MAX + || (*vli >> (*vli_pos * 7)) != 0) + return LZMA_PROG_ERROR;; + + if (*in_pos >= in_size) + return LZMA_BUF_ERROR; + } + + do { + // Read the next byte. Use a temporary variable so that we + // can update *in_pos immediately. + const uint8_t byte = in[*in_pos]; + ++*in_pos; + + // Add the newly read byte to *vli. + *vli += (lzma_vli)(byte & 0x7F) << (*vli_pos * 7); + ++*vli_pos; + + // Check if this is the last byte of a multibyte integer. + if ((byte & 0x80) == 0) { + // We don't allow using variable-length integers as + // padding i.e. the encoding must use the most the + // compact form. + if (byte == 0x00 && *vli_pos > 1) + return LZMA_DATA_ERROR; + + return vli_pos == &vli_pos_internal + ? LZMA_OK : LZMA_STREAM_END; + } + + // There is at least one more byte coming. If we have already + // read maximum number of bytes, the integer is considered + // corrupt. + // + // If we need bigger integers in future, old versions liblzma + // will confusingly indicate the file being corrupt istead of + // unsupported. I suppose it's still better this way, because + // in the foreseeable future (writing this in 2008) the only + // reason why files would appear having over 63-bit integers + // is that the files are simply corrupt. + if (*vli_pos == LZMA_VLI_BYTES_MAX) + return LZMA_DATA_ERROR; + + } while (*in_pos < in_size); + + return vli_pos == &vli_pos_internal ? LZMA_DATA_ERROR : LZMA_OK; +} |