mirror of
				https://github.com/fmtlib/fmt.git
				synced 2025-11-04 16:11:47 +01:00 
			
		
		
		
	
		
			
	
	
		
			153 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			153 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								// Copyright (c) 2019, Paul Dreik
							 | 
						||
| 
								 | 
							
								// License: see LICENSE.rst in the fmt root directory
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <fmt/chrono.h>
							 | 
						||
| 
								 | 
							
								#include <cstdint>
							 | 
						||
| 
								 | 
							
								#include <limits>
							 | 
						||
| 
								 | 
							
								#include <stdexcept>
							 | 
						||
| 
								 | 
							
								#include <type_traits>
							 | 
						||
| 
								 | 
							
								#include <vector>
							 | 
						||
| 
								 | 
							
								#include "fuzzer_common.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename Item, typename Ratio>
							 | 
						||
| 
								 | 
							
								void invoke_inner(fmt::string_view formatstring, const Item item) {
							 | 
						||
| 
								 | 
							
								  const std::chrono::duration<Item, Ratio> value(item);
							 | 
						||
| 
								 | 
							
								  try {
							 | 
						||
| 
								 | 
							
								#if FMT_FUZZ_FORMAT_TO_STRING
							 | 
						||
| 
								 | 
							
								    std::string message = fmt::format(formatstring, value);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    fmt::memory_buffer buf;
							 | 
						||
| 
								 | 
							
								    fmt::format_to(buf, formatstring, value);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								  } catch (std::exception& /*e*/) {
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Item is the underlying type for duration (int, long etc)
							 | 
						||
| 
								 | 
							
								template <typename Item>
							 | 
						||
| 
								 | 
							
								void invoke_outer(const uint8_t* Data, std::size_t Size, const int scaling) {
							 | 
						||
| 
								 | 
							
								  // always use a fixed location of the data
							 | 
						||
| 
								 | 
							
								  using fmt_fuzzer::Nfixed;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  constexpr auto N = sizeof(Item);
							 | 
						||
| 
								 | 
							
								  static_assert(N <= Nfixed, "fixed size is too small");
							 | 
						||
| 
								 | 
							
								  if (Size <= Nfixed + 1) {
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const Item item = fmt_fuzzer::assignFromBuf<Item>(Data);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // fast forward
							 | 
						||
| 
								 | 
							
								  Data += Nfixed;
							 | 
						||
| 
								 | 
							
								  Size -= Nfixed;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Data is already allocated separately in libFuzzer so reading past
							 | 
						||
| 
								 | 
							
								  // the end will most likely be detected anyway
							 | 
						||
| 
								 | 
							
								  const auto formatstring = fmt::string_view(fmt_fuzzer::as_chars(Data), Size);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // doit_impl<Item,std::yocto>(buf.data(),item);
							 | 
						||
| 
								 | 
							
								  // doit_impl<Item,std::zepto>(buf.data(),item);
							 | 
						||
| 
								 | 
							
								  switch (scaling) {
							 | 
						||
| 
								 | 
							
								  case 1:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::atto>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 2:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::femto>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 3:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::pico>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 4:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::nano>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 5:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::micro>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 6:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::milli>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 7:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::centi>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 8:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::deci>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 9:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::deca>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 10:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::kilo>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 11:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::mega>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 12:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::giga>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 13:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::tera>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 14:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::peta>(formatstring, item);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 15:
							 | 
						||
| 
								 | 
							
								    invoke_inner<Item, std::exa>(formatstring, item);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  // doit_impl<Item,std::zeta>(buf.data(),item);
							 | 
						||
| 
								 | 
							
								  // doit_impl<Item,std::yotta>(buf.data(),item);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, std::size_t Size) {
							 | 
						||
| 
								 | 
							
								  if (Size <= 4) {
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const auto representation = Data[0];
							 | 
						||
| 
								 | 
							
								  const auto scaling = Data[1];
							 | 
						||
| 
								 | 
							
								  Data += 2;
							 | 
						||
| 
								 | 
							
								  Size -= 2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  switch (representation) {
							 | 
						||
| 
								 | 
							
								  case 1:
							 | 
						||
| 
								 | 
							
								    invoke_outer<char>(Data, Size, scaling);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 2:
							 | 
						||
| 
								 | 
							
								    invoke_outer<unsigned char>(Data, Size, scaling);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 3:
							 | 
						||
| 
								 | 
							
								    invoke_outer<signed char>(Data, Size, scaling);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 4:
							 | 
						||
| 
								 | 
							
								    invoke_outer<short>(Data, Size, scaling);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 5:
							 | 
						||
| 
								 | 
							
								    invoke_outer<unsigned short>(Data, Size, scaling);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 6:
							 | 
						||
| 
								 | 
							
								    invoke_outer<int>(Data, Size, scaling);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 7:
							 | 
						||
| 
								 | 
							
								    invoke_outer<unsigned int>(Data, Size, scaling);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 8:
							 | 
						||
| 
								 | 
							
								    invoke_outer<long>(Data, Size, scaling);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 9:
							 | 
						||
| 
								 | 
							
								    invoke_outer<unsigned long>(Data, Size, scaling);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 10:
							 | 
						||
| 
								 | 
							
								    invoke_outer<float>(Data, Size, scaling);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 11:
							 | 
						||
| 
								 | 
							
								    invoke_outer<double>(Data, Size, scaling);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  case 12:
							 | 
						||
| 
								 | 
							
								    invoke_outer<long double>(Data, Size, scaling);
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  default:
							 | 
						||
| 
								 | 
							
								    break;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return 0;
							 | 
						||
| 
								 | 
							
								}
							 |