MySQL和MariaDB-将一个表示十进制值的字符串(带有许多前导零)转换为数值会产生意外的结果



当将一个包含多个前导零的表示十进制值的字符串强制转换为数值MySQL和MariaDB时,会出现意外结果-启用严格模式时会发生Out of range value错误,禁用严格模式时则会显示Out of range value警告,并将结果钳制为给定精度的最大十进制值。例如:

SELECT CAST(0000000000000000000000000000000000000000000000000000000000000000000000000000000020.01 AS DECIMAL(15,2)) as val;给出9999999999999.99

但实际上它并不是超出范围的值,它只是有许多前导零的值!为什么它会这样工作?在MS SQLPostgreSQL中,不会发生这种情况

当我们开始研究这种行为时,当输入字符串超过83个符号时,禁用严格模式会发生错误。83限制与MySQLC源代码中的DECIMAL_MAX_STR_LENGTH常数有关,当输入字符串比该常数长时,结果值被设置为给定精度的最大十进制值。该错误存在于MySQL 8.0MariaDB 10.4.13中,可能也存在于它们的旧版本中。

在某些情况下,这可能是危险的,例如在使用MySQL的在线金融服务中。恶意人员可以使用此漏洞通过输入带有多个前导零的sum来在其帐户上获得大笔资金。

我们向MySQL开发人员报告了这个错误,他们回答说这是

已知行为。简单地说,数字数据类型有其局限性。这具体的限制描述得不太好,尤其是如果你溢出,会发生什么事。

他们决定不修复此问题,但将其描述添加到了文档中。

此外,我们向MariaDB报告,他们已经解决了问题

最新更新