From 5c993bf8e8cde97fe82c6d6eec4befeb1527bdac Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 26 Feb 2026 10:25:51 +0300 Subject: [PATCH] strconv: fix common_parse_int not giving result when needed (fixes #17031) --- vlib/strconv/atoi.v | 10 +++++++--- vlib/strconv/atoi_test.v | 7 +++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/vlib/strconv/atoi.v b/vlib/strconv/atoi.v index fbcc3ea14..07689fb99 100644 --- a/vlib/strconv/atoi.v +++ b/vlib/strconv/atoi.v @@ -190,11 +190,15 @@ pub fn common_parse_int(_s string, base int, _bit_size int, error_on_non_digit b // TODO: check should u64(bit_size-1) be size of int (32)? cutoff := u64(1) << u64(bit_size - 1) if !neg && un >= cutoff { - // return error('parse_int: range error ${s0}') + if error_on_high_digit { + return error('common_parse_int: integer overflow ${_s}') + } return i64(cutoff - u64(1)) } if neg && un > cutoff { - // return error('parse_int: range error ${s0}') + if error_on_high_digit { + return error('common_parse_int: integer overflow ${_s}') + } return -i64(cutoff) } return if neg { -i64(un) } else { i64(un) } @@ -213,7 +217,7 @@ pub fn common_parse_int(_s string, base int, _bit_size int, error_on_non_digit b // correspond to int, int8, int16, int32, and int64. // If bitSize is below 0 or above 64, an error is returned. pub fn parse_int(_s string, base int, _bit_size int) !i64 { - return common_parse_int(_s, base, _bit_size, true, true) + return common_parse_int(_s, base, _bit_size, true, false) } // atoi_common_check perform basics check on string to parse: diff --git a/vlib/strconv/atoi_test.v b/vlib/strconv/atoi_test.v index e54ea520b..bc54a7b83 100644 --- a/vlib/strconv/atoi_test.v +++ b/vlib/strconv/atoi_test.v @@ -341,6 +341,13 @@ fn test_parse_int() { } } +fn test_common_parse_int_error_on_high_digit() { + assert strconv.common_parse_int('9223372036854775808', 0, 64, false, true) or { 1 } == 1 + assert strconv.common_parse_int('-9223372036854775809', 0, 64, false, true) or { 1 } == 1 + assert strconv.common_parse_int('9223372036854775808', 0, 64, false, false) or { 1 } == max_i64 + assert strconv.common_parse_int('-9223372036854775809', 0, 64, false, false) or { 1 } == min_i64 +} + fn test_common_parse_uint2() { mut result, mut error := strconv.common_parse_uint2('1', 10, 8) assert result == 1 -- 2.39.5