Description:
There exist a logical error in the function Field_varstring::val_real and Field_varstring::val_int. For example, the Field_varstring::val_int code is following.
6565 longlong Field_varstring::val_int() const {
6566 ASSERT_COLUMN_MARKED_FOR_READ;
6567 int error;
6568 const char *end;
6569 const CHARSET_INFO *cs = charset();
6570
6571 uint length = data_length();
6572 longlong result =
6573 my_strntoll(cs, (char *)ptr + length_bytes, length, 10, &end, &error);
6574
6575 if ((error || (length != (uint)(end - (char *)ptr + length_bytes) &&
6576 !check_if_only_end_space(
6577 cs, end, (char *)ptr + length_bytes + length)))) {
6578 push_numerical_conversion_warning(current_thd, (char *)ptr + length_bytes,
6579 length, cs, "INTEGER",
6580 ER_TRUNCATED_WRONG_VALUE);
6581 }
6582 return result;
6583 }
In the if statement, the judgment "(length != (uint)(end - (char *)ptr + length_bytes)" always is true. As demonstrated in the figure below, the "(end - (char *)ptr + length_bytes)" is equal “length+ 2*length_bytes”. It always greater than "length".
|-----------------|----------------------------|
| length_bytes | length |
ptr ptr+length_bytes end
How to repeat:
As above.
Suggested fix:
The "(length != (uint)(end - (char *)ptr + length_bytes)" should be fixed as "(length != (uint)(end - (char *)ptr - length_bytes)".