chrono-duration.cc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Copyright (c) 2019, Paul Dreik
  2. // For the license information refer to format.h.
  3. #include <fmt/chrono.h>
  4. #include <cstdint>
  5. #include "fuzzer-common.h"
  6. template <typename Period, typename Rep>
  7. void invoke_inner(fmt::string_view format_str, Rep rep) {
  8. auto value = std::chrono::duration<Rep, Period>(rep);
  9. try {
  10. #if FMT_FUZZ_FORMAT_TO_STRING
  11. std::string message = fmt::format(format_str, value);
  12. #else
  13. auto buf = fmt::memory_buffer();
  14. fmt::format_to(std::back_inserter(buf), format_str, value);
  15. #endif
  16. } catch (std::exception&) {
  17. }
  18. }
  19. // Rep is a duration's representation type.
  20. template <typename Rep>
  21. void invoke_outer(const uint8_t* data, size_t size, int period) {
  22. // Always use a fixed location of the data.
  23. static_assert(sizeof(Rep) <= fixed_size, "fixed size is too small");
  24. if (size <= fixed_size + 1) return;
  25. const Rep rep = assign_from_buf<Rep>(data);
  26. data += fixed_size;
  27. size -= fixed_size;
  28. // data is already allocated separately in libFuzzer so reading past the end
  29. // will most likely be detected anyway.
  30. const auto format_str = fmt::string_view(as_chars(data), size);
  31. // yocto, zepto, zetta and yotta are not handled.
  32. switch (period) {
  33. case 1:
  34. invoke_inner<std::atto>(format_str, rep);
  35. break;
  36. case 2:
  37. invoke_inner<std::femto>(format_str, rep);
  38. break;
  39. case 3:
  40. invoke_inner<std::pico>(format_str, rep);
  41. break;
  42. case 4:
  43. invoke_inner<std::nano>(format_str, rep);
  44. break;
  45. case 5:
  46. invoke_inner<std::micro>(format_str, rep);
  47. break;
  48. case 6:
  49. invoke_inner<std::milli>(format_str, rep);
  50. break;
  51. case 7:
  52. invoke_inner<std::centi>(format_str, rep);
  53. break;
  54. case 8:
  55. invoke_inner<std::deci>(format_str, rep);
  56. break;
  57. case 9:
  58. invoke_inner<std::deca>(format_str, rep);
  59. break;
  60. case 10:
  61. invoke_inner<std::kilo>(format_str, rep);
  62. break;
  63. case 11:
  64. invoke_inner<std::mega>(format_str, rep);
  65. break;
  66. case 12:
  67. invoke_inner<std::giga>(format_str, rep);
  68. break;
  69. case 13:
  70. invoke_inner<std::tera>(format_str, rep);
  71. break;
  72. case 14:
  73. invoke_inner<std::peta>(format_str, rep);
  74. break;
  75. case 15:
  76. invoke_inner<std::exa>(format_str, rep);
  77. break;
  78. }
  79. }
  80. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  81. if (size <= 4) return 0;
  82. const auto representation = data[0];
  83. const auto period = data[1];
  84. data += 2;
  85. size -= 2;
  86. switch (representation) {
  87. case 1:
  88. invoke_outer<char>(data, size, period);
  89. break;
  90. case 2:
  91. invoke_outer<signed char>(data, size, period);
  92. break;
  93. case 3:
  94. invoke_outer<unsigned char>(data, size, period);
  95. break;
  96. case 4:
  97. invoke_outer<short>(data, size, period);
  98. break;
  99. case 5:
  100. invoke_outer<unsigned short>(data, size, period);
  101. break;
  102. case 6:
  103. invoke_outer<int>(data, size, period);
  104. break;
  105. case 7:
  106. invoke_outer<unsigned int>(data, size, period);
  107. break;
  108. case 8:
  109. invoke_outer<long>(data, size, period);
  110. break;
  111. case 9:
  112. invoke_outer<unsigned long>(data, size, period);
  113. break;
  114. case 10:
  115. invoke_outer<float>(data, size, period);
  116. break;
  117. case 11:
  118. invoke_outer<double>(data, size, period);
  119. break;
  120. case 12:
  121. invoke_outer<long double>(data, size, period);
  122. break;
  123. }
  124. return 0;
  125. }