Skip to content

fix out-of-range double-to-int UB in proto map key lookup#2050

Open
sahvx655-wq wants to merge 1 commit into
google:masterfrom
sahvx655-wq:map-key-double-cast-ub
Open

fix out-of-range double-to-int UB in proto map key lookup#2050
sahvx655-wq wants to merge 1 commit into
google:masterfrom
sahvx655-wq:map-key-double-cast-ub

Conversation

@sahvx655-wq

Copy link
Copy Markdown
Contributor

The four ValueAsInt32/ValueAsInt64/ValueAsUInt32/ValueAsUInt64 helpers in parsed_map_field_value.cc coerce a double map key to the proto key's integer type, but they run the static_cast before checking the value is in range. Converting an out-of-range, negative (for an unsigned key), or non-finite double to an integer type is undefined behaviour, and a -fsanitize=float-cast-overflow build aborts with "1e+19 is outside the range of representable values of type 'long long'". It is reachable from any expression that indexes or tests membership on an integer-keyed proto map field with a double key, which CEL accepts ({1: 'x'}[1.0] is defined to work), for example msg.map_int64_int64[1e19] or the same value passed through dyn().

internal/number.h already gets this right for in-memory maps by range-checking the double before narrowing. The fix routes each double branch through cel::internal::Number, so the lossless-convertibility check runs first and AsInt/AsUint only see a value known to be representable. Behaviour for valid keys is unchanged and previously-undefined keys now report a miss. All four sibling helpers shared the defect, so all four are covered, with a regression test over the int32/int64/uint32/uint64 map fields.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant