diff options
author | unknown <gshchepa/uchum@gleb.loc> | 2007-10-26 21:26:06 +0500 |
---|---|---|
committer | unknown <gshchepa/uchum@gleb.loc> | 2007-10-26 21:26:06 +0500 |
commit | b9ecbb7e5c764158b81597b4197a926732c31004 (patch) | |
tree | c5fb7ca84eb605614b54e556b4845137df4d556a | |
parent | 6356f16196be6492f7b18cc06df53075a2b14203 (diff) | |
download | mariadb-git-b9ecbb7e5c764158b81597b4197a926732c31004.tar.gz |
Fixed bug #31036: Using order by with archive table crashes server.
1. Memory overrun have been fixed.
2. Server failure on assertion has been fixed.
storage/archive/azio.c:
Fixed bug #31036.
The ha_archive::rnd_pos function has been modified to take
into account the result of the azseek function and
to return HA_ERR_CRASHED_ON_USAGE in case of seek error.
storage/archive/ha_archive.cc:
Fixed bug #31036.
1. Memory overrun has been fixed: maximal sizes of azio_stream::inbuf
and azio_stream::outbuf was mixed.
2. Zero value of the output parameter of the azread function was
incorrectly interpreted by the azseek function: after the first
successful read attempt the execution of the azseek loop was
interrupted and negative value was returned.
(See ha_archive::rnd_pos: that negative value was silently ignored,
and an incomplete data was used, for example, as a size of a packed
record, and server failed with the assertion:
"row_len <= record_buffer->length".)
mysql-test/t/archive.test:
Added test case for bug #31036.
mysql-test/r/archive.result:
Added test case for bug #31036.
-rw-r--r-- | mysql-test/r/archive.result | 4 | ||||
-rw-r--r-- | mysql-test/t/archive.test | 22 | ||||
-rw-r--r-- | storage/archive/azio.c | 10 | ||||
-rw-r--r-- | storage/archive/ha_archive.cc | 4 |
4 files changed, 33 insertions, 7 deletions
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index 36b013703d8..803c102f6cf 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12682,3 +12682,7 @@ check table t1 extended; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; +CREATE TABLE t1(a VARCHAR(510)) ENGINE = ARCHIVE; +INSERT INTO t1(a) VALUES (''); +SELECT * FROM t1 ORDER BY a; +DROP TABLE t1; diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 23c591856a7..a8567ab9fd0 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1559,3 +1559,25 @@ insert into t1 set a=''; insert into t1 set a='a'; check table t1 extended; drop table t1; + +# +# BUG#31036 - Using order by with archive table crashes server +# + +CREATE TABLE t1(a VARCHAR(510)) ENGINE = ARCHIVE; + +let $bug31036=41; +--disable_query_log +while($bug31036) +{ + INSERT INTO t1(a) VALUES (REPEAT('a', 510)); + dec $bug31036; +} +--enable_query_log +INSERT INTO t1(a) VALUES (''); + +--disable_result_log +SELECT * FROM t1 ORDER BY a; +--enable_result_log + +DROP TABLE t1; diff --git a/storage/archive/azio.c b/storage/archive/azio.c index f6b1a6e733f..b5c3dd465af 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -681,8 +681,8 @@ my_off_t azseek (s, offset, whence) /* There was a zmemzero here if inbuf was null -Brian */ while (offset > 0) { - uInt size = AZ_BUFSIZE_WRITE; - if (offset < AZ_BUFSIZE_WRITE) size = (uInt)offset; + uInt size = AZ_BUFSIZE_READ; + if (offset < AZ_BUFSIZE_READ) size = (uInt)offset; size = azwrite(s, s->inbuf, size); if (size == 0) return -1L; @@ -725,11 +725,11 @@ my_off_t azseek (s, offset, whence) } while (offset > 0) { int error; - unsigned int size = AZ_BUFSIZE_READ; - if (offset < AZ_BUFSIZE_READ) size = (int)offset; + unsigned int size = AZ_BUFSIZE_WRITE; + if (offset < AZ_BUFSIZE_WRITE) size = (int)offset; size = azread(s, s->outbuf, size, &error); - if (error <= 0) return -1L; + if (error < 0) return -1L; offset -= size; } return s->out; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 6696eac2fbb..3015ae78761 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1241,8 +1241,8 @@ int ha_archive::rnd_pos(uchar * buf, uchar *pos) DBUG_ENTER("ha_archive::rnd_pos"); ha_statistic_increment(&SSV::ha_read_rnd_next_count); current_position= (my_off_t)my_get_ptr(pos, ref_length); - (void)azseek(&archive, current_position, SEEK_SET); - + if (azseek(&archive, current_position, SEEK_SET) < 0) + DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); DBUG_RETURN(get_row(&archive, buf)); } |