| 239 | } |
| 240 | |
| 241 | Timestamp randTimestamp( |
| 242 | FuzzerGenerator& rng, |
| 243 | const VectorFuzzer::Options& opts) { |
| 244 | switch (opts.timestampPrecision) { |
| 245 | case VectorFuzzer::Options::TimestampPrecision::kNanoSeconds: { |
| 246 | const auto& format = (opts.timestampFormat.size() == 1) |
| 247 | ? opts.timestampFormat.front() |
| 248 | : opts.timestampFormat |
| 249 | [rand<uint32_t>(rng) % opts.timestampFormat.size()]; |
| 250 | switch (format) { |
| 251 | case VectorFuzzer::Options::TimestampFormat::kStandard: |
| 252 | return Timestamp( |
| 253 | rand<int32_t>(rng), (rand<int64_t>(rng) % MAX_NANOS)); |
| 254 | case VectorFuzzer::Options::TimestampFormat::kSpecial: { |
| 255 | // Generate timestamps beyond 2262-04-12. |
| 256 | Timestamp specialTimestamp; |
| 257 | |
| 258 | constexpr int64_t kDaysPerYear = 365; |
| 259 | constexpr int64_t kMaxInvalidYear = 100'000; |
| 260 | constexpr int64_t kMinInvalidYear = 2263; |
| 261 | |
| 262 | int64_t year = |
| 263 | (rand<int64_t>(rng) % (kMaxInvalidYear - kMinInvalidYear + 1)) + |
| 264 | kMinInvalidYear; |
| 265 | int64_t seconds; |
| 266 | try { |
| 267 | int64_t days = checkedMultiply(year, kDaysPerYear); |
| 268 | seconds = checkedMultiply(days, Timestamp::kSecondsInDay); |
| 269 | } catch (...) { |
| 270 | seconds = rand<int32_t>(rng); |
| 271 | } |
| 272 | uint64_t nanos = rand<uint64_t>(rng) % (Timestamp::kMaxNanos + 1); |
| 273 | |
| 274 | std::memcpy(&specialTimestamp, &seconds, sizeof(int64_t)); |
| 275 | std::memcpy( |
| 276 | reinterpret_cast<char*>(&specialTimestamp) + sizeof(int64_t), |
| 277 | &nanos, |
| 278 | sizeof(uint64_t)); |
| 279 | |
| 280 | return specialTimestamp; |
| 281 | } |
| 282 | } |
| 283 | } |
| 284 | case VectorFuzzer::Options::TimestampPrecision::kMicroSeconds: |
| 285 | return Timestamp::fromMicros(rand<int64_t>(rng)); |
| 286 | case VectorFuzzer::Options::TimestampPrecision::kMilliSeconds: |
| 287 | return Timestamp::fromMillis(rand<int64_t>(rng)); |
| 288 | case VectorFuzzer::Options::TimestampPrecision::kSeconds: |
| 289 | return Timestamp(rand<int32_t>(rng), 0); |
| 290 | } |
| 291 | return {}; // no-op. |
| 292 | } |
| 293 | |
| 294 | size_t getElementsVectorLength( |
| 295 | const VectorFuzzer::Options& opts, |
no test coverage detected