mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
What was wrong: The mysqltest expression evaluator did signed arithmetic without checking that the result fits in long long. Boundary expressions triggered undefined behavior or returned mathematically wrong wrapped values, e.g. -9223372036854775808 / -1 gave -9223372036854775808, and unsigned 18446744073709551615 + 1 gave 0. How it is fixed: Check unary minus, +, -, *, / and abs() before evaluating and die() with an "Evaluation error: ... overflow" message when the result is not representable in 64 bits. Unsigned +, - and * are checked the same way; an unsigned difference that is negative but fits in long long is returned as a signed value. A negative signed operand mixed with an unsigned one is rejected instead of being silently converted. Valid boundary results are kept: -9223372036854775808 % -1 = 0 and -4611686018427387904 * 2 = -9223372036854775808. Unary minus on an unsigned value still wraps, as conv(-~0, ...) in main.mysqltest_string_functions relies on it. How it is tested: main.mysqltest_expression_evaluation: the former wrapping cases now expect an error, and signed and unsigned overflow cases were added. main.mysqltest, main.mysqltest_string_functions and the other tests using $() pass, also with --ps-protocol.