File tree Expand file tree Collapse file tree 4 files changed +742
-5
lines changed
main/java/com/google/firebase/firestore
test/java/com/google/firebase/firestore/pipeline Expand file tree Collapse file tree 4 files changed +742
-5
lines changed Original file line number Diff line number Diff line change @@ -750,11 +750,32 @@ internal object Values {
750750
751751 @JvmStatic
752752 fun timestamp (seconds : Long , nanos : Int ): Timestamp {
753+ validateRange(seconds, nanos)
754+
753755 // Firestore backend truncates precision down to microseconds. To ensure offline mode works
754756 // the same with regards to truncation, perform the truncation immediately without waiting for
755757 // the backend to do that.
756758 val truncatedNanoseconds: Int = nanos / 1000 * 1000
757-
758759 return Timestamp .newBuilder().setSeconds(seconds).setNanos(truncatedNanoseconds).build()
759760 }
761+
762+ /* *
763+ * Ensures that the date and time are within what we consider valid ranges.
764+ *
765+ * More specifically, the nanoseconds need to be less than 1 billion- otherwise it would trip over
766+ * into seconds, and need to be greater than zero.
767+ *
768+ * The seconds need to be after the date `1/1/1` and before the date `1/1/10000`.
769+ *
770+ * @throws IllegalArgumentException if the date and time are considered invalid
771+ */
772+ private fun validateRange (seconds : Long , nanoseconds : Int ) {
773+ require(nanoseconds in 0 until 1_000_000_000 ) {
774+ " Timestamp nanoseconds out of range: $nanoseconds "
775+ }
776+
777+ require(seconds in - 62_135_596_800 until 253_402_300_800 ) {
778+ " Timestamp seconds out of range: $seconds "
779+ }
780+ }
760781}
Original file line number Diff line number Diff line change @@ -26,8 +26,11 @@ internal sealed class EvaluateResult(val value: Value?) {
2626 fun timestamp (timestamp : Timestamp ): EvaluateResult =
2727 EvaluateResultValue (encodeValue(timestamp))
2828 fun timestamp (seconds : Long , nanos : Int ): EvaluateResult =
29- if (seconds !in - 62_135_596_800 until 253_402_300_800 ) EvaluateResultError
30- else timestamp(Values .timestamp(seconds, nanos))
29+ try {
30+ timestamp(Values .timestamp(seconds, nanos))
31+ } catch (e: IllegalArgumentException ) {
32+ EvaluateResultError
33+ }
3134 }
3235}
3336
Original file line number Diff line number Diff line change @@ -568,14 +568,14 @@ internal val evaluateTimestampToUnixSeconds = unaryFunction { t: Timestamp ->
568568internal val evaluateUnixMicrosToTimestamp = unaryFunction { micros: Long ->
569569 EvaluateResult .timestamp(
570570 Math .floorDiv(micros, L_MICROS_PER_SECOND ),
571- Math .floorMod(micros, I_MICROS_PER_SECOND )
571+ Math .floorMod(micros, I_MICROS_PER_SECOND ) * 1000
572572 )
573573}
574574
575575internal val evaluateUnixMillisToTimestamp = unaryFunction { millis: Long ->
576576 EvaluateResult .timestamp(
577577 Math .floorDiv(millis, L_MILLIS_PER_SECOND ),
578- Math .floorMod(millis, I_MILLIS_PER_SECOND )
578+ Math .floorMod(millis, I_MILLIS_PER_SECOND ) * 1000_000
579579 )
580580}
581581
You can’t perform that action at this time.
0 commit comments