当将一个包含多个前导零的表示十进制值的字符串强制转换为数值MySQL和MariaDB时,会出现意外结果-启用严格模式时会发生Out of range value
错误,禁用严格模式时则会显示Out of range value
警告,并将结果钳制为给定精度的最大十进制值。例如:
SELECT CAST(0000000000000000000000000000000000000000000000000000000000000000000000000000000020.01 AS DECIMAL(15,2)) as val;
给出9999999999999.99
但实际上它并不是超出范围的值,它只是有许多前导零的值!为什么它会这样工作?在MS SQL
和PostgreSQL
中,不会发生这种情况
当我们开始研究这种行为时,当输入字符串超过83个符号时,禁用严格模式会发生错误。83
限制与MySQL
C
源代码中的DECIMAL_MAX_STR_LENGTH
常数有关,当输入字符串比该常数长时,结果值被设置为给定精度的最大十进制值。该错误存在于MySQL 8.0
和MariaDB 10.4.13
中,可能也存在于它们的旧版本中。
在某些情况下,这可能是危险的,例如在使用MySQL的在线金融服务中。恶意人员可以使用此漏洞通过输入带有多个前导零的sum来在其帐户上获得大笔资金。
我们向MySQL
开发人员报告了这个错误,他们回答说这是
已知行为。简单地说,数字数据类型有其局限性。这具体的限制描述得不太好,尤其是如果你溢出,会发生什么事。
他们决定不修复此问题,但将其描述添加到了文档中。
此外,我们向MariaDB
报告,他们已经解决了问题