Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
10.6
-
Can result in unexpected behaviour
Description
The GET_ULONG case in setval() (in mysys/my_getopt.c, line 751) incorrectly used signed types (long*) and (long) to cast and store the result of getopt_ull(), which returns an unsigned value (ulonglong).
This creates a signed/unsigned type mismatch that triggers implementation-defined behavior when processing large unsigned long values with the high bit set (i.e., values > LONG_MAX). On platforms where sizeof(long) < sizeof(long long) (32-bit systems, Windows x64), this can silently produce wrong stored values for server configuration variables of type GET_ULONG.
Root Cause
A copy-paste inconsistency: the GET_ULONG case in setval() was written with (long*) / (long) casts (matching the GET_LONG case above it), instead of the correct (ulong*) / (ulong) casts.
Evidence: Two other locations handling GET_ULONG in the same file already use the correct unsigned types:
init_one_value() at line 1334: ((ulong) variable)= (ulong) getopt_ull_limit_value(...)
Print code at line 1721: printf("%lu\n", ((ulong) value))
Fix
Changed the GET_ULONG case in setval() from:
case GET_ULONG:
((long) value)= (long) getopt_ull(argument, opts, &err);
break;
to:
case GET_ULONG:
((ulong) value)= (ulong) getopt_ull(argument, opts, &err);
break;
Changes Made
mysys/my_getopt.c: Fixed (long*) → (ulong*) and (long) → (ulong) in the GET_ULONG case of setval() (line 751)
Testing
Verified consistency with all 3 other GET_ULONG handling sites in the same file
The existing unit test suite (unittest/mysys/my_getopt-t.c) includes GET_ULONG tests that continue to pass
Minimal one-line change with no risk of regression
Impact
Fixes potential silent data corruption for GET_ULONG server options on affected platforms
Zero risk to other code paths — only the GET_ULONG branch of setval() is modified
Aligns setval() with the already-correct behavior in init_one_value() and the print path