summaryrefslogtreecommitdiff
path: root/sql/spatial.h
diff options
context:
space:
mode:
authorGeorgi Kodinov <georgi.kodinov@oracle.com>2013-03-27 16:03:00 +0200
committerGeorgi Kodinov <georgi.kodinov@oracle.com>2013-03-27 16:03:00 +0200
commite7c48834ff1827df1a35e542d1682ec55f3fe46d (patch)
treeecf91f5f10d81b8c7b3e0375ef43fe684123cb76 /sql/spatial.h
parent84bd6fec76d6b93d189725b535979996f9c2cb00 (diff)
downloadmariadb-git-e7c48834ff1827df1a35e542d1682ec55f3fe46d.tar.gz
Bug #16451878: GEOMETRY QUERY CRASHES SERVER
The GIS WKB reader was checking for the presence of enough data by first multiplying the number read (where it could overflow) and only then comparing it to the number of bytes available. This can overflow and effectively turn off the check. Fixed by: 1. Introducing a new function that does division only so no overflow is possible. 2. Using the proper macros and parenthesizing them. 3. Doing an in-line division check in the only place where the boundary check is done over a data structure other than a dense points array.
Diffstat (limited to 'sql/spatial.h')
-rw-r--r--sql/spatial.h29
1 files changed, 26 insertions, 3 deletions
diff --git a/sql/spatial.h b/sql/spatial.h
index 80972421f83..075ae0ecc89 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 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
@@ -22,7 +22,7 @@
const uint SRID_SIZE= 4;
const uint SIZEOF_STORED_DOUBLE= 8;
-const uint POINT_DATA_SIZE= SIZEOF_STORED_DOUBLE*2;
+const uint POINT_DATA_SIZE= (SIZEOF_STORED_DOUBLE * 2);
const uint WKB_HEADER_SIZE= 1+4;
const uint32 GET_SIZE_ERROR= ((uint32) -1);
@@ -317,10 +317,33 @@ protected:
const char *get_mbr_for_points(MBR *mbr, const char *data, uint offset)
const;
- inline bool no_data(const char *cur_data, uint32 data_amount) const
+ /**
+ Check if there're enough data remaining as requested
+
+ @arg cur_data pointer to the position in the binary form
+ @arg data_amount number of points expected
+ @return true if not enough data
+ */
+ inline bool no_data(const char *cur_data, size_t data_amount) const
{
return (cur_data + data_amount > m_data_end);
}
+
+ /**
+ Check if there're enough points remaining as requested
+
+ Need to perform the calculation in logical units, since multiplication
+ can overflow the size data type.
+
+ @arg data pointer to the begining of the points array
+ @arg expected_points number of points expected
+ @return true if there are not enough points
+ */
+ inline bool not_enough_points(const char *data, uint32 expected_points) const
+ {
+ return (m_data_end < data ||
+ (expected_points > ((m_data_end - data) / POINT_DATA_SIZE)));
+ }
const char *m_data;
const char *m_data_end;
};