• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }