summaryrefslogtreecommitdiff
path: root/strings
diff options
context:
space:
mode:
authorVenkata Sidagam <venkata.sidagam@oracle.com>2014-01-11 14:48:29 +0530
committerVenkata Sidagam <venkata.sidagam@oracle.com>2014-01-11 14:48:29 +0530
commitff6b117c364698c50b177e62475a8bebf92d4980 (patch)
treefd328e1f871c0e19b59c610a4dc0c95d58da265a /strings
parent8765bec5a2a17a8a0c7ce30fff7c9cdf67df3bd7 (diff)
downloadmariadb-git-ff6b117c364698c50b177e62475a8bebf92d4980.tar.gz
Bug #17760379 COLLATIONS WITH CONTRACTIONS BUFFER-OVERFLOW THEMSELVES IN THE FOOT
Description: A typo in create_tailoring() causes the "contraction_flags" to be written into cs->contractions in the wrong place. This causes two problems: (1) Anyone relying on `contraction_flags` to decide "could this character be part of a contraction" is 100% broken. (2) Anyone relying on `contractions` to determine the weight of a contraction is mostly broken Analysis: When we are preparing the contraction in create_tailoring(), we are corrupting the cs->contractions memory location which is supposed to store the weights(8k) + contraction information(256 bytes). We started storing the contraction information after the 4k location. This is because of logic flaw in the code. Fix: When we create the contractions, we need to calculate the contraction with (char*) (cs->contractions + 0x40*0x40) from ((char*) cs->contractions) + 0x40*0x40. This makes the "cs->contractions" to move to 8k bytes and stores the contraction information from there. Similarly when we are calculating it for like range queries we need to calculate it from the 8k bytes onwards, this can be done by changing the logic to (const char*) (cs->contractions + 0x40*0x40). And for ucs2 charsets we need to modify the my_cs_can_be_contraction_head() and my_cs_can_be_contraction_tail() to point to 8k+ locations.
Diffstat (limited to 'strings')
-rw-r--r--strings/ctype-mb.c2
-rw-r--r--strings/ctype-uca.c2
2 files changed, 2 insertions, 2 deletions
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index fddb8d2a16b..258613d3b05 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -697,7 +697,7 @@ my_bool my_like_range_mb(CHARSET_INFO *cs,
char *max_end= max_str + res_length;
size_t maxcharlen= res_length / cs->mbmaxlen;
const char *contraction_flags= cs->contractions ?
- ((const char*) cs->contractions) + 0x40*0x40 : NULL;
+ (const char *) (cs->contractions + 0x40*0x40) : NULL;
for (; ptr != end && min_str != min_end && maxcharlen ; maxcharlen--)
{
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index 8cd850b06df..7ec2e9851e1 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -8046,7 +8046,7 @@ static my_bool create_tailoring(CHARSET_INFO *cs, void *(*alloc)(size_t))
if (!(cs->contractions= (uint16*) (*alloc)(size)))
return 1;
bzero((void*)cs->contractions, size);
- contraction_flags= ((char*) cs->contractions) + 0x40*0x40;
+ contraction_flags= (char *) (cs->contractions + 0x40*0x40);
for (i=0; i < rc; i++)
{
if (rule[i].curr[1])