Bug #121111 Hex Result Metadata Uint32 Wrap
Submitted: 18 Aug 9:15 Modified: 19 Aug 8:22
Reporter: xingwang Verdant Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S3 (Non-critical)
Version:8.0.46, 8.4.11, 9.7.2 OS:Any
Assigned to: CPU Architecture:Any

[18 Aug 9:15] xingwang Verdant
Description:
# `HEX()` metadata overflow truncates grouped results

## Summary

`HEX()` doubles its argument's declared maximum length with unchecked 32-bit
arithmetic. A legal expression descriptor just above `2^31` therefore wraps
to a tiny width. Direct evaluation returns the complete value, while a
temporary-table consumer such as `GROUP BY` silently truncates it.

This is a Release-build result-integrity bug. It does not require a large row,
large packet, malformed storage, or an extension. The reproducer stores one
byte and the server remains alive.

## Affected version

Reproduced twice on MySQL Community Server 8.4.10, both the official optimized
image and an exact-source Debug+ASan build. The same arithmetic is retained in
the checked MySQL 8.4.11 source revision.

## Reproduction

Run the file with a user that can create objects in a test schema:

```sh
mysql --force -uroot -p < reproduce.sql
```

The control and trigger differ only in the `SUBSTRING()` start position:
`2147483646` versus `2147483647`. Both select the same runtime value `AA`.

Expected observations:

- direct control and trigger both return `4141`;
- grouped control returns `4141`;
- grouped trigger returns only `41`;
- the control view declares four bytes, while the trigger view declares two.

How to repeat:
DROP DATABASE IF EXISTS h54;
CREATE DATABASE h54;
USE h54;
CREATE TABLE source_data(a LONGBLOB);
INSERT INTO source_data VALUES (_binary'A');

SELECT HEX(IF(a IS NOT NULL,_binary'AA',SUBSTRING(a,2147483646)))
       AS control_direct
FROM source_data;
SELECT HEX(IF(a IS NOT NULL,_binary'AA',SUBSTRING(a,2147483647)))
       AS trigger_direct
FROM source_data;

SELECT HEX(IF(a IS NOT NULL,_binary'AA',SUBSTRING(a,2147483646)))
       AS control_grouped
FROM source_data GROUP BY control_grouped;
SELECT HEX(IF(a IS NOT NULL,_binary'AA',SUBSTRING(a,2147483647)))
       AS trigger_grouped
FROM source_data GROUP BY trigger_grouped;

CREATE VIEW control_view AS
SELECT HEX(IF(a IS NOT NULL,_binary'AA',SUBSTRING(a,2147483646))) AS h
FROM source_data;
CREATE VIEW trigger_view AS
SELECT HEX(IF(a IS NOT NULL,_binary'AA',SUBSTRING(a,2147483647))) AS h
FROM source_data;
SELECT TABLE_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH
FROM information_schema.columns
WHERE TABLE_SCHEMA='h54' AND TABLE_NAME IN ('control_view','trigger_view')
ORDER BY TABLE_NAME;
[19 Aug 8:22] Chaithra Marsur Gopala Reddy
Hi xingwang Verdant,

Thank you for the test case. Verified as described.