Skip to content

Commit 841dc07

Browse files
committed
MDEV-28386 UBSAN: runtime error: negation of -X cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself in my_strntoull_8bit on SELECT ... OCT
The code in my_strntoull_8bit() and my_strntoull_mb2_or_mb4() could hit undefinite behavior by negating of LONGLONG_MIN. Fixing the code to avoid this.
1 parent 0a5e4a0 commit 841dc07

File tree

6 files changed

+52
-2
lines changed

6 files changed

+52
-2
lines changed

mysql-test/main/ctype_ucs.result

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6540,5 +6540,14 @@ DROP VIEW v1;
65406540
DROP TABLE t1;
65416541
SET NAMES utf8mb3;
65426542
#
6543+
# MDEV-28386 UBSAN: runtime error: negation of -X cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself in my_strntoull_8bit on SELECT ... OCT
6544+
#
6545+
CREATE TABLE t1 (c TEXT CHARACTER SET ucs2);
6546+
INSERT INTO t1 VALUES ('-9223372036854775808.5');
6547+
SELECT OCT(c) FROM t1;
6548+
OCT(c)
6549+
1000000000000000000000
6550+
DROP TABLE t1;
6551+
#
65436552
# End of 10.5 tests
65446553
#

mysql-test/main/ctype_ucs.test

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,15 @@ DROP VIEW v1;
12171217
DROP TABLE t1;
12181218
SET NAMES utf8mb3;
12191219

1220+
--echo #
1221+
--echo # MDEV-28386 UBSAN: runtime error: negation of -X cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself in my_strntoull_8bit on SELECT ... OCT
1222+
--echo #
1223+
1224+
CREATE TABLE t1 (c TEXT CHARACTER SET ucs2);
1225+
INSERT INTO t1 VALUES ('-9223372036854775808.5');
1226+
SELECT OCT(c) FROM t1;
1227+
DROP TABLE t1;
1228+
12201229

12211230
--echo #
12221231
--echo # End of 10.5 tests

mysql-test/main/func_str.result

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5317,5 +5317,18 @@ SELECT SUBSTR(0,@a) FROM t;
53175317
SUBSTR(0,@a)
53185318
DROP TABLE t;
53195319
#
5320+
# MDEV-28386 UBSAN: runtime error: negation of -X cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself in my_strntoull_8bit on SELECT ... OCT
5321+
#
5322+
CREATE TABLE t1 (c BLOB);
5323+
INSERT INTO t1 VALUES ('-9223372036854775808.5');
5324+
SELECT OCT(c) FROM t1;
5325+
OCT(c)
5326+
1000000000000000000000
5327+
SELECT BIN(c) FROM t1;
5328+
BIN(c)
5329+
1000000000000000000000000000000000000000000000000000000000000000
5330+
DROP TABLE t1;
5331+
DO OCT(-9223372036854775808);
5332+
#
53205333
# End of 10.5 tests
53215334
#

mysql-test/main/func_str.test

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2358,6 +2358,19 @@ CREATE TABLE t (c1 INT,c2 CHAR);
23582358
SELECT SUBSTR(0,@a) FROM t;
23592359
DROP TABLE t;
23602360

2361+
--echo #
2362+
--echo # MDEV-28386 UBSAN: runtime error: negation of -X cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself in my_strntoull_8bit on SELECT ... OCT
2363+
--echo #
2364+
2365+
CREATE TABLE t1 (c BLOB);
2366+
INSERT INTO t1 VALUES ('-9223372036854775808.5');
2367+
SELECT OCT(c) FROM t1;
2368+
SELECT BIN(c) FROM t1;
2369+
DROP TABLE t1;
2370+
2371+
DO OCT(-9223372036854775808);
2372+
2373+
23612374
--echo #
23622375
--echo # End of 10.5 tests
23632376
--echo #

strings/ctype-simple.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,10 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
758758
return (~(ulonglong) 0);
759759
}
760760

761-
return (negative ? -((longlong) i) : (longlong) i);
761+
/* Avoid undefinite behavior - negation of LONGLONG_MIN */
762+
return negative && (longlong) i != LONGLONG_MIN ?
763+
-((longlong) i) :
764+
(longlong) i;
762765

763766
noconv:
764767
err[0]= EDOM;

strings/ctype-ucs2.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,10 @@ my_strntoull_mb2_or_mb4(CHARSET_INFO *cs,
616616
return (~(ulonglong) 0);
617617
}
618618

619-
return (negative ? -((longlong) res) : (longlong) res);
619+
/* Avoid undefinite behavior - negation of LONGLONG_MIN */
620+
return negative && (longlong) res != LONGLONG_MIN ?
621+
-((longlong) res) :
622+
(longlong) res;
620623
}
621624

622625

0 commit comments

Comments
 (0)