Skip to content

Commit 95a2cff

Browse files
l46kokcopybara-github
authored andcommitted
Fix conformance issues around overflows
PiperOrigin-RevId: 955074851
1 parent 0bd9173 commit 95a2cff

5 files changed

Lines changed: 33 additions & 22 deletions

File tree

common/src/main/java/dev/cel/common/internal/ProtoAdapter.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,10 +353,14 @@ private BidiConverter fieldToValueConverter(FieldDescriptor fieldDescriptor) {
353353
case ENUM:
354354
return BidiConverter.<Object, Long>of(
355355
value -> (long) ((EnumValueDescriptor) value).getNumber(),
356-
number ->
357-
fieldDescriptor
358-
.getEnumType()
359-
.findValueByNumberCreatingIfUnknown(number.intValue()));
356+
number -> {
357+
if (number > Integer.MAX_VALUE || number < Integer.MIN_VALUE) {
358+
throw new IllegalArgumentException("Enum value out of int32 range: " + number);
359+
}
360+
return fieldDescriptor
361+
.getEnumType()
362+
.findValueByNumberCreatingIfUnknown(number.intValue());
363+
});
360364
case MESSAGE:
361365
return BidiConverter.<MessageOrBuilder, Object>of(
362366
this::adaptProtoToValue,

common/src/main/java/dev/cel/common/internal/ProtoTimeUtils.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,10 @@ public static Duration between(Timestamp from, Timestamp to) {
406406
Instant javaTo = ProtoTimeUtils.toJavaInstant(checkValid(to));
407407

408408
java.time.Duration between = java.time.Duration.between(javaFrom, javaTo);
409+
// Call toNanos() to validate 64-bit nanosecond overflow (throws ArithmeticException).
410+
// Suppress unused variable warning as the duration object itself is returned.
411+
@SuppressWarnings("unused")
412+
long unused = between.toNanos();
409413

410414
return ProtoTimeUtils.toProtoDuration(between);
411415
}

conformance/src/test/java/dev/cel/conformance/BUILD.bazel

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,7 @@ _TESTS_TO_SKIP_LEGACY = [
108108
# TODO: Support setting / getting enum values out of the defined enum value range.
109109
"enums/legacy_proto2/select_big,select_neg",
110110
"enums/legacy_proto2/assign_standalone_int_big,assign_standalone_int_neg",
111-
# TODO: Generate errors on enum value assignment overflows for proto3.
112-
"enums/legacy_proto3/assign_standalone_int_too_big,assign_standalone_int_too_neg",
113-
# TODO: Ensure overflow occurs on conversions of double values which might not work properly on all platforms.
114-
"conversions/int/double_int_min_range",
115-
# TODO: Duration and timestamp operations should error on overflow.
116-
"timestamps/timestamp_range/sub_time_duration_over,sub_time_duration_under",
111+
117112
# TODO: Ensure adding negative duration values is appropriately supported.
118113
"timestamps/timestamp_arithmetic/add_time_to_duration_nanos_negative",
119114

@@ -154,15 +149,6 @@ _TESTS_TO_SKIP_PLANNER = [
154149
# TODO: Check behavior for go/cpp
155150
"basic/functions/unbound_is_runtime_error",
156151

157-
# TODO: Ensure overflow occurs on conversions of double values which might not work properly on all platforms.
158-
"conversions/int/double_int_min_range",
159-
"enums/legacy_proto3/assign_standalone_int_too_big",
160-
"enums/legacy_proto3/assign_standalone_int_too_neg",
161-
162-
# TODO: Duration and timestamp operations should error on overflow.
163-
"timestamps/timestamp_range/sub_time_duration_over",
164-
"timestamps/timestamp_range/sub_time_duration_under",
165-
166152
# Skip until fixed.
167153
"parse/receiver_function_names",
168154

runtime/src/main/java/dev/cel/runtime/RuntimeHelpers.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ public static Optional<UnsignedLong> doubleToUnsignedChecked(double v) {
391391
public static Optional<Long> doubleToLongChecked(double v) {
392392
// getExponent of NaN or Infinite values will return a Double.MAX_EXPONENT + 1 (or 128)
393393
int exp = Math.getExponent(v);
394-
if (exp >= 63 && v != Math.scalb(-1.0, 63)) {
394+
if (exp >= 63) {
395395
return Optional.empty();
396396
}
397397
return Optional.of((long) v);

runtime/src/main/java/dev/cel/runtime/standard/SubtractOperator.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,30 @@ public enum SubtractOverload implements CelStandardOverload {
6868
"subtract_timestamp_timestamp",
6969
Instant.class,
7070
Instant.class,
71-
(Instant i1, Instant i2) -> java.time.Duration.between(i2, i1));
71+
(Instant i1, Instant i2) -> {
72+
java.time.Duration between = java.time.Duration.between(i2, i1);
73+
try {
74+
// Call toNanos() to validate 64-bit nanosecond overflow (throws
75+
// ArithmeticException).
76+
@SuppressWarnings("unused")
77+
long unused = between.toNanos();
78+
} catch (ArithmeticException e) {
79+
throw new CelNumericOverflowException(e);
80+
}
81+
return between;
82+
});
7283
} else {
7384
return CelFunctionBinding.from(
7485
"subtract_timestamp_timestamp",
7586
Timestamp.class,
7687
Timestamp.class,
77-
(Timestamp t1, Timestamp t2) -> ProtoTimeUtils.between(t2, t1));
88+
(Timestamp t1, Timestamp t2) -> {
89+
try {
90+
return ProtoTimeUtils.between(t2, t1);
91+
} catch (ArithmeticException e) {
92+
throw new CelNumericOverflowException(e);
93+
}
94+
});
7895
}
7996
}),
8097
SUBTRACT_TIMESTAMP_DURATION(

0 commit comments

Comments
 (0)