* Copyright (c) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <vector>
#include <fuzzer/FuzzedDataProvider.h>
#include "mpeg4demuxerplugin_sample.h"
#define FUZZ_PROJECT_NAME "demuxerpluginmpeg4_fuzzer"
namespace OHOS {
namespace {
constexpr size_t MIN_INPUT_SIZE = 32;
constexpr uint32_t MAX_TIMEOUT_MS = 100;
constexpr uint32_t MAX_CACHE_LIMIT = 1024 * 1024;
constexpr uint32_t MAX_PROBE_SIZE = 1024 * 1024;
constexpr int64_t MAX_SEEK_TIME_MS = 60 * 1000;
constexpr int64_t MAX_READ_TIMEOUT_MS = 1000;
uint32_t ConsumeBoundedU32(FuzzedDataProvider &provider, uint32_t maxValue)
{
return provider.ConsumeIntegralInRange<uint32_t>(0, maxValue);
}
int64_t ConsumeBoundedI64(FuzzedDataProvider &provider, int64_t minValue,
int64_t maxValue)
{
return provider.ConsumeIntegralInRange<int64_t>(minValue, maxValue);
}
Media::Mpeg4DemuxerPluginFuzzConfig ConsumeConfig(FuzzedDataProvider &provider)
{
Media::Mpeg4DemuxerPluginFuzzConfig config;
config.useEmptyBuffer = provider.ConsumeBool();
config.useConfigs = provider.ConsumeBool();
config.interruptState = provider.ConsumeBool();
config.stopReadPacketState = provider.ConsumeBool();
config.invalidTrackId = ConsumeBoundedU32(provider, UINT16_MAX);
config.timeoutMs = ConsumeBoundedU32(provider, MAX_TIMEOUT_MS);
config.cacheLimit = ConsumeBoundedU32(provider, MAX_CACHE_LIMIT);
config.trackCacheLimit = ConsumeBoundedU32(provider, MAX_CACHE_LIMIT);
config.trackCacheWindowMs = ConsumeBoundedU32(provider, MAX_TIMEOUT_MS);
config.frameId = provider.ConsumeIntegral<uint32_t>();
config.gopId = provider.ConsumeIntegral<uint32_t>();
config.relativePresentationTimeUs = provider.ConsumeIntegral<uint64_t>();
config.probSize =
static_cast<int32_t>(ConsumeBoundedU32(provider, MAX_PROBE_SIZE));
config.seekTimeMs =
ConsumeBoundedI64(provider, -MAX_SEEK_TIME_MS, MAX_SEEK_TIME_MS);
config.secondSeekTimeMs =
ConsumeBoundedI64(provider, -MAX_SEEK_TIME_MS, MAX_SEEK_TIME_MS);
config.readTimeoutMs =
ConsumeBoundedI64(provider, -MAX_READ_TIMEOUT_MS, MAX_READ_TIMEOUT_MS);
config.dts = provider.ConsumeIntegral<int64_t>();
return config;
}
void RunDemuxerPluginMpeg4FuzzTest(const uint8_t *data, size_t size)
{
if (data == nullptr || size < MIN_INPUT_SIZE) {
return;
}
FuzzedDataProvider provider(data, size);
Media::Mpeg4DemuxerPluginFuzzConfig config = ConsumeConfig(provider);
std::vector<uint8_t> streamData = provider.ConsumeRemainingBytes<uint8_t>();
if (streamData.empty()) {
return;
}
auto demuxerTest = std::make_shared<Media::Mpeg4DemuxerPluginFuzzTest>();
if (!demuxerTest->InitWithData(streamData.data(), streamData.size())) {
return;
}
demuxerTest->Run(config);
}
}
void DemuxerPluginMpeg4FuzzTest(const uint8_t *data, size_t size)
{
RunDemuxerPluginMpeg4FuzzTest(data, size);
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
OHOS::DemuxerPluginMpeg4FuzzTest(data, size);
return 0;
}