[MDEV-27480] Functions don't validate arguments properly and cast/truncate values without warnings or errors Created: 2022-01-12 Updated: 2023-11-28 |
|
| Status: | Stalled |
| Project: | MariaDB Server |
| Component/s: | Server |
| Affects Version/s: | 10.2, 10.3, 10.4, 10.5, 10.6, 10.7 |
| Fix Version/s: | 10.11 |
| Type: | Bug | Priority: | Major |
| Reporter: | Elena Stepanova | Assignee: | Elena Stepanova |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||
| Description |
|
Since CRC32(par, expr) and CRC32C(par, expr) presume the par part to be an already calculated CRC32 value, it has to be a 32-bit unsigned integer. However, they don't check it to be in the range, they just either truncate or roll over all other numeric values silently, without warnings or errors:
It does however validate it to be numeric, so the behavior is at least inconsistent.
|
| Comments |
| Comment by Elena Stepanova [ 2022-01-12 ] | ||||||||||||||||||||||||||
|
Actually there is some validation, but it's even more confusing – what's converted to what and why
| ||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2022-01-14 ] | ||||||||||||||||||||||||||
|
I added the following test case:
Appending an empty string will not change the checksum. Only a warning is being added; the argument was already being truncated to its least significant 32 bits. | ||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2022-01-14 ] | ||||||||||||||||||||||||||
|
For the record, also the first warning with strange empty string for the following is being issued already before the parser has resolved the crc32() function:
| ||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2022-01-14 ] | ||||||||||||||||||||||||||
|
The Item::val_int() function interface returns the result in longlong and Item::null_value and Item::unsigned_flag. This means that conversions will necessarily occur in two steps: first, to 64-bit signed or unsigned integer, and then (within the 2-ary CRC32() and CRC32C() functions) to 32-bit unsigned integer. Functions that expect an integer argument normally invoke Item::val_int(). For arguments whose type is a string, there is a wrapper that converts them to integers. That wrapper would issue a warning for invalid strings, such as '' (0) or '24/7' (24). Similarly, floating-point values will be converted by an Item::val_int() wrapper that would apparently return the integer part of the value. I consider those conversions to be outside the scope of the implementation of any function whose arguments are integers. Those affect many other functions, such as substr('',429496729656755555555555555555555555555555555555555555555555555555555555555555555555555). I fixed those cases that clearly are within the control of the function:
| ||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2022-01-21 ] | ||||||||||||||||||||||||||
|
Re-opening as It wasn't fixed, it was decided that since it's a general legacy problem which many functions have, it should be fixed in a consistent way everywhere. |