Index: xz/src/liblzma/common/vli_decoder.c |
=================================================================== |
--- xz/src/liblzma/common/vli_decoder.c (revision 0) |
+++ xz/src/liblzma/common/vli_decoder.c (revision 0) |
@@ -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; |
+} |
Property changes on: xz/src/liblzma/common/vli_decoder.c |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |