summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Kosov <claprix@yandex.ru>2020-03-11 16:40:34 +0300
committerEugene Kosov <claprix@yandex.ru>2020-03-11 18:02:12 +0300
commit7f36300df56da317a46aff1f58b6cdc0e5727cf6 (patch)
tree4123fada3b9752865cd0f5ae8d9ccee3ff2a331f
parentdf88e7cefaa7dcffdc52359b73a1087e8569e000 (diff)
downloadmariadb-git-7f36300df56da317a46aff1f58b6cdc0e5727cf6.tar.gz
MDEV-21918 improve page_zip_verify_checksum()
actually, page_zip_verify_checksum() generally allows all-zeroes checksums because our CRC32 checksum is something like crc_1 ^ crc_2 ^ crc_3 Also, all zeroes page is considered correct. As a side effect fix nasty reinterpret_cast<> UB Also, since c0f47a4a5842 innodb_checksum_algorithm=full_crc32 exists which computes CRC32 in one go (without bitwise arithmetic)
-rw-r--r--storage/innobase/page/page0zip.cc37
-rw-r--r--storage/xtradb/page/page0zip.cc37
2 files changed, 30 insertions, 44 deletions
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index 1b0fcea326a..6f1c19799b5 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -4918,35 +4918,28 @@ page_zip_verify_checksum(
ib_uint32_t crc32 = 0 /* silence bogus warning */;
ib_uint32_t innodb = 0 /* silence bogus warning */;
- stored = static_cast<ib_uint32_t>(mach_read_from_4(
- static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
+ const srv_checksum_algorithm_t curr_algo =
+ static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
-#if FIL_PAGE_LSN % 8
-#error "FIL_PAGE_LSN must be 64 bit aligned"
-#endif
+ if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
+ return true;
+ }
- /* Check if page is empty */
- if (stored == 0
- && *reinterpret_cast<const ib_uint64_t*>(static_cast<const char*>(
- data)
- + FIL_PAGE_LSN) == 0) {
- /* make sure that the page is really empty */
- for (ulint i = 0; i < size; i++) {
- if (*((const char*) data + i) != 0) {
- return(FALSE);
- }
+ bool all_zeroes = true;
+ for (size_t i = 0; i < size; i++) {
+ if (static_cast<const byte*>(data)[i] != 0) {
+ all_zeroes = false;
+ break;
}
- /* Empty page */
- return(TRUE);
}
- const srv_checksum_algorithm_t curr_algo =
- static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
-
- if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
- return(TRUE);
+ if (all_zeroes) {
+ return true;
}
+ stored = static_cast<ib_uint32_t>(mach_read_from_4(
+ static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
+
calc = static_cast<ib_uint32_t>(page_zip_calc_checksum(
data, size, curr_algo));
diff --git a/storage/xtradb/page/page0zip.cc b/storage/xtradb/page/page0zip.cc
index 0c7f9b6feff..d85594c5ce3 100644
--- a/storage/xtradb/page/page0zip.cc
+++ b/storage/xtradb/page/page0zip.cc
@@ -4927,35 +4927,28 @@ page_zip_verify_checksum(
ib_uint32_t crc32 = 0 /* silence bogus warning */;
ib_uint32_t innodb = 0 /* silence bogus warning */;
- stored = static_cast<ib_uint32_t>(mach_read_from_4(
- static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
+ const srv_checksum_algorithm_t curr_algo =
+ static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
-#if FIL_PAGE_LSN % 8
-#error "FIL_PAGE_LSN must be 64 bit aligned"
-#endif
+ if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
+ return true;
+ }
- /* Check if page is empty */
- if (stored == 0
- && *reinterpret_cast<const ib_uint64_t*>(static_cast<const char*>(
- data)
- + FIL_PAGE_LSN) == 0) {
- /* make sure that the page is really empty */
- for (ulint i = 0; i < size; i++) {
- if (*((const char*) data + i) != 0) {
- return(FALSE);
- }
+ bool all_zeroes = true;
+ for (size_t i = 0; i < size; i++) {
+ if (static_cast<const byte*>(data)[i] != 0) {
+ all_zeroes = false;
+ break;
}
- /* Empty page */
- return(TRUE);
}
- const srv_checksum_algorithm_t curr_algo =
- static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
-
- if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
- return(TRUE);
+ if (all_zeroes) {
+ return true;
}
+ stored = static_cast<ib_uint32_t>(mach_read_from_4(
+ static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
+
calc = static_cast<ib_uint32_t>(page_zip_calc_checksum(
data, size, curr_algo));