summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/xa.result7
-rw-r--r--mysql-test/main/xa.test16
-rw-r--r--sql/handler.h8
-rw-r--r--sql/sql_yacc.yy2
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());
}
;