Skip to content

Commit ff06148

Browse files
committed
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.
1 parent 605aa82 commit ff06148

File tree

3 files changed

+4
-4
lines changed

3 files changed

+4
-4
lines changed

include/m_ctype.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,13 +372,13 @@ my_cs_have_contractions(CHARSET_INFO *cs)
372372
static inline my_bool
373373
my_cs_can_be_contraction_head(CHARSET_INFO *cs, my_wc_t wc)
374374
{
375-
return ((const char *)cs->contractions)[0x40*0x40 + (wc & 0xFF)];
375+
return ((const char *) cs->contractions)[0x40 * 0x40 * 2 + (wc & 0xFF)];
376376
}
377377

378378
static inline my_bool
379379
my_cs_can_be_contraction_tail(CHARSET_INFO *cs, my_wc_t wc)
380380
{
381-
return ((const char *)cs->contractions)[0x40*0x40 + (wc & 0xFF)];
381+
return ((const char *) cs->contractions)[0x40 * 0x40 * 2 + (wc & 0xFF)];
382382
}
383383

384384
static inline uint16*

strings/ctype-mb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ my_bool my_like_range_mb(CHARSET_INFO *cs,
697697
char *max_end= max_str + res_length;
698698
size_t maxcharlen= res_length / cs->mbmaxlen;
699699
const char *contraction_flags= cs->contractions ?
700-
((const char*) cs->contractions) + 0x40*0x40 : NULL;
700+
(const char *) (cs->contractions + 0x40*0x40) : NULL;
701701

702702
for (; ptr != end && min_str != min_end && maxcharlen ; maxcharlen--)
703703
{

strings/ctype-uca.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8046,7 +8046,7 @@ static my_bool create_tailoring(CHARSET_INFO *cs, void *(*alloc)(size_t))
80468046
if (!(cs->contractions= (uint16*) (*alloc)(size)))
80478047
return 1;
80488048
bzero((void*)cs->contractions, size);
8049-
contraction_flags= ((char*) cs->contractions) + 0x40*0x40;
8049+
contraction_flags= (char *) (cs->contractions + 0x40*0x40);
80508050
for (i=0; i < rc; i++)
80518051
{
80528052
if (rule[i].curr[1])

0 commit comments

Comments
 (0)