coderforlife / ms-compress

Open source implementations of Microsoft compression algorithms
205 stars 46 forks source link

Decompressing to undersized buffer with lznt1 returns DATA_ERROR not BUF_ERROR #17

Closed nemequ closed 9 years ago

nemequ commented 9 years ago

When I decompress some data to a buffer which is 1 byte too small (using ms_decompress(MSCOMP_LZNT1, …)) I get MSCOMP_DATA_ERROR (-3) instead of MSCOMP_BUF_ERROR (-5).

xpress and xpress-huffman work as expected.

nemequ commented 9 years ago

Test case (just change CODEC_TO_TEST to MSCOMP_XPRESS or MSCOMP_XPRESS_HUFF and it will work as expected:

#include "mscomp.h"

#include <stdio.h>
#include <assert.h>
#include <assert.h>
#include <stdint.h>

#define CODEC_TO_TEST MSCOMP_LZNT1

#define LOREM_IPSUM (uint8_t*)                      \
  "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vulputate " \
  "lectus nisl, vitae ultricies justo dictum nec. Vestibulum ante ipsum " \
  "primis in faucibus orci luctus et ultrices posuere cubilia Curae; "  \
  "Suspendisse suscipit quam a lectus adipiscing, sed tempor purus "    \
  "cursus. Vivamus id nulla eget elit eleifend molestie. Integer "      \
  "sollicitudin lorem enim, eu eleifend orci facilisis sed. Pellentesque " \
  "sodales luctus enim vel viverra. Cras interdum vel nisl in "         \
  "facilisis. Curabitur sollicitudin tortor vel congue "                \
  "auctor. Suspendisse egestas orci vitae neque placerat blandit.\n"    \
  "\n"                                                                  \
  "Aenean sed nisl ultricies, vulputate lorem a, suscipit nulla. Donec " \
  "egestas volutpat neque a eleifend. Nullam porta semper "             \
  "nunc. Pellentesque adipiscing molestie magna, quis pulvinar metus "  \
  "gravida sit amet. Vestibulum mollis et sapien eu posuere. Quisque "  \
  "tristique dignissim ante et aliquet. Phasellus vulputate condimentum " \
  "nulla in vulputate.\n"                                               \
  "\n"                                                                  \
  "Nullam volutpat tellus at nisi auctor, vitae mattis nibh viverra. Nunc " \
  "vitae lectus tristique, ultrices nibh quis, lobortis elit. Curabitur " \
  "at vestibulum nisi, nec facilisis ante. Nulla pharetra blandit lacus, " \
  "at sodales nulla placerat eget. Nulla congue varius tortor, sit amet " \
  "tempor est mattis nec. Praesent vitae tristique ipsum, rhoncus "     \
  "tristique lorem. Sed et erat tristique ligula accumsan fringilla eu in " \
  "urna. Donec dapibus hendrerit neque nec venenatis. In euismod sapien " \
  "ipsum, auctor consectetur mi dapibus hendrerit.\n"                   \
  "\n"                                                                  \
  "Phasellus sagittis rutrum velit, in sodales nibh imperdiet a. Integer " \
  "vitae arcu blandit nibh laoreet scelerisque eu sit amet eros. Aenean " \
  "odio felis, aliquam in eros at, ornare luctus magna. In semper "     \
  "tincidunt nunc, sollicitudin gravida nunc laoreet eu. Cras eu tempor " \
  "sapien, ut dignissim elit. Proin eleifend arcu tempus, semper erat et, " \
  "accumsan erat. Praesent vulputate diam mi, eget mollis leo "         \
  "pellentesque eget. Aliquam eu tortor posuere, posuere velit sed, "   \
  "suscipit eros. Nam eu leo vitae mauris condimentum lobortis non quis " \
  "mauris. Nulla venenatis fringilla urna nec venenatis. Nam eget velit " \
  "nulla. Proin ut malesuada felis. Suspendisse vitae nunc neque. Donec " \
  "faucibus tempor lacinia. Vivamus ac vulputate sapien, eget lacinia " \
  "nisl.\n"                                                             \
  "\n"                                                                  \
  "Curabitur eu dolor molestie, ullamcorper lorem quis, egestas "       \
  "urna. Suspendisse in arcu sed justo blandit condimentum. Ut auctor, " \
  "sem quis condimentum mattis, est purus pulvinar elit, quis viverra " \
  "nibh metus ac diam. Etiam aliquet est eu dui fermentum consequat. Cras " \
  "auctor diam eget bibendum sagittis. Aenean elementum purus sit amet " \
  "sem euismod, non varius felis dictum. Aliquam tempus pharetra ante a " \
  "sagittis. Curabitur ut urna felis. Etiam sed vulputate nisi. Praesent " \
  "at libero eleifend, sagittis quam a, varius sapien."
#define LOREM_IPSUM_LENGTH ((size_t) 2725)

int main(int argc, char *argv[]) {
  static uint8_t compressed[4096];
  size_t compressed_length = sizeof (compressed);
  static uint8_t decompressed[LOREM_IPSUM_LENGTH];
  size_t decompressed_length = sizeof (decompressed);

  MSCompStatus res = ms_compress (CODEC_TO_TEST, LOREM_IPSUM, LOREM_IPSUM_LENGTH, compressed, &compressed_length);
  assert (res == MSCOMP_OK);
  fprintf (stdout, "Compressed %p[%zu] to %p[%zu]\n", LOREM_IPSUM, LOREM_IPSUM_LENGTH, compressed, compressed_length);

  res = ms_decompress (CODEC_TO_TEST, compressed, compressed_length, decompressed, &decompressed_length);
  fprintf (stdout, "Decompressed %p[%zu] to %p[%zu]\n", compressed, compressed_length, decompressed, decompressed_length);
  assert (decompressed_length == LOREM_IPSUM_LENGTH);

  decompressed_length--;
  res = ms_decompress (CODEC_TO_TEST, compressed, compressed_length, decompressed, &decompressed_length);
  assert (res == MSCOMP_BUF_ERROR);

  fprintf (stderr, "Victory!\n");

  return 0;
}
coderforlife commented 9 years ago

This seems to be because LZNT1 does not have an optimized decompressor like Xpress and Xpress Huffman and is using the ALL_AT_ONCE_WRAPPER_DECOMPRESS. If you compile with MSCOMP_WITHOUT_OPT_DECOMPRESS all will behave by returning MSCOMP_DATA_ERROR. It looks as though my ALL_AT_ONCE_WRAPPER_DECOMPRESS needs to be improved...

coderforlife commented 9 years ago

So, the underlying issue is that *_inflate_end always returns MSCOMP_DATA_ERROR when the stream doesn't seem to be at the proper end (an "inconsistent state"). This reflects what inflateEnd in zlib returns (they return Z_STREAM_ERROR). I will have to think about how to change how this all operates so that when using the ALL_AT_ONCE_WRAPPER_DECOMPRESS you don't lose the MSCOMP_BUF_ERROR error messages.

nemequ commented 9 years ago

Thanks.