1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <cstddef>
17 #include <cstdint>
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <sys/stat.h>
21 #include "securec.h"
22
23 #include <iostream>
24 #include "demuxer_plugin_manager.h"
25 #include "stream_demuxer.h"
26
27 #define FUZZ_PROJECT_NAME "demuxerpluginmanager_fuzzer"
28 using namespace std;
29 using namespace OHOS::Media;
30 namespace OHOS {
31 const char *MP4_PATH = "/data/test/fuzz_create.mp4";
32 const int64_t INVALID_STREAM_OR_TRACK_ID = -1;
33 const int64_t TRUE_OR_FALSE = 2;
34 const int64_t AUDIO_TRACK = 1;
35 const int64_t VIDEO_TRACK = 0;
36 const int64_t SUBTITLE_TRACK = 2;
37 const int64_t EXPECT_SIZE = 37;
38 const int64_t TRACK_COUNT = 3;
39 const int64_t SELECT_TRACK = 4;
40 const size_t VIDEO_HEIGHT_SIZE = 35;
41 const size_t VIDEO_WIDTH_SIZE = 36;
42 const size_t BITRATE = 37;
CheckDataValidity(const uint8_t * data,size_t size)43 bool CheckDataValidity(const uint8_t *data, size_t size)
44 {
45 if (size < EXPECT_SIZE) {
46 return false;
47 }
48 int32_t fd = open(MP4_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
49 if (fd < 0) {
50 return false;
51 }
52 int len = write(fd, data, size - 36);
53 if (len <= 0) {
54 close(fd);
55 return false;
56 }
57 close(fd);
58 return true;
59 }
60
DemuxerPluginManagerFuzzTest(const uint8_t * data,size_t size)61 bool DemuxerPluginManagerFuzzTest(const uint8_t *data, size_t size)
62 {
63 if (!CheckDataValidity(data, size)) {
64 return false;
65 }
66
67 std::shared_ptr<OHOS::Media::DemuxerPluginManager> demuxerPluginManager_ =
68 std::make_shared<OHOS::Media::DemuxerPluginManager>();
69
70 std::shared_ptr<OHOS::Media::BaseStreamDemuxer> streamDemuxer =
71 std::make_shared<StreamDemuxer>();
72
73 std::shared_ptr<MediaSource> mediaSource =
74 std::make_shared<MediaSource>(MP4_PATH);
75
76 std::shared_ptr<Source> source = std::make_shared<Source>();
77
78 auto res = source->SetSource(mediaSource);
79 if (res != Status::OK) {
80 return false;
81 }
82
83 std::vector<StreamInfo> streams;
84 demuxerPluginManager_->SetIsHlsFmp4(false);
85
86 streamDemuxer->SetSourceType(mediaSource->GetSourceType());
87 streamDemuxer->SetInterruptState(false);
88 streamDemuxer->SetSource(source);
89 streamDemuxer->Init(MP4_PATH);
90
91 Media::Plugins::StreamInfo videoInfo;
92 videoInfo.streamId = (size - VIDEO_TRACK) % TRACK_COUNT;
93 videoInfo.bitRate = size - BITRATE;
94 videoInfo.videoWidth = size - VIDEO_WIDTH_SIZE;
95 videoInfo.videoHeight = size - VIDEO_HEIGHT_SIZE;
96 videoInfo.videoType = Media::Plugins::VideoType::VIDEO_TYPE_SDR;
97 videoInfo.type = OHOS::Media::Plugins::StreamType::VIDEO;
98
99 Media::Plugins::StreamInfo audioInfo;
100 audioInfo.streamId = (size - AUDIO_TRACK) % TRACK_COUNT;
101 audioInfo.bitRate = size - BITRATE;
102 audioInfo.videoWidth = size - VIDEO_WIDTH_SIZE;
103 audioInfo.videoHeight = size - VIDEO_HEIGHT_SIZE;
104 audioInfo.videoType = Media::Plugins::VideoType::VIDEO_TYPE_SDR;
105 audioInfo.type = OHOS::Media::Plugins::StreamType::AUDIO;
106
107 Media::Plugins::StreamInfo subtitleInfo;
108 subtitleInfo.streamId = (size - SUBTITLE_TRACK) % TRACK_COUNT;
109 subtitleInfo.type = OHOS::Media::Plugins::StreamType::SUBTITLE;
110 streams.push_back(videoInfo);
111 streams.push_back(audioInfo);
112 streams.push_back(subtitleInfo);
113
114 int32_t streamID = size % SELECT_TRACK;
115 int32_t trackId = size % SELECT_TRACK;
116 int32_t innerTrackId = size % SELECT_TRACK;
117 demuxerPluginManager_->InitDefaultPlay(streams);
118 demuxerPluginManager_->InitDefaultPlay(streams);
119 demuxerPluginManager_->SetResetEosStatus(size % TRUE_OR_FALSE == 0);
120 demuxerPluginManager_->GetTrackInfoByStreamID(streamID, trackId, innerTrackId);
121 if (innerTrackId != trackId) {
122 return false;
123 }
124 TrackType trackType;
125 switch (size % SELECT_TRACK) {
126 case VIDEO_TRACK:
127 trackType = TrackType::TRACK_VIDEO;
128 break;
129 case AUDIO_TRACK:
130 trackType = TrackType::TRACK_AUDIO;
131 break;
132 case SUBTITLE_TRACK:
133 trackType = TrackType::TRACK_SUBTITLE;
134 break;
135 default:
136 trackType = TrackType::TRACK_INVALID;
137 break;
138 }
139 demuxerPluginManager_->GetTrackInfoByStreamID(streamID, trackId, innerTrackId, trackType);
140 if (innerTrackId != trackId) {
141 return false;
142 }
143 int32_t innerTrackIndex = demuxerPluginManager_->GetInnerTrackIDByTrackID(trackId);
144 if (innerTrackIndex != trackId) {
145 return false;
146 }
147 int32_t cusTypeStreamId = demuxerPluginManager_->GetStreamIDByTrackType(trackType);
148 if (trackType == TRACK_VIDEO) {
149 if (cusTypeStreamId != videoInfo.streamId) {
150 return false;
151 }
152 } else if (trackType == TRACK_AUDIO) {
153 if (cusTypeStreamId != audioInfo.streamId) {
154 return false;
155 }
156 } else if (trackType == TRACK_SUBTITLE) {
157 if (cusTypeStreamId != subtitleInfo.streamId) {
158 return false;
159 }
160 } else {
161 if (cusTypeStreamId != INVALID_STREAM_OR_TRACK_ID) {
162 return false;
163 }
164 }
165
166 demuxerPluginManager_->StopPlugin(streamID, streamDemuxer);
167 bool isRebooted = false;
168 demuxerPluginManager_->RebootPlugin(streamID, trackType, streamDemuxer, isRebooted);
169 int64_t realSeekTime = size;
170 demuxerPluginManager_->SingleStreamSeekTo(realSeekTime,
171 Plugins::SeekMode::SEEK_CLOSEST_SYNC, streamID, realSeekTime);
172 demuxerPluginManager_->Start();
173 demuxerPluginManager_->Stop();
174 demuxerPluginManager_->Flush();
175 demuxerPluginManager_->Reset();
176
177 Plugins::MediaInfo mediaInfo;
178 demuxerPluginManager_->LoadCurrentAllPlugin(streamDemuxer, mediaInfo);
179 demuxerPluginManager_->GetCurrentBitRate();
180 demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
181 demuxerPluginManager_->AddExternalSubtitle();
182 demuxerPluginManager_->AddExternalSubtitle();
183 demuxerPluginManager_->SetApiVersion(size);
184
185 int ret = remove(MP4_PATH);
186 if (ret != 0) {
187 return false;
188 }
189 return true;
190 }
191 } // namespace OHOS
192
193 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)194 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
195 {
196 /* Run your code on data */
197 OHOS::DemuxerPluginManagerFuzzTest(data, size);
198 return 0;
199 }