Commit 6083ae52 authored by Yasufumi Kinoshita's avatar Yasufumi Kinoshita

Bug #16089381 : POSSIBLE NUMBER UNDERFLOW AROUND CALLING PAGE_ZIP_EMPTY_SIZE()

some callers for page_zip_empty_size() ignored possibility its returning 0, and could cause underflow.

rb#1837 approved by Marko
parent f130ccc1
/*****************************************************************************
Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
......@@ -1146,27 +1146,13 @@ btr_cur_optimistic_insert(
Subtract one byte for the encoded heap_no in the
modification log. */
ulint free_space_zip = page_zip_empty_size(
cursor->index->n_fields, zip_size) - 1;
cursor->index->n_fields, zip_size);
ulint n_uniq = dict_index_get_n_unique_in_tree(index);
ut_ad(dict_table_is_comp(index->table));
/* There should be enough room for two node pointer
records on an empty non-leaf page. This prevents
infinite page splits. */
if (UNIV_LIKELY(entry->n_fields >= n_uniq)
&& UNIV_UNLIKELY(REC_NODE_PTR_SIZE
+ rec_get_converted_size_comp_prefix(
index, entry->fields, n_uniq,
NULL)
/* On a compressed page, there is
a two-byte entry in the dense
page directory for every record.
But there is no record header. */
- (REC_N_NEW_EXTRA_BYTES - 2)
> free_space_zip / 2)) {
if (free_space_zip == 0) {
too_big:
if (big_rec_vec) {
dtuple_convert_back_big_rec(
index, entry, big_rec_vec);
......@@ -1174,6 +1160,27 @@ btr_cur_optimistic_insert(
return(DB_TOO_BIG_RECORD);
}
/* Subtract one byte for the encoded heap_no in the
modification log. */
free_space_zip--;
/* There should be enough room for two node pointer
records on an empty non-leaf page. This prevents
infinite page splits. */
if (entry->n_fields >= n_uniq
&& (REC_NODE_PTR_SIZE
+ rec_get_converted_size_comp_prefix(
index, entry->fields, n_uniq, NULL)
/* On a compressed page, there is
a two-byte entry in the dense
page directory for every record.
But there is no record header. */
- (REC_N_NEW_EXTRA_BYTES - 2)
> free_space_zip / 2)) {
goto too_big;
}
}
LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page),
......
/*****************************************************************************
Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -1415,6 +1415,10 @@ dict_index_too_big_for_tree(
/* maximum allowed size of a node pointer record */
ulint page_ptr_max;
DBUG_EXECUTE_IF(
"ib_force_create_table",
return(FALSE););
comp = dict_table_is_comp(table);
zip_size = dict_table_zip_size(table);
......@@ -1429,7 +1433,10 @@ dict_index_too_big_for_tree(
number in the page modification log. The maximum
allowed node pointer size is half that. */
page_rec_max = page_zip_empty_size(new_index->n_fields,
zip_size) - 1;
zip_size);
if (page_rec_max) {
page_rec_max--;
}
page_ptr_max = page_rec_max / 2;
/* On a compressed page, there is a two-byte entry in
the dense page directory for every record. But there
......
/*****************************************************************************
Copyright (c) 2005, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 2005, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -188,8 +188,8 @@ page_zip_rec_needs_ext(
one record on an empty leaf page. Subtract 1 byte for
the encoded heap number. Check also the available space
on the uncompressed page. */
return(rec_size - (REC_N_NEW_EXTRA_BYTES - 2)
>= (page_zip_empty_size(n_fields, zip_size) - 1)
return(rec_size - (REC_N_NEW_EXTRA_BYTES - 2 - 1)
>= page_zip_empty_size(n_fields, zip_size)
|| rec_size >= page_get_free_space_of_empty(TRUE) / 2);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment