Coverage Report

Created: 2025-12-12 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/decoder_fuzzer.cpp
Line
Count
Source
1
/*
2
# Copyright 2021 Google LLC
3
#
4
# Licensed under the Apache License, Version 2.0 (the "License");
5
# you may not use this file except in compliance with the License.
6
# You may obtain a copy of the License at
7
#
8
#      http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
#
16
################################################################################
17
*/
18
// TODO: This should be moved to the openh264 repo.
19
20
#include <stddef.h>
21
#include <stdint.h>
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
26
#include <memory>
27
28
#include "codec_def.h"
29
#include "codec_app_def.h"
30
#include "codec_api.h"
31
#include "read_config.h"
32
#include "typedefs.h"
33
#include "measure_time.h"
34
35
/*
36
 * To build locally:
37
 * 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
38
 * clang++ -o decoder_fuzzer -fsanitize=address -g -O1 -I./codec/api/wels -I./codec/console/common/inc -I./codec/common/inc -L. -lFuzzer -lstdc++ decoder_fuzzer.cpp libopenh264.a
39
 */
40
41
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
42
10.6k
{
43
10.6k
  int32_t i;
44
10.6k
  int32_t iBufPos = 0;
45
10.6k
  int32_t iEndOfStreamFlag;
46
10.6k
  int iLevelSetting = (int) WELS_LOG_QUIET; // disable logging while fuzzing
47
10.6k
  int32_t iSliceSize;
48
10.6k
  ISVCDecoder *pDecoder;
49
10.6k
  SDecodingParam sDecParam = {0};
50
10.6k
  SBufferInfo sDstBufInfo;
51
10.6k
  std::unique_ptr<uint8_t[]> pBuf(new uint8_t[size + 4]);
52
10.6k
  uint8_t* pData[3] = {NULL};
53
10.6k
  uint8_t uiStartCode[4] = {0, 0, 0, 1};
54
55
10.6k
  memcpy(pBuf.get(), data, size);
56
10.6k
  memcpy(pBuf.get() + size, &uiStartCode[0], 4);
57
10.6k
  memset(&sDstBufInfo, 0, sizeof(SBufferInfo));
58
59
  // TODO: is this the best/fastest ERROR_CON to use?
60
10.6k
  sDecParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
61
  // TODO: should we also fuzz VIDEO_BITSTREAM_SVC?
62
10.6k
  sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_AVC;
63
  
64
10.6k
  WelsCreateDecoder (&pDecoder);
65
10.6k
  pDecoder->Initialize (&sDecParam);
66
10.6k
  pDecoder->SetOption (DECODER_OPTION_TRACE_LEVEL, &iLevelSetting);
67
68
4.71M
  while (1) {
69
4.71M
    if (iBufPos >= size) {
70
10.6k
      iEndOfStreamFlag = 1;
71
10.6k
      if (iEndOfStreamFlag)
72
10.6k
        pDecoder->SetOption (DECODER_OPTION_END_OF_STREAM, (void*)&iEndOfStreamFlag);
73
10.6k
      break;
74
10.6k
    }
75
76
82.5M
    for (i = 0; i < size; i++) {
77
82.5M
      if ((pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 0 && pBuf[iBufPos + i + 3] == 1
78
82.2M
          && i > 0) || (pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 1 && i > 0)) {
79
4.69M
        break;
80
4.69M
      }
81
82.5M
    }
82
4.69M
    iSliceSize = i;
83
4.69M
    if (iSliceSize < 4) {
84
333k
      if (iSliceSize == 0) {
85
        // I don't think this should happen but let's just avoid the hang
86
0
        goto label_cleanup;
87
0
      }
88
333k
      iBufPos += iSliceSize;
89
333k
      continue;
90
333k
    }
91
92
4.36M
    pDecoder->DecodeFrameNoDelay (pBuf.get() + iBufPos, iSliceSize, pData, &sDstBufInfo);
93
4.36M
    iBufPos += iSliceSize;
94
4.36M
  }
95
96
10.6k
label_cleanup:
97
10.6k
  pDecoder->Uninitialize ();
98
10.6k
  WelsDestroyDecoder (pDecoder);
99
100
10.6k
  return 0;
101
10.6k
}