Scientific calculator with math syntax that supports user-defined variables and functions, complex numbers, and estimation of derivatives and integrals
Reachable assertion code in core::char::to_digit:L349 caused by input “777_77” in REPL.
Error Message
"thread 'main' panicked at 'to_digit: radix is too high (maximum 36)", /home/nyw0102/s2fuzz/scripts/rust/library/core/src/char/methods.rs:349:13`
ASAN log (SEGV)
`AddressSanitizer:DEADLYSIGNAL
==1969104==ERROR: AddressSanitizer: SEGV on unknown address 0x100080006c6e (pc 0x55555573da2f bp 0x7ffffffea830 sp 0x7ffffffe9fe0 T0)
==1969104==The signal is caused by a READ memory access.
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/home/nyw0102/Test-Sets/kalker/target/x86_64-unknown-linux-gnu/debug/kalker+0x1e9a2f) (BuildId: 0e98ee328013dbca462706015cb56f4bb56e0f94)
==1969104==ABORTING`
Description
First, input “777_77” goes into function “string_to_num” via parameter named “value”
fn string_to_num(value: &str) -> Result<f64, KalkError> { let base = get_base(value)?; if let Some(result) = crate::radix::parse_float_radix(&value.replace(" ", ""), base) { Ok(result) } else { Err(KalkError::InvalidNumberLiteral(value.into())) } }
In this function, the “base” value is initialized by function get_base with parameter “value” which is “777_77”
`fn get_base(value: &str) -> Result<u8, KalkError> {
let underscorepos = if let Some(i) = value.find('') {
i
} else {
return Ok(10);
};
let subscript = value.chars().skip(underscore_pos + 1usize);
if let Some(base) = crate::text_utils::parse_subscript(subscript) {
Ok(base)
} else {
Err(KalkError::UnrecognizedBase)
}
}`
In “getbase(value: &str) function, it erases all letters before “” in string “777_77” and produces an iterator with value “77”. And this returns the value from function “kalker::text_utils::parse_subscript” which is initialized the iterator.
pub fn parse_subscript(chars: impl Iterator<Item = char>) -> Option<u8> { if let Ok(result) = subscript_to_normal(chars).parse::<u8>() { Some(result) } else { None } }
This function returns a value from kalker::text_utils::subscript_to_normal function initiated with “chars”
This function matches each letter in “chars” by iteration. So, this function finally return the value Ok(”77”)
After this process, the “string_to_num” function initialize the value “base” as “Ok(”77”)
Then, this “base’ flows into function “parse_float_radix” as parameter named “base”.
`pub fn parse_float_radix(value: &str, radix: u8) -> Option {
if radix == 10 {
return if let Ok(result) = value.parse::() {
Some(result)
} else {
None
};
}
let mut sum = 0f64;
let length = value.find('_').unwrap_or(value.len());
let mut i = (value.find('.').unwrap_or(length) as i32) - 1;
for c in value.chars() {
if c == '_' {
break;
}
if c == '.' {
continue;
}
let digit = c.to_digit(radix as u32)? as f64;
sum += digit * (radix as f64).powi(i as i32);
i -= 1;
}
Some(sum)
} This function calls to_digit() function with parameter “77” pub const fn to_digit(self, radix: u32) -> Option {
// If not a digit, a number greater than radix will be created.
let mut digit = (self as u32).wrapping_sub('0' as u32);
if radix > 10 {
assert!(radix <= 36, "to_digit: radix is too high (maximum 36)");
if digit < 10 {
return Some(digit);
}
// Force the 6th bit to be set to ensure ascii is lower case.
digit = (self as u32 | 0b10_0000).wrapping_sub('a' as u32).saturating_add(10);
}
// FIXME: once then_some is const fn, use it here
if digit < radix { Some(digit) } else { None }
}`
And finally to_digit() function gets value “77” as ‘radix’ parameter get it encounters assert!(radix <= 36, "to_digit: radix is too high (maximum 36)")
platform: Linux
version: Latest
Overview:
Reachable assertion code in core::char::to_digit:L349 caused by input “777_77” in REPL.
Error Message "thread 'main' panicked at 'to_digit: radix is too high (maximum 36)", /home/nyw0102/s2fuzz/scripts/rust/library/core/src/char/methods.rs:349:13`
ASAN log (SEGV)
`AddressSanitizer:DEADLYSIGNAL
==1969104==ERROR: AddressSanitizer: SEGV on unknown address 0x100080006c6e (pc 0x55555573da2f bp 0x7ffffffea830 sp 0x7ffffffe9fe0 T0) ==1969104==The signal is caused by a READ memory access.
0 0x55555573da2f (/home/nyw0102/Test-Sets/kalker/target/x86_64-unknown-linux-gnu/debug/kalker+0x1e9a2f) (BuildId: 0e98ee328013dbca462706015cb56f4bb56e0f94)
AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV (/home/nyw0102/Test-Sets/kalker/target/x86_64-unknown-linux-gnu/debug/kalker+0x1e9a2f) (BuildId: 0e98ee328013dbca462706015cb56f4bb56e0f94) ==1969104==ABORTING`
Description
First, input “777_77” goes into function “string_to_num” via parameter named “value”
fn string_to_num(value: &str) -> Result<f64, KalkError> { let base = get_base(value)?; if let Some(result) = crate::radix::parse_float_radix(&value.replace(" ", ""), base) { Ok(result) } else { Err(KalkError::InvalidNumberLiteral(value.into())) } }
In this function, the “base” value is initialized by function get_base with parameter “value” which is “777_77” `fn get_base(value: &str) -> Result<u8, KalkError> { let underscorepos = if let Some(i) = value.find('') { i } else { return Ok(10); };}`
In “getbase(value: &str) function, it erases all letters before “” in string “777_77” and produces an iterator with value “77”. And this returns the value from function “kalker::text_utils::parse_subscript” which is initialized the iterator.
pub fn parse_subscript(chars: impl Iterator<Item = char>) -> Option<u8> { if let Ok(result) = subscript_to_normal(chars).parse::<u8>() { Some(result) } else { None } }
This function returns a value from kalker::text_utils::subscript_to_normal function initiated with “chars”
`pub fn subscript_tonormal(chars: impl Iterator- ) -> String {
let mut regular = String::new();
for c in chars {
regular.push(match c {
'₀' => '0',
'₁' => '1',
'₂' => '2',
'₃' => '3',
'₄' => '4',
'₅' => '5',
'₆' => '6',
'₇' => '7',
'₈' => '8',
'₉' => '9',
'₊' => '+',
'₋' => '-',
'₌' => '=',
'₍' => '(',
'₎' => ')',
'ₖ' => 'k',
'ₗ' => 'l',
'ₘ' => 'm',
'ₙ' => 'n',
'ᵀ' => 'T',
=> c,
});
}
} `
This function matches each letter in “chars” by iteration. So, this function finally return the value Ok(”77”) After this process, the “string_to_num” function initialize the value “base” as “Ok(”77”) Then, this “base’ flows into function “parse_float_radix” as parameter named “base”.
`pub fn parse_float_radix(value: &str, radix: u8) -> Option {
if radix == 10 {
return if let Ok(result) = value.parse::() {
Some(result)
} else {
None
};
}
} {
// If not a digit, a number greater than radix will be created.
let mut digit = (self as u32).wrapping_sub('0' as u32);
if radix > 10 {
assert!(radix <= 36, "to_digit: radix is too high (maximum 36)");
if digit < 10 {
return Some(digit);
}
// Force the 6th bit to be set to ensure ascii is lower case.
digit = (self as u32 | 0b10_0000).wrapping_sub('a' as u32).saturating_add(10);
}
// FIXME: once then_some is const fn, use it here
if digit < radix { Some(digit) } else { None }
}`
And finally to_digit() function gets value “77” as ‘radix’ parameter get it encounters assert!(radix <= 36, "to_digit: radix is too high (maximum 36)")
This function calls to_digit() function with parameter “77”
pub const fn to_digit(self, radix: u32) -> OptionHow to Reproduce