Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /base /command_line_fuzzer.cc
blob: 531f28b7a87fdb4c7c5f84a4725603409a6f13af [file] [log] [blame] [edit]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include"base/command_line.h"
#include<fuzzer/FuzzedDataProvider.h>
#include<stdint.h>
#include<algorithm>
#include<string>
#include<tuple>
#include"base/check.h"
#include"base/files/file_path.h"
#include"base/strings/string_util.h"
#include"base/strings/utf_string_conversions.h"
#include"build/build_config.h"
namespace base{
namespace{
CommandLine::StringTypeGenerateNativeString(FuzzedDataProvider& provider){
const std::string raw_string= provider.ConsumeRandomLengthString();
#if BUILDFLAG(IS_WIN)
return UTF8ToWide(raw_string);
#else
return raw_string;
#endif
}
CommandLine::StringVectorGenerateNativeStringVector(
FuzzedDataProvider& provider){
CommandLine::StringVector strings(
provider.ConsumeIntegralInRange<int>(0,100));
for(auto& item: strings){
item=GenerateNativeString(provider);
}
return strings;
}
FilePathGenerateFilePath(FuzzedDataProvider& provider){
returnFilePath(GenerateNativeString(provider));
}
boolIsForbiddenSwitchCharacter(char c){
returnIsAsciiWhitespace(c)|| c=='='|| c!=ToLowerASCII(c);
}
boolIsValidSwitchName(const std::string& text){
// This duplicates the logic in command_line.cc, but it's not exposed in form
// of public interface.
return!text.empty()&&
!std::ranges::any_of(text,IsForbiddenSwitchCharacter)&&
!StartsWith(text,"-")&&!StartsWith(text,"/");
}
}// namespace
extern"C"intLLVMFuzzerTestOneInput(constuint8_t* data,size_t size){
FuzzedDataProvider provider(data, size);
// Create a randomly initialized command line.
CommandLine command_line(CommandLine::NO_PROGRAM);
switch(provider.ConsumeIntegralInRange<int>(0,3)){
case0:
// Leave empty.
break;
case1:
command_line=CommandLine(GenerateFilePath(provider));
break;
case2:
command_line=CommandLine(GenerateNativeStringVector(provider));
break;
case3:
#if BUILDFLAG(IS_WIN)
command_line.ParseFromString(GenerateNativeString(provider));
#endif
break;
}
// Do a few mutations of the command line.
while(provider.remaining_bytes()>0){
switch(provider.ConsumeIntegralInRange<int>(0,4)){
case0:{
// Add a switch.
std::string name= provider.ConsumeRandomLengthString();
if(IsValidSwitchName(name)){
CommandLine::StringType value=GenerateNativeString(provider);
command_line.AppendSwitchNative(name, value);
CHECK(command_line.HasSwitch(name));
CHECK(command_line.GetSwitchValueNative(name)== value);
}
break;
}
case1:{
// Remove a switch.
std::string name= provider.ConsumeRandomLengthString();
if(IsValidSwitchName(name)){
command_line.RemoveSwitch(name);
CHECK(!command_line.HasSwitch(name));
CHECK(command_line.GetSwitchValueNative(name).empty());
}
break;
}
case2:{
// Add an argument.
CommandLine::StringType arg=GenerateNativeString(provider);
if(!arg.empty()&&IsStringASCII(arg)){
command_line.AppendArgNative(arg);
}
break;
}
case3:{
// Add a wrapper.
CommandLine::StringType wrapper=GenerateNativeString(provider);
if(!wrapper.empty()){
command_line.PrependWrapper(wrapper);
}
break;
}
case4:{
// Check a switch.
std::string name= provider.ConsumeRandomLengthString();
if(IsValidSwitchName(name)){
std::ignore= command_line.HasSwitch(name);
std::ignore= command_line.GetSwitchValueNative(name);
}
break;
}
}
// Smoke-test various accessors.
std::ignore= command_line.GetCommandLineString();
std::ignore= command_line.GetArgumentsString();
#if BUILDFLAG(IS_WIN)
std::ignore= command_line.GetCommandLineStringForShell();
std::ignore= command_line.GetCommandLineStringWithUnsafeInsertSequences();
#endif
}
return0;
}
}// namespace base

[8]ページ先頭

©2009-2025 Movatter.jp