diff --git a/src/Functions/GatherUtils/Algorithms.h b/src/Functions/GatherUtils/Algorithms.h index 620d6439af2..101e1354bc6 100644 --- a/src/Functions/GatherUtils/Algorithms.h +++ b/src/Functions/GatherUtils/Algorithms.h @@ -342,7 +342,7 @@ void NO_INLINE sliceDynamicOffsetUnbounded(Source && src, Sink && sink, const IC if (offset > 0) slice = src.getSliceFromLeft(offset - 1); else - slice = src.getSliceFromRight(-offset); + slice = src.getSliceFromRight(-UInt64(offset)); writeSlice(slice, sink); } @@ -374,7 +374,7 @@ void NO_INLINE sliceDynamicOffsetBounded(Source && src, Sink && sink, const ICol Int64 size = has_length ? length_nested_column->getInt(row_num) : static_cast(src.getElementSize()); if (size < 0) - size += offset > 0 ? static_cast(src.getElementSize()) - (offset - 1) : -offset; + size += offset > 0 ? static_cast(src.getElementSize()) - (offset - 1) : -UInt64(offset); if (offset != 0 && size > 0) { @@ -383,7 +383,7 @@ void NO_INLINE sliceDynamicOffsetBounded(Source && src, Sink && sink, const ICol if (offset > 0) slice = src.getSliceFromLeft(offset - 1, size); else - slice = src.getSliceFromRight(-offset, size); + slice = src.getSliceFromRight(-UInt64(offset), size); writeSlice(slice, sink); } diff --git a/tests/queries/0_stateless/01658_substring_ubsan.reference b/tests/queries/0_stateless/01658_substring_ubsan.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/0_stateless/01658_substring_ubsan.sql b/tests/queries/0_stateless/01658_substring_ubsan.sql new file mode 100644 index 00000000000..3d7968b8d6b --- /dev/null +++ b/tests/queries/0_stateless/01658_substring_ubsan.sql @@ -0,0 +1,10 @@ +/** NOTE: The behaviour of substring and substringUTF8 is inconsistent when negative offset is greater than string size: + * substring: + * hello + * ^-----^ - offset -10, length 7, result: "he" + * substringUTF8: + * hello + * ^-----^ - offset -10, length 7, result: "hello" + * This may be subject for change. + */ +SELECT substringUTF8('hello, п�иве�', -9223372036854775808, number) FROM numbers(16) FORMAT Null;