diff --git a/conformance/BUILD b/conformance/BUILD index ce8ee59e7..5d8fe7e7a 100644 --- a/conformance/BUILD +++ b/conformance/BUILD @@ -136,9 +136,6 @@ cc_binary( "--skip_test=fields/qualified_identifier_resolution/map_field_select", "--skip_test=fields/qualified_identifier_resolution/ident_with_longest_prefix_check", # New conformance tests awaiting synchronization. - "--skip_test=basic/self_eval_nonzeroish/self_eval_int_hex", - "--skip_test=basic/self_eval_nonzeroish/self_eval_int_hex_negative", - "--skip_test=basic/self_eval_nonzeroish/self_eval_uint_hex", "--skip_test=basic/functions/unbound", "--skip_test=basic/functions/unbound_is_runtime_error", "--skip_test=comparisons/eq_literal/not_eq_list_false_vs_types", diff --git a/parser/parser_test.cc b/parser/parser_test.cc index 62fb88861..d06899da2 100644 --- a/parser/parser_test.cc +++ b/parser/parser_test.cc @@ -138,6 +138,9 @@ std::vector test_cases = { {"0u", "0u^#1:uint64#"}, {"23u", "23u^#1:uint64#"}, {"24u", "24u^#1:uint64#"}, + {"0xAu", "10u^#1:uint64#"}, + {"-0xA", "-10^#1:int64#"}, + {"0xA", "10^#1:int64#"}, {"-1", "-1^#1:int64#"}, {"4--4", "_-_(\n" diff --git a/parser/visitor.cc b/parser/visitor.cc index 7ba3a0917..037d6b4b6 100644 --- a/parser/visitor.cc +++ b/parser/visitor.cc @@ -7,6 +7,7 @@ #include "absl/strings/numbers.h" #include "absl/strings/str_format.h" #include "absl/strings/str_join.h" +#include "absl/strings/match.h" #include "common/escaping.h" #include "common/operators.h" #include "parser/balancer.h" @@ -400,9 +401,13 @@ antlrcpp::Any ParserVisitor::visitInt(CelParser::IntContext* ctx) { if (ctx->sign) { value = ctx->sign->getText(); } + int base = 10; + if (absl::StartsWith(ctx->tok->getText(), "0x")) { + base = 16; + } value += ctx->tok->getText(); int64_t int_value; - if (absl::SimpleAtoi(value, &int_value)) { + if (absl::numbers_internal::safe_strto64_base(value, &int_value, base)) { return sf_->newLiteralInt(ctx, int_value); } else { return sf_->reportError(ctx, "invalid int literal"); @@ -415,8 +420,12 @@ antlrcpp::Any ParserVisitor::visitUint(CelParser::UintContext* ctx) { if (!value.empty()) { value.resize(value.size() - 1); } + int base = 10; + if (absl::StartsWith(value, "0x")) { + base = 16; + } uint64_t uint_value; - if (absl::SimpleAtoi(value, &uint_value)) { + if (absl::numbers_internal::safe_strtou64_base(value, &uint_value, base)) { return sf_->newLiteralUint(ctx, uint_value); } else { return sf_->reportError(ctx, "invalid uint literal");