decompress_dstSize_tooSmall.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * Copyright (c) 2016-2021, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under both the BSD-style license (found in the
  6. * LICENSE file in the root directory of this source tree) and the GPLv2 (found
  7. * in the COPYING file in the root directory of this source tree).
  8. * You may select, at your option, one of the above-listed licenses.
  9. */
  10. /**
  11. * This fuzz target attempts to decompress a valid compressed frame into
  12. * an output buffer that is too small to ensure we always get
  13. * ZSTD_error_dstSize_tooSmall.
  14. */
  15. #include <stddef.h>
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include "fuzz_helpers.h"
  19. #include "zstd.h"
  20. #include "zstd_errors.h"
  21. #include "zstd_helpers.h"
  22. #include "fuzz_data_producer.h"
  23. static ZSTD_CCtx *cctx = NULL;
  24. static ZSTD_DCtx *dctx = NULL;
  25. int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
  26. {
  27. /* Give a random portion of src data to the producer, to use for
  28. parameter generation. The rest will be used for (de)compression */
  29. FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
  30. size_t rBufSize = FUZZ_dataProducer_uint32Range(producer, 0, size);
  31. size = FUZZ_dataProducer_remainingBytes(producer);
  32. /* Ensure the round-trip buffer is too small. */
  33. if (rBufSize >= size) {
  34. rBufSize = size > 0 ? size - 1 : 0;
  35. }
  36. size_t const cBufSize = ZSTD_compressBound(size);
  37. if (!cctx) {
  38. cctx = ZSTD_createCCtx();
  39. FUZZ_ASSERT(cctx);
  40. }
  41. if (!dctx) {
  42. dctx = ZSTD_createDCtx();
  43. FUZZ_ASSERT(dctx);
  44. }
  45. void *cBuf = FUZZ_malloc(cBufSize);
  46. void *rBuf = FUZZ_malloc(rBufSize);
  47. size_t const cSize = ZSTD_compressCCtx(cctx, cBuf, cBufSize, src, size, 1);
  48. FUZZ_ZASSERT(cSize);
  49. size_t const rSize = ZSTD_decompressDCtx(dctx, rBuf, rBufSize, cBuf, cSize);
  50. if (size == 0) {
  51. FUZZ_ASSERT(rSize == 0);
  52. } else {
  53. FUZZ_ASSERT(ZSTD_isError(rSize));
  54. FUZZ_ASSERT(ZSTD_getErrorCode(rSize) == ZSTD_error_dstSize_tooSmall);
  55. }
  56. free(cBuf);
  57. free(rBuf);
  58. FUZZ_dataProducer_free(producer);
  59. #ifndef STATEFUL_FUZZING
  60. ZSTD_freeCCtx(cctx); cctx = NULL;
  61. ZSTD_freeDCtx(dctx); dctx = NULL;
  62. #endif
  63. return 0;
  64. }