Line | Count | Source (jump to first uncovered line) |
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 | 15.4k | { |
43 | 15.4k | int32_t i; |
44 | 15.4k | int32_t iBufPos = 0; |
45 | 15.4k | int32_t iEndOfStreamFlag; |
46 | 15.4k | int iLevelSetting = (int) WELS_LOG_QUIET; // disable logging while fuzzing |
47 | 15.4k | int32_t iSliceSize; |
48 | 15.4k | ISVCDecoder *pDecoder; |
49 | 15.4k | SDecodingParam sDecParam = {0}; |
50 | 15.4k | SBufferInfo sDstBufInfo; |
51 | 15.4k | std::unique_ptr<uint8_t[]> pBuf(new uint8_t[size + 4]); |
52 | 15.4k | uint8_t* pData[3] = {NULL}; |
53 | 15.4k | uint8_t uiStartCode[4] = {0, 0, 0, 1}; |
54 | | |
55 | 15.4k | memcpy(pBuf.get(), data, size); |
56 | 15.4k | memcpy(pBuf.get() + size, &uiStartCode[0], 4); |
57 | 15.4k | memset(&sDstBufInfo, 0, sizeof(SBufferInfo)); |
58 | | |
59 | | // TODO: is this the best/fastest ERROR_CON to use? |
60 | 15.4k | sDecParam.eEcActiveIdc = ERROR_CON_SLICE_COPY; |
61 | | // TODO: should we also fuzz VIDEO_BITSTREAM_SVC? |
62 | 15.4k | sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_AVC; |
63 | | |
64 | 15.4k | WelsCreateDecoder (&pDecoder); |
65 | 15.4k | pDecoder->Initialize (&sDecParam); |
66 | 15.4k | pDecoder->SetOption (DECODER_OPTION_TRACE_LEVEL, &iLevelSetting); |
67 | | |
68 | 4.94M | while (1) { |
69 | 4.94M | if (iBufPos >= size) { |
70 | 15.4k | iEndOfStreamFlag = 1; |
71 | 15.4k | if (iEndOfStreamFlag) |
72 | 15.4k | pDecoder->SetOption (DECODER_OPTION_END_OF_STREAM, (void*)&iEndOfStreamFlag); |
73 | 15.4k | break; |
74 | 15.4k | } |
75 | | |
76 | 80.2M | for (i = 0; i < size; i++) { |
77 | 80.2M | if ((pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 0 && pBuf[iBufPos + i + 3] == 1 |
78 | 80.2M | && i > 0) || (pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 1 && i > 0)) { |
79 | 4.93M | break; |
80 | 4.93M | } |
81 | 80.2M | } |
82 | 4.93M | iSliceSize = i; |
83 | 4.93M | if (iSliceSize < 4) { |
84 | 226k | 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 | 226k | iBufPos += iSliceSize; |
89 | 226k | continue; |
90 | 226k | } |
91 | | |
92 | 4.70M | pDecoder->DecodeFrameNoDelay (pBuf.get() + iBufPos, iSliceSize, pData, &sDstBufInfo); |
93 | 4.70M | iBufPos += iSliceSize; |
94 | 4.70M | } |
95 | | |
96 | 15.4k | label_cleanup: |
97 | 15.4k | pDecoder->Uninitialize (); |
98 | 15.4k | WelsDestroyDecoder (pDecoder); |
99 | | |
100 | 15.4k | return 0; |
101 | 15.4k | } |