@@ -576,34 +576,41 @@ template <typename Traits>
576576absl::Status WriteTimestamp (JsonWriter& writer, const Msg<Traits>& msg,
577577 const Desc<Traits>& desc) {
578578 auto secs_field = Traits::MustHaveField (desc, 1 );
579- auto secs = Traits::GetSize (secs_field, msg) > 0
580- ? Traits::GetInt64 (secs_field, msg)
581- : 0 ;
582- RETURN_IF_ERROR (secs.status ());
579+ auto status_or_secs = Traits::GetSize (secs_field, msg) > 0
580+ ? Traits::GetInt64 (secs_field, msg)
581+ : 0 ;
582+ RETURN_IF_ERROR (status_or_secs.status ());
583+ int64_t secs = *status_or_secs;
583584
584- if (* secs < -62135596800 ) {
585+ if (secs < -62135596800 ) {
585586 return absl::InvalidArgumentError (
586587 " minimum acceptable time value is 0001-01-01T00:00:00Z" );
587- } else if (* secs > 253402300799 ) {
588+ } else if (secs > 253402300799 ) {
588589 return absl::InvalidArgumentError (
589590 " maximum acceptable time value is 9999-12-31T23:59:59Z" );
590591 }
591592
592593 // Ensure seconds is positive.
593- * secs += 62135596800 ;
594+ secs += 62135596800 ;
594595
595596 auto nanos_field = Traits::MustHaveField (desc, 2 );
596- auto nanos = Traits::GetSize (nanos_field, msg) > 0
597- ? Traits::GetInt32 (nanos_field, msg)
598- : 0 ;
599- RETURN_IF_ERROR (nanos.status ());
597+ auto status_or_nanos = Traits::GetSize (nanos_field, msg) > 0
598+ ? Traits::GetInt32 (nanos_field, msg)
599+ : 0 ;
600+ RETURN_IF_ERROR (status_or_nanos.status ());
601+ int32_t nanos = *status_or_nanos;
602+
603+ if (nanos < 0 || nanos > 999999999 ) {
604+ return absl::InvalidArgumentError (
605+ " nanos must be in range [0, +999,999,999]" );
606+ }
600607
601608 // Julian Day -> Y/M/D, Algorithm from:
602609 // Fliegel, H. F., and Van Flandern, T. C., "A Machine Algorithm for
603610 // Processing Calendar Dates," Communications of the Association of
604611 // Computing Machines, vol. 11 (1968), p. 657.
605612 int32_t L, N, I, J, K;
606- L = static_cast <int32_t >(* secs / 86400 ) - 719162 + 68569 + 2440588 ;
613+ L = static_cast <int32_t >(secs / 86400 ) - 719162 + 68569 + 2440588 ;
607614 N = 4 * L / 146097 ;
608615 L = L - (146097 * N + 3 ) / 4 ;
609616 I = 4000 * (L + 1 ) / 1461001 ;
@@ -614,18 +621,18 @@ absl::Status WriteTimestamp(JsonWriter& writer, const Msg<Traits>& msg,
614621 J = J + 2 - 12 * L;
615622 I = 100 * (N - 49 ) + I + L;
616623
617- int32_t sec = * secs % 60 ;
618- int32_t min = (* secs / 60 ) % 60 ;
619- int32_t hour = (* secs / 3600 ) % 24 ;
624+ int32_t sec = secs % 60 ;
625+ int32_t min = (secs / 60 ) % 60 ;
626+ int32_t hour = (secs / 3600 ) % 24 ;
620627
621- if (* nanos == 0 ) {
628+ if (nanos == 0 ) {
622629 writer.Write (absl::StrFormat (R"( "%04d-%02d-%02dT%02d:%02d:%02dZ")" , I, J, K,
623630 hour, min, sec));
624631 return absl::OkStatus ();
625632 }
626633
627634 size_t digits = 9 ;
628- uint32_t frac_seconds = std::abs (* nanos);
635+ uint32_t frac_seconds = std::abs (nanos);
629636 while (frac_seconds % 1000 == 0 ) {
630637 frac_seconds /= 1000 ;
631638 digits -= 3 ;
@@ -640,45 +647,47 @@ template <typename Traits>
640647absl::Status WriteDuration (JsonWriter& writer, const Msg<Traits>& msg,
641648 const Desc<Traits>& desc) {
642649 constexpr int64_t kMaxSeconds = int64_t {3652500 } * 86400 ;
643- constexpr int64_t kMaxNanos = 999999999 ;
650+ constexpr int32_t kMaxNanos = 999999999 ;
644651
645652 auto secs_field = Traits::MustHaveField (desc, 1 );
646- auto secs = Traits::GetSize (secs_field, msg) > 0
647- ? Traits::GetInt64 (secs_field, msg)
648- : 0 ;
649- RETURN_IF_ERROR (secs.status ());
653+ auto status_or_secs = Traits::GetSize (secs_field, msg) > 0
654+ ? Traits::GetInt64 (secs_field, msg)
655+ : 0 ;
656+ RETURN_IF_ERROR (status_or_secs.status ());
657+ int64_t secs = *status_or_secs;
650658
651- if (* secs > kMaxSeconds || * secs < -kMaxSeconds ) {
659+ if (secs > kMaxSeconds || secs < -kMaxSeconds ) {
652660 return absl::InvalidArgumentError (" duration out of range" );
653661 }
654662
655663 auto nanos_field = Traits::MustHaveField (desc, 2 );
656- auto nanos = Traits::GetSize (nanos_field, msg) > 0
657- ? Traits::GetInt32 (nanos_field, msg)
658- : 0 ;
659- RETURN_IF_ERROR (nanos.status ());
664+ auto status_or_nanos = Traits::GetSize (nanos_field, msg) > 0
665+ ? Traits::GetInt32 (nanos_field, msg)
666+ : 0 ;
667+ RETURN_IF_ERROR (status_or_nanos.status ());
668+ int32_t nanos = *status_or_nanos;
660669
661- if (* nanos > kMaxNanos || * nanos < -kMaxNanos ) {
670+ if (nanos > kMaxNanos || nanos < -kMaxNanos ) {
662671 return absl::InvalidArgumentError (" duration out of range" );
663672 }
664- if ((* secs != 0 ) && (* nanos != 0 ) && ((* secs < 0 ) != (* nanos < 0 ))) {
673+ if ((secs != 0 ) && (nanos != 0 ) && ((secs < 0 ) != (nanos < 0 ))) {
665674 return absl::InvalidArgumentError (" nanos and seconds signs do not match" );
666675 }
667676
668- if (* nanos == 0 ) {
669- writer.Write (absl::StrFormat (R"( "%ds")" , * secs));
677+ if (nanos == 0 ) {
678+ writer.Write (absl::StrFormat (R"( "%ds")" , secs));
670679 return absl::OkStatus ();
671680 }
672681
673682 size_t digits = 9 ;
674- uint32_t frac_seconds = std::abs (* nanos);
683+ uint32_t frac_seconds = std::abs (nanos);
675684 while (frac_seconds % 1000 == 0 ) {
676685 frac_seconds /= 1000 ;
677686 digits -= 3 ;
678687 }
679688
680- absl::string_view sign = ((* secs < 0 ) || (* nanos < 0 )) ? " -" : " " ;
681- writer.Write (absl::StrFormat (R"( "%s%d.%.*ds")" , sign, std::abs (* secs), digits,
689+ absl::string_view sign = ((secs < 0 ) || (nanos < 0 )) ? " -" : " " ;
690+ writer.Write (absl::StrFormat (R"( "%s%d.%.*ds")" , sign, std::abs (secs), digits,
682691 frac_seconds));
683692 return absl::OkStatus ();
684693}
0 commit comments