diff options
-rw-r--r-- | mysql-test/main/xa.result | 7 | ||||
-rw-r--r-- | mysql-test/main/xa.test | 16 | ||||
-rw-r--r-- | sql/handler.h | 8 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 |
4 files changed, 31 insertions, 2 deletions
diff --git a/mysql-test/main/xa.result b/mysql-test/main/xa.result index 030415a5320..bd2946247d8 100644 --- a/mysql-test/main/xa.result +++ b/mysql-test/main/xa.result @@ -1,4 +1,11 @@ call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction"); +XA START 'btw_may_not_be_empty','', 4294967295; +ERROR XAE05: XAER_INVAL: Invalid arguments (or unsupported command) +XA START 'btw_may_not_be_empty','', 4294967293; +ERROR XAE05: XAER_INVAL: Invalid arguments (or unsupported command) +XA START 'btw_may_not_be_empty','', 4294967292; +XA END 'btw_may_not_be_empty','', 4294967292; +XA ROLLBACK 'btw_may_not_be_empty','', 4294967292; drop table if exists t1, t2; create table t1 (a int) engine=innodb; xa start 'test1'; diff --git a/mysql-test/main/xa.test b/mysql-test/main/xa.test index 41c1f5a8859..55c41452635 100644 --- a/mysql-test/main/xa.test +++ b/mysql-test/main/xa.test @@ -10,6 +10,22 @@ call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction"); +# Range of valid formatID of XID's [ gtrid, bqual [ , formatID ] ] +# is constrained to max(uint32) - 3. +# and -1 is an invalid value. + +--let $max_uint32 = `SELECT (1 << 32) - 1` +--let $max_id = `SELECT $max_uint32 - 3` +--let $max_plus_1 = `SELECT $max_id + 1` + +--error ER_XAER_INVAL +--eval XA START 'btw_may_not_be_empty','', $max_uint32 +--error ER_XAER_INVAL +--eval XA START 'btw_may_not_be_empty','', $max_plus_1 +--eval XA START 'btw_may_not_be_empty','', $max_id +--eval XA END 'btw_may_not_be_empty','', $max_id +--eval XA ROLLBACK 'btw_may_not_be_empty','', $max_id + --disable_warnings drop table if exists t1, t2; --enable_warnings diff --git a/sql/handler.h b/sql/handler.h index 0a561ec8b3f..92c2a61ed0e 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -829,6 +829,10 @@ typedef ulonglong my_xid; // this line is the same as in log_event.h @see MYSQL_XID in mysql/plugin.h */ struct xid_t { + static const uint32 INVALID_format_id= UINT32_MAX; + // Two more values reserved for Todo: MDEV-21777 + static const uint32 MAX_format_id= UINT32_MAX - 3; + long formatID; long gtrid_length; long bqual_length; @@ -864,8 +868,8 @@ struct xid_t { bqual_length= b; memcpy(data, d, g+b); } - bool is_null() const { return formatID == -1; } - void null() { formatID= -1; } + bool is_null() const { return formatID == INVALID_format_id; } + void null() { formatID= INVALID_format_id; } my_xid quick_get_my_xid() { my_xid tmp; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f24da3ed412..4c714902175 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -17542,6 +17542,8 @@ xid: MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE); if (unlikely(!(Lex->xid=(XID *)thd->alloc(sizeof(XID))))) MYSQL_YYABORT; + if ($5 > XID::MAX_format_id) + my_yyabort_error((ER_XAER_INVAL, MYF(0), "")); Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length()); } ; |