Coverage Report

Created: 2022-04-16 06:38

/src/decoder_fuzzer.cpp
Line
Count
Source (jump to first uncovered line)
1
// TODO: This should be moved to the openh264 repo.
2
3
#include <stddef.h>
4
#include <stdint.h>
5
#include <stdio.h>
6
#include <stdlib.h>
7
#include <string.h>
8
9
#include <memory>
10
11
#include "codec_def.h"
12
#include "codec_app_def.h"
13
#include "codec_api.h"
14
#include "read_config.h"
15
#include "typedefs.h"
16
#include "measure_time.h"
17
18
/*
19
 * To build locally:
20
 * CC=clang CXX=clang++ CFLAGS="-fsanitize=address,fuzzer-no-link -g" CXXFLAGS="-fsanitize=address,fuzzer-no-link -g" LDFLAGS="-fsanitize=address,fuzzer-no-link" make -j$(nproc) USE_ASM=No BUILDTYPE=Debug libraries
21
 * clang++ -o decoder_fuzzer -fsanitize=address -g -O1 -I./codec/api/svc -I./codec/console/common/inc -I./codec/common/inc -L. -lFuzzer -lstdc++ decoder_fuzzer.cpp libopenh264.a
22
 */
23
24
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
25
18.9k
{
26
18.9k
  int32_t i;
27
18.9k
  int32_t iBufPos = 0;
28
18.9k
  int32_t iEndOfStreamFlag;
29
18.9k
  int iLevelSetting = (int) WELS_LOG_QUIET; // disable logging while fuzzing
30
18.9k
  int32_t iSliceSize;
31
18.9k
  ISVCDecoder *pDecoder;
32
18.9k
  SDecodingParam sDecParam = {0};
33
18.9k
  SBufferInfo sDstBufInfo;
34
18.9k
  std::unique_ptr<uint8_t[]> pBuf(new uint8_t[size + 4]);
35
18.9k
  uint8_t* pData[3] = {NULL};
36
18.9k
  uint8_t uiStartCode[4] = {0, 0, 0, 1};
37
38
18.9k
  memcpy(pBuf.get(), data, size);
39
18.9k
  memcpy(pBuf.get() + size, &uiStartCode[0], 4);
40
18.9k
  memset(&sDstBufInfo, 0, sizeof(SBufferInfo));
41
42
  // TODO: is this the best/fastest ERROR_CON to use?
43
18.9k
  sDecParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
44
  // TODO: should we also fuzz VIDEO_BITSTREAM_SVC?
45
18.9k
  sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_AVC;
46
  
47
18.9k
  WelsCreateDecoder (&pDecoder);
48
18.9k
  pDecoder->Initialize (&sDecParam);
49
18.9k
  pDecoder->SetOption (DECODER_OPTION_TRACE_LEVEL, &iLevelSetting);
50
51
1.74M
  while (1) {
52
1.74M
    if (iBufPos >= size) {
53
18.9k
      iEndOfStreamFlag = 1;
54
18.9k
      if (iEndOfStreamFlag)
55
18.9k
        pDecoder->SetOption (DECODER_OPTION_END_OF_STREAM, (void*)&iEndOfStreamFlag);
56
18.9k
      break;
57
18.9k
    }
58
59
45.2M
    for (i = 0; i < size; i++) {
60
45.2M
      if ((pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 0 && pBuf[iBufPos + i + 3] == 1
61
45.2M
          && i > 0) || (pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 1 && i > 0)) {
62
1.72M
        break;
63
1.72M
      }
64
45.2M
    }
65
1.72M
    iSliceSize = i;
66
1.72M
    if (iSliceSize < 4) {
67
162k
      if (iSliceSize == 0) {
68
        // I don't think this should happen but let's just avoid the hang
69
0
        goto label_cleanup;
70
0
      }
71
162k
      iBufPos += iSliceSize;
72
162k
      continue;
73
162k
    }
74
75
1.56M
    pDecoder->DecodeFrameNoDelay (pBuf.get() + iBufPos, iSliceSize, pData, &sDstBufInfo);
76
1.56M
    iBufPos += iSliceSize;
77
1.56M
  }
78
79
18.9k
label_cleanup:
80
18.9k
  pDecoder->Uninitialize ();
81
18.9k
  WelsDestroyDecoder (pDecoder);
82
83
18.9k
  return 0;
84
18.9k
}