Bug #81685 "select current_time(256)" succeeds while error is expected
Submitted: 2 Jun 2016 9:43 Modified: 2 Jun 2016 9:54
Reporter: Su Dylan Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: DML Severity:S3 (Non-critical)
Version:5.7.8, 5.6.12 OS:Any
Assigned to: CPU Architecture:Any

[2 Jun 2016 9:43] Su Dylan
Description:
Output:
===
mysql> select current_time(6);
+-----------------+
| current_time(6) |
+-----------------+
| 17:41:16.994799 |
+-----------------+
1 row in set (0.00 sec)

mysql> select current_time(7);
ERROR 1426 (42000): Too-big precision 7 specified for 'curtime'. Maximum is 6.
mysql> select current_time(256);
+-------------------+
| current_time(256) |
+-------------------+
| 17:41:28          |
+-------------------+
1 row in set (0.00 sec)

Problem:
===
"select current_time(256)" is expected to fail with "Too-big precision".

How to repeat:
select current_time(256);

Suggested fix:
"select current_time(256)" fails with "Too-big precision".
[2 Jun 2016 9:54] MySQL Verification Team
Hello Su Dylan,

Thank you for the report and test case.
Observed that 5.7.12 is affected.

Thanks,
Umesh
[2 Jun 2016 12:53] Peter Laursen
A few more observations:

-- it wraps around any modulus of 256 (=2^8). So some uncheked 1-byte buffer seems to bethe culprit
SELECT CURRENT_TIME(257); -- 14:42:38.1  
SELECT CURRENT_TIME(262); -- 14:43:24.621965    
SELECT CURRENT_TIME(263); -- Too-big precision 7 specified for 'curtime'. Maximum is 6.

-- note here the modulus 20 of the calculation 788 = (3*256) + 20
SELECT CURRENT_TIME(788); -- Too-big precision 20 specified for 'curtime'.
 Maximum is 6.

- Peter
-- not a MySQL/Oracle erson.
[2 Jun 2016 13:20] Peter Laursen
MariaDB 10.1.14 is fine:

SELECT CURRENT_TIME(256); -- Too big precision 256 specified for 'curtime'. Maximum is 6.
SELECT CURRENT_TIME(788); -- Too big precision 788 specified for 'curtime'. Maximum is 6.
[2 Jun 2016 13:28] MySQL Verification Team
In the parser code...

CURTIME func_datetime_precision
{
  $$= NEW_PTN Item_func_curtime_local(@$, static_cast<uint8>($2));
}
[2 Jun 2016 13:51] Peter Laursen
Besides, can we have the error message reframed from "Too-big .. " to "Too big ..".

I don't know what "Too-big" is, but I know what "Too big" means"! :-(
[2 Jun 2016 18:37] Peter Laursen
OK .. thanks to Shane (again). This is indeed a variant of what I thought/guessed from the behavior with unrealistic large parametrs.

"uint8" in the code here is a 1-byte integer not protected from overflowing resulting in wrapping around (n*(2^8)) where "n" is any integer.

A few old issues of mine:
http://bugs.mysql.com/bug.php?id=42698
http://bugs.mysql.com/bug.php?id=75286

So not properly checking for overflow for integers and/or using unrealistic short integer variants resulting in wrapping even with realistic use cases seems to have been a bad habit of MySQL developers for long time. Though this problem basically may be rooted in the "C" language itself (it would not happen in Algol/Pascal/Ada language family, that I know best) there should be several ways to prevent this.