diff --git a/common/values/string_value.cc b/common/values/string_value.cc index b9495fa69..914f6e496 100644 --- a/common/values/string_value.cc +++ b/common/values/string_value.cc @@ -667,8 +667,11 @@ absl::StatusOr> SubstringImpl( ++size_code_points; size_code_units += code_units; } - if (size_code_points == start && start == end) { - return std::pair{size_code_units, size_code_units}; + if (size_code_points == start) { + start_code_units = size_code_units; + } + if (size_code_points == end) { + return std::pair{start_code_units, size_code_units}; } return absl::InvalidArgumentError( ".substring(, ): or is greater than " @@ -697,8 +700,11 @@ absl::StatusOr> SubstringImpl(const absl::Cord& cord, ++size_code_points; size_code_units += code_units; } - if (size_code_points == start && start == end) { - return std::pair{size_code_units, size_code_units}; + if (size_code_points == start) { + start_code_units = size_code_units; + } + if (size_code_points == end) { + return std::pair{start_code_units, size_code_units}; } return absl::InvalidArgumentError( ".substring(, ): or is greater than " diff --git a/common/values/string_value_test.cc b/common/values/string_value_test.cc index 6bfcb83aa..c64151034 100644 --- a/common/values/string_value_test.cc +++ b/common/values/string_value_test.cc @@ -475,6 +475,12 @@ TEST_F(StringValueTest, Substring) { EXPECT_THAT(unicode_view.Substring(1, 2, arena()), StringValueIs("€")); EXPECT_THAT(unicode_cord.Substring(2, 4, arena()), StringValueIs("€€")); EXPECT_THAT(unicode_view.Substring(2, 4, arena()), StringValueIs("€€")); + EXPECT_THAT(unicode_cord.Substring(4, 6, arena()), StringValueIs("€€")); + EXPECT_THAT(unicode_view.Substring(4, 6, arena()), StringValueIs("€€")); + EXPECT_THAT(unicode_cord.Substring(0, 6, arena()), StringValueIs("€€€€€€")); + EXPECT_THAT(unicode_view.Substring(0, 6, arena()), StringValueIs("€€€€€€")); + EXPECT_THAT(unicode_cord.Substring(6, 6, arena()), StringValueIs("")); + EXPECT_THAT(unicode_view.Substring(6, 6, arena()), StringValueIs("")); EXPECT_THAT(unicode_cord.Substring(2, arena()), StringValueIs("€€€€")); EXPECT_THAT(unicode_view.Substring(2, arena()), StringValueIs("€€€€")); diff --git a/extensions/strings_test.cc b/extensions/strings_test.cc index c3059808f..46d9908eb 100644 --- a/extensions/strings_test.cc +++ b/extensions/strings_test.cc @@ -221,7 +221,10 @@ INSTANTIATE_TEST_SUITE_P( "'tacocat'.substring(4) == 'cat'", "'tacocat'.substring(7) == ''", "'tacocat'.substring(0, 4) == 'taco'", "'tacocat'.substring(4, 4) == ''", + "'tacocat'.substring(4, 7) == 'cat'", + "'tacocat'.substring(0, 7) == 'tacocat'", "'ta©o©αT'.substring(2, 6) == '©o©α'", + "'ta©o©αT'.substring(4, 7) == '©αT'", "'ta©o©αT'.substring(7, 7) == ''", // Tests for reverse()