diff --git a/cpp/src/arrow/compute/kernels/scalar_string_ascii.cc b/cpp/src/arrow/compute/kernels/scalar_string_ascii.cc index 8e7b626837fe..6b4d01c66ed9 100644 --- a/cpp/src/arrow/compute/kernels/scalar_string_ascii.cc +++ b/cpp/src/arrow/compute/kernels/scalar_string_ascii.cc @@ -2642,7 +2642,8 @@ struct SliceBytesTransform : StringSliceTransformBase { // on the resulting slice lengths, so return a worst case estimate. return input_bytes; } - int64_t max_slice_bytes = (opt.stop - opt.start + opt.step - 1) / opt.step; + const int64_t stop = std::clamp(opt.stop, -input_bytes, input_bytes); + int64_t max_slice_bytes = (stop - opt.start + opt.step - 1) / opt.step; return std::min(input_bytes, ninputs * std::max(0, max_slice_bytes)); } diff --git a/cpp/src/arrow/compute/kernels/scalar_string_test.cc b/cpp/src/arrow/compute/kernels/scalar_string_test.cc index 74650c1d76c5..66eef0965a7e 100644 --- a/cpp/src/arrow/compute/kernels/scalar_string_test.cc +++ b/cpp/src/arrow/compute/kernels/scalar_string_test.cc @@ -2702,6 +2702,13 @@ TYPED_TEST(TestBinaryKernels, SliceBytesBasic) { } TYPED_TEST(TestBinaryKernels, SliceBytesPosPos) { + SliceOptions options_default_stop{/*start=*/1}; + const std::string long_input(300, 'x'); + this->CheckUnary( + "binary_slice", this->template MakeArray({"abcdef", long_input}), + this->template MakeArray({"bcdef", std::string(299, 'x')}), + &options_default_stop); + SliceOptions options{2, 4}; this->CheckUnary( "binary_slice",