| 
									
										
										
										
											2020-10-14 07:13:37 -07:00
										 |  |  | // A fuzzer for floating-point formatter.
 | 
					
						
							|  |  |  | // For the license information refer to format.h.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <cstdint>
 | 
					
						
							|  |  |  | #include <cstdlib>
 | 
					
						
							|  |  |  | #include <stdexcept>
 | 
					
						
							|  |  |  | #include <limits>
 | 
					
						
							|  |  |  | #include <fmt/format.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "fuzzer-common.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-03 19:34:35 -08:00
										 |  |  | void check_round_trip(fmt::string_view format_str, double value) { | 
					
						
							| 
									
										
										
										
											2020-10-14 07:13:37 -07:00
										 |  |  |   auto buffer = fmt::memory_buffer(); | 
					
						
							| 
									
										
										
										
											2020-11-03 19:34:35 -08:00
										 |  |  |   fmt::format_to(buffer, format_str, value); | 
					
						
							| 
									
										
										
										
											2020-10-14 07:13:37 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (std::isnan(value)) { | 
					
						
							|  |  |  |     auto nan = std::signbit(value) ? "-nan" : "nan"; | 
					
						
							|  |  |  |     if (fmt::string_view(buffer.data(), buffer.size()) != nan) | 
					
						
							|  |  |  |       throw std::runtime_error("round trip failure"); | 
					
						
							| 
									
										
										
										
											2020-11-03 19:34:35 -08:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2020-10-14 07:13:37 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-11-03 19:34:35 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-14 07:13:37 -07:00
										 |  |  |   buffer.push_back('\0'); | 
					
						
							|  |  |  |   char* ptr = nullptr; | 
					
						
							|  |  |  |   if (std::strtod(buffer.data(), &ptr) != value) | 
					
						
							|  |  |  |     throw std::runtime_error("round trip failure"); | 
					
						
							| 
									
										
										
										
											2020-10-16 07:35:53 -07:00
										 |  |  |   if (ptr + 1 != buffer.end()) | 
					
						
							| 
									
										
										
										
											2020-10-14 07:13:37 -07:00
										 |  |  |     throw std::runtime_error("unparsed output"); | 
					
						
							| 
									
										
										
										
											2020-11-03 19:34:35 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { | 
					
						
							|  |  |  |   if (size <= sizeof(double) || !std::numeric_limits<double>::is_iec559) | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   check_round_trip("{}", assign_from_buf<double>(data)); | 
					
						
							|  |  |  |   // A larger than necessary precision is used to trigger the fallback
 | 
					
						
							|  |  |  |   // formatter.
 | 
					
						
							|  |  |  |   check_round_trip("{:.50g}", assign_from_buf<double>(data)); | 
					
						
							| 
									
										
										
										
											2020-10-14 07:13:37 -07:00
										 |  |  |   return 0; | 
					
						
							|  |  |  | } |