~ubuntu-branches/ubuntu/lucid/mysql-dfsg-5.1/lucid-security

« back to all changes in this revision

Viewing changes to sql/item_strfunc.cc

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 22:33:55 UTC
  • mto: (1.2.1) (37.1.1 lucid-security)
  • mto: This revision was merged to the branch mainline in revision 36.
  • Revision ID: package-import@ubuntu.com-20120222223355-ku1tb4r70osci6v2
Tags: upstream-5.1.61
ImportĀ upstreamĀ versionĀ 5.1.61

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2006 MySQL AB
 
1
/*
 
2
   Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
2
3
 
3
4
   This program is free software; you can redistribute it and/or modify
4
5
   it under the terms of the GNU General Public License as published by
11
12
 
12
13
   You should have received a copy of the GNU General Public License
13
14
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
 
 
 
15
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
 
16
*/
16
17
 
17
18
/**
18
19
  @file
39
40
#include "../mysys/my_static.h"                 // For soundex_map
40
41
C_MODE_END
41
42
 
 
43
/**
 
44
   @todo Remove this. It is not safe to use a shared String object.
 
45
 */
42
46
String my_empty_string("",default_charset_info);
43
47
 
44
48
 
 
49
/*
 
50
  Convert an array of bytes to a hexadecimal representation.
 
51
 
 
52
  Used to generate a hexadecimal representation of a message digest.
 
53
*/
 
54
static void array_to_hex(char *to, const char *str, uint len)
 
55
{
 
56
  const char *str_end= str + len;
 
57
  for (; str != str_end; ++str)
 
58
  {
 
59
    *to++= _dig_vec_lower[((uchar) *str) >> 4];
 
60
    *to++= _dig_vec_lower[((uchar) *str) & 0x0F];
 
61
  }
 
62
}
45
63
 
46
64
 
47
65
bool Item_str_func::fix_fields(THD *thd, Item **ref)
114
132
      null_value=1;
115
133
      return 0;
116
134
    }
117
 
    sprintf((char *) str->ptr(),
118
 
            "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
119
 
            digest[0], digest[1], digest[2], digest[3],
120
 
            digest[4], digest[5], digest[6], digest[7],
121
 
            digest[8], digest[9], digest[10], digest[11],
122
 
            digest[12], digest[13], digest[14], digest[15]);
 
135
    array_to_hex((char *) str->ptr(), (const char*) digest, 16);
123
136
    str->length((uint) 32);
124
137
    return str;
125
138
  }
160
173
    if (!( str->alloc(SHA1_HASH_SIZE*2) ||
161
174
           (mysql_sha1_result(&context,digest))))
162
175
    {
163
 
      sprintf((char *) str->ptr(),
164
 
      "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\
165
 
%02x%02x%02x%02x%02x%02x%02x%02x",
166
 
           digest[0], digest[1], digest[2], digest[3],
167
 
           digest[4], digest[5], digest[6], digest[7],
168
 
           digest[8], digest[9], digest[10], digest[11],
169
 
           digest[12], digest[13], digest[14], digest[15],
170
 
           digest[16], digest[17], digest[18], digest[19]);
171
 
 
 
176
      array_to_hex((char *) str->ptr(), (const char*) digest, SHA1_HASH_SIZE);
172
177
      str->length((uint)  SHA1_HASH_SIZE*2);
173
178
      null_value=0;
174
179
      return str;
323
328
      }
324
329
      else if (str->alloced_length() >= res->length()+res2->length())
325
330
      {
326
 
        if (str == res2)
 
331
        if (str->ptr() == res2->ptr())
327
332
          str->replace(0,0,*res);
328
333
        else
329
334
        {
460
465
  if ((null_value= args[0]->null_value))
461
466
    return 0;                                   // ENCRYPT(NULL) == NULL
462
467
  if ((res_length=res->length()) == 0)
463
 
    return &my_empty_string;
 
468
    return make_empty_result();
464
469
 
465
470
  if (arg_count == 1)
466
471
  {
515
520
  tmp_arg[res_length-1]=tail;                   // save extra length
516
521
  tmp_value.realloc(res_length+1);
517
522
  tmp_value.length(res_length+1);
 
523
  tmp_value.set_charset(&my_charset_bin);
518
524
  tmp_value[0]=(char) (128 | key_number);
519
525
  // Real encryption
520
526
  bzero((char*) &ivec,sizeof(ivec));
602
608
  if ((tail=(uint) (uchar) tmp_value[length-2]) > 8)
603
609
    goto wrong_key;                                  // Wrong key
604
610
  tmp_value.length(length-1-tail);
 
611
  tmp_value.set_charset(&my_charset_bin);
605
612
  return &tmp_value;
606
613
 
607
614
error:
651
658
    }
652
659
 
653
660
  if (i ==  arg_count)
654
 
    return &my_empty_string;
 
661
    return make_empty_result();
655
662
 
656
663
  for (i++; i < arg_count ; i++)
657
664
  {
677
684
             res->length() + sep_str->length() + res2->length())
678
685
    {
679
686
      /* We have room in str;  We can't get any errors here */
680
 
      if (str == res2)
681
 
      {                                         // This is quote uncommon!
 
687
      if (str->ptr() == res2->ptr())
 
688
      {                                         // This is quite uncommon!
682
689
        str->replace(0,0,*sep_str);
683
690
        str->replace(0,0,*res);
684
691
      }
802
809
    return 0;
803
810
  /* An empty string is a special case as the string pointer may be null */
804
811
  if (!res->length())
805
 
    return &my_empty_string;
 
812
    return make_empty_result();
806
813
  if (tmp_value.alloced_length() < res->length() &&
807
814
      tmp_value.realloc(res->length()))
808
815
  {
903
910
    search=res2->ptr();
904
911
    search_end=search+from_length;
905
912
redo:
 
913
    DBUG_ASSERT(res->ptr() || !offset);
906
914
    ptr=res->ptr()+offset;
907
915
    strend=res->ptr()+res->length();
908
 
    end=strend-from_length+1;
 
916
    /*
 
917
      In some cases val_str() can return empty string
 
918
      with ptr() == NULL and length() == 0.
 
919
      Let's check strend to avoid overflow.
 
920
    */
 
921
    end= strend ? strend - from_length + 1 : NULL;
909
922
    while (ptr < end)
910
923
    {
911
924
        if (*ptr == *search)
1012
1025
  if ((length < 0) || (length > res->length()))
1013
1026
    length= res->length();
1014
1027
 
 
1028
  /*
 
1029
    There is one exception not handled (intentionaly) by the character set
 
1030
    aggregation code. If one string is strong side and is binary, and
 
1031
    another one is weak side and is a multi-byte character string,
 
1032
    then we need to operate on the second string in terms on bytes when
 
1033
    calling ::numchars() and ::charpos(), rather than in terms of characters.
 
1034
    Lets substitute its character set to binary.
 
1035
  */
 
1036
  if (collation.collation == &my_charset_bin)
 
1037
  {
 
1038
    res->set_charset(&my_charset_bin);
 
1039
    res2->set_charset(&my_charset_bin);
 
1040
  }
 
1041
 
1015
1042
  /* start and length are now sufficiently valid to pass to charpos function */
1016
1043
   start= res->charpos((int) start);
1017
1044
   length= res->charpos((int) length, (uint32) start);
1122
1149
 
1123
1150
  /* if "unsigned_flag" is set, we have a *huge* positive number. */
1124
1151
  if ((length <= 0) && (!args[1]->unsigned_flag))
1125
 
    return &my_empty_string;
1126
 
 
 
1152
    return make_empty_result();
1127
1153
  if ((res->length() <= (ulonglong) length) ||
1128
1154
      (res->length() <= (char_pos= res->charpos((int) length))))
1129
1155
    return res;
1166
1192
 
1167
1193
  /* if "unsigned_flag" is set, we have a *huge* positive number. */
1168
1194
  if ((length <= 0) && (!args[1]->unsigned_flag))
1169
 
    return &my_empty_string; /* purecov: inspected */
 
1195
    return make_empty_result(); /* purecov: inspected */
1170
1196
 
1171
1197
  if (res->length() <= (ulonglong) length)
1172
1198
    return res; /* purecov: inspected */
1205
1231
  /* Negative or zero length, will return empty string. */
1206
1232
  if ((arg_count == 3) && (length <= 0) && 
1207
1233
      (length == 0 || !args[2]->unsigned_flag))
1208
 
    return &my_empty_string;
 
1234
    return make_empty_result();
1209
1235
 
1210
1236
  /* Assumes that the maximum length of a String is < INT_MAX32. */
1211
1237
  /* Set here so that rest of code sees out-of-bound value as such. */
1216
1242
  /* Assumes that the maximum length of a String is < INT_MAX32. */
1217
1243
  if ((!args[1]->unsigned_flag && (start < INT_MIN32 || start > INT_MAX32)) ||
1218
1244
      (args[1]->unsigned_flag && ((ulonglong) start > INT_MAX32)))
1219
 
    return &my_empty_string;
 
1245
    return make_empty_result();
1220
1246
 
1221
1247
  start= ((start < 0) ? res->numchars() + start : start - 1);
1222
1248
  start= res->charpos((int) start);
1223
1249
  if ((start < 0) || ((uint) start + 1 > res->length()))
1224
 
    return &my_empty_string;
 
1250
    return make_empty_result();
1225
1251
 
1226
1252
  length= res->charpos((int) length, (uint32) start);
1227
1253
  tmp_length= res->length() - start;
1284
1310
  null_value=0;
1285
1311
  uint delimiter_length= delimiter->length();
1286
1312
  if (!res->length() || !delimiter_length || !count)
1287
 
    return &my_empty_string;            // Wrong parameters
 
1313
    return make_empty_result();         // Wrong parameters
1288
1314
 
1289
1315
  res->set_charset(collation.collation);
1290
1316
 
1633
1659
  if ((null_value=args[0]->null_value))
1634
1660
    return 0;
1635
1661
  if (res->length() == 0)
1636
 
    return &my_empty_string;
 
1662
    return make_empty_result();
1637
1663
  my_make_scrambled_password(tmp_value, res->ptr(), res->length());
1638
1664
  str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, res->charset());
1639
1665
  return str;
1657
1683
  if ((null_value=args[0]->null_value))
1658
1684
    return 0;
1659
1685
  if (res->length() == 0)
1660
 
    return &my_empty_string;
 
1686
    return make_empty_result();
1661
1687
  my_make_scrambled_password_323(tmp_value, res->ptr(), res->length());
1662
1688
  str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, res->charset());
1663
1689
  return str;
1685
1711
  if ((null_value=args[0]->null_value))
1686
1712
    return 0;
1687
1713
  if (res->length() == 0)
1688
 
    return &my_empty_string;
1689
 
 
 
1714
    return make_empty_result();
1690
1715
  if (arg_count == 1)
1691
1716
  {                                     // generate random salt
1692
1717
    time_t timestamp=current_thd->query_start();
1720
1745
#endif  /* HAVE_CRYPT */
1721
1746
}
1722
1747
 
 
1748
bool Item_func_encode::seed()
 
1749
{
 
1750
  char buf[80];
 
1751
  ulong rand_nr[2];
 
1752
  String *key, tmp(buf, sizeof(buf), system_charset_info);
 
1753
 
 
1754
  if (!(key= args[1]->val_str(&tmp)))
 
1755
    return TRUE;
 
1756
 
 
1757
  hash_password(rand_nr, key->ptr(), key->length());
 
1758
  sql_crypt.init(rand_nr);
 
1759
 
 
1760
  return FALSE;
 
1761
}
 
1762
 
1723
1763
void Item_func_encode::fix_length_and_dec()
1724
1764
{
1725
1765
  max_length=args[0]->max_length;
1726
1766
  maybe_null=args[0]->maybe_null || args[1]->maybe_null;
1727
1767
  collation.set(&my_charset_bin);
 
1768
  /* Precompute the seed state if the item is constant. */
 
1769
  seeded= args[1]->const_item() &&
 
1770
          (args[1]->result_type() == STRING_RESULT) && !seed();
1728
1771
}
1729
1772
 
1730
1773
String *Item_func_encode::val_str(String *str)
1731
1774
{
1732
1775
  String *res;
1733
 
  char pw_buff[80];
1734
 
  String tmp_pw_value(pw_buff, sizeof(pw_buff), system_charset_info);
1735
 
  String *password;
1736
1776
  DBUG_ASSERT(fixed == 1);
1737
1777
 
1738
1778
  if (!(res=args[0]->val_str(str)))
1739
1779
  {
1740
 
    null_value=1; /* purecov: inspected */
1741
 
    return 0; /* purecov: inspected */
 
1780
    null_value= 1;
 
1781
    return NULL;
1742
1782
  }
1743
1783
 
1744
 
  if (!(password=args[1]->val_str(& tmp_pw_value)))
 
1784
  if (!seeded && seed())
1745
1785
  {
1746
 
    null_value=1;
1747
 
    return 0;
 
1786
    null_value= 1;
 
1787
    return NULL;
1748
1788
  }
1749
1789
 
1750
 
  null_value=0;
1751
 
  res=copy_if_not_alloced(str,res,res->length());
1752
 
  SQL_CRYPT sql_crypt(password->ptr(), password->length());
1753
 
  sql_crypt.init();
 
1790
  null_value= 0;
 
1791
  res= copy_if_not_alloced(str, res, res->length());
 
1792
  crypto_transform(res);
 
1793
  sql_crypt.reinit();
 
1794
 
 
1795
  return res;
 
1796
}
 
1797
 
 
1798
void Item_func_encode::crypto_transform(String *res)
 
1799
{
1754
1800
  sql_crypt.encode((char*) res->ptr(),res->length());
1755
1801
  res->set_charset(&my_charset_bin);
1756
 
  return res;
1757
1802
}
1758
1803
 
1759
 
String *Item_func_decode::val_str(String *str)
 
1804
void Item_func_decode::crypto_transform(String *res)
1760
1805
{
1761
 
  String *res;
1762
 
  char pw_buff[80];
1763
 
  String tmp_pw_value(pw_buff, sizeof(pw_buff), system_charset_info);
1764
 
  String *password;
1765
 
  DBUG_ASSERT(fixed == 1);
1766
 
 
1767
 
  if (!(res=args[0]->val_str(str)))
1768
 
  {
1769
 
    null_value=1; /* purecov: inspected */
1770
 
    return 0; /* purecov: inspected */
1771
 
  }
1772
 
 
1773
 
  if (!(password=args[1]->val_str(& tmp_pw_value)))
1774
 
  {
1775
 
    null_value=1;
1776
 
    return 0;
1777
 
  }
1778
 
 
1779
 
  null_value=0;
1780
 
  res=copy_if_not_alloced(str,res,res->length());
1781
 
  SQL_CRYPT sql_crypt(password->ptr(), password->length());
1782
 
  sql_crypt.init();
1783
1806
  sql_crypt.decode((char*) res->ptr(),res->length());
1784
 
  return res;
1785
1807
}
1786
1808
 
1787
1809
 
1827
1849
 
1828
1850
 
1829
1851
/**
1830
 
  @todo
1831
 
  make USER() replicate properly (currently it is replicated to "")
 
1852
  @note USER() is replicated correctly if binlog_format=ROW or (as of
 
1853
  BUG#28086) binlog_format=MIXED, but is incorrectly replicated to ''
 
1854
  if binlog_format=STATEMENT.
1832
1855
*/
1833
1856
bool Item_func_user::init(const char *user, const char *host)
1834
1857
{
1948
1971
  for ( ; ; ) /* Skip pre-space */
1949
1972
  {
1950
1973
    if ((rc= cs->cset->mb_wc(cs, &wc, (uchar*) from, (uchar*) end)) <= 0)
1951
 
      return &my_empty_string; /* EOL or invalid byte sequence */
 
1974
      return make_empty_result(); /* EOL or invalid byte sequence */
1952
1975
    
1953
1976
    if (rc == 1 && cs->ctype)
1954
1977
    {
1973
1996
        {
1974
1997
          /* Extra safety - should not really happen */
1975
1998
          DBUG_ASSERT(false);
1976
 
          return &my_empty_string;
 
1999
          return make_empty_result();
1977
2000
        }
1978
2001
        to+= rc;
1979
2002
        break;
2270
2293
          else
2271
2294
          {
2272
2295
            if (tmp_str.copy(*res))             // Don't use 'str'
2273
 
              return &my_empty_string;
 
2296
              return make_empty_result();
2274
2297
            result= &tmp_str;
2275
2298
          }
2276
2299
        }
2280
2303
          {                                     // Copy data to tmp_str
2281
2304
            if (tmp_str.alloc(result->length()+res->length()+1) ||
2282
2305
                tmp_str.copy(*result))
2283
 
              return &my_empty_string;
 
2306
              return make_empty_result();
2284
2307
            result= &tmp_str;
2285
2308
          }
2286
2309
          if (tmp_str.append(STRING_WITH_LEN(","), &my_charset_bin) || tmp_str.append(*res))
2287
 
            return &my_empty_string;
 
2310
            return make_empty_result();
2288
2311
        }
2289
2312
      }
2290
2313
    }
2423
2446
  null_value= 0;
2424
2447
 
2425
2448
  if (count <= 0 && (count == 0 || !args[1]->unsigned_flag))
2426
 
    return &my_empty_string;
 
2449
    return make_empty_result();
2427
2450
 
2428
2451
  /* Assumes that the maximum length of a String is < INT_MAX32. */
2429
2452
  /* Bounds check on count:  If this is triggered, we will error. */
2515
2538
  /* Set here so that rest of code sees out-of-bound value as such. */
2516
2539
  if ((ulonglong) count > INT_MAX32)
2517
2540
    count= INT_MAX32;
 
2541
  /*
 
2542
    There is one exception not handled (intentionaly) by the character set
 
2543
    aggregation code. If one string is strong side and is binary, and
 
2544
    another one is weak side and is a multi-byte character string,
 
2545
    then we need to operate on the second string in terms on bytes when
 
2546
    calling ::numchars() and ::charpos(), rather than in terms of characters.
 
2547
    Lets substitute its character set to binary.
 
2548
  */
 
2549
  if (collation.collation == &my_charset_bin)
 
2550
  {
 
2551
    res->set_charset(&my_charset_bin);
 
2552
    rpad->set_charset(&my_charset_bin);
 
2553
  }
 
2554
 
2518
2555
  if (count <= (res_char_length= res->numchars()))
2519
2556
  {                                             // String to pad is big enough
2520
2557
    res->length(res->charpos((int) count));     // Shorten result if longer
2617
2654
  if ((ulonglong) count > INT_MAX32)
2618
2655
    count= INT_MAX32;
2619
2656
 
 
2657
  /*
 
2658
    There is one exception not handled (intentionaly) by the character set
 
2659
    aggregation code. If one string is strong side and is binary, and
 
2660
    another one is weak side and is a multi-byte character string,
 
2661
    then we need to operate on the second string in terms on bytes when
 
2662
    calling ::numchars() and ::charpos(), rather than in terms of characters.
 
2663
    Lets substitute its character set to binary.
 
2664
  */
 
2665
  if (collation.collation == &my_charset_bin)
 
2666
  {
 
2667
    res->set_charset(&my_charset_bin);
 
2668
    pad->set_charset(&my_charset_bin);
 
2669
  }
 
2670
 
2620
2671
  res_char_length= res->numchars();
2621
2672
 
2622
2673
  if (count <= res_char_length)
2703
2754
 
2704
2755
  ptr= longlong2str(dec, ans, to_base);
2705
2756
  if (str->copy(ans, (uint32) (ptr-ans), default_charset()))
2706
 
    return &my_empty_string;
 
2757
    return make_empty_result();
2707
2758
  return str;
2708
2759
}
2709
2760
 
2713
2764
  DBUG_ASSERT(fixed == 1);
2714
2765
  if (use_cached_value)
2715
2766
    return null_value ? 0 : &str_value;
2716
 
  /* 
2717
 
    Here we don't pass 'str' as a parameter to args[0]->val_str()
2718
 
    as 'str' may point to 'str_value' (e.g. see Item::save_in_field()),
2719
 
    which we use below to convert string. 
2720
 
    Use argument's 'str_value' instead.
2721
 
  */
2722
 
  String *arg= args[0]->val_str(&args[0]->str_value);
 
2767
  String *arg= args[0]->val_str(str);
2723
2768
  uint dummy_errors;
2724
2769
  if (!arg)
2725
2770
  {
2726
2771
    null_value=1;
2727
2772
    return 0;
2728
2773
  }
2729
 
  null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(),
 
2774
  null_value= tmp_value.copy(arg->ptr(), arg->length(), arg->charset(),
2730
2775
                             conv_charset, &dummy_errors);
2731
 
  return null_value ? 0 : check_well_formed_result(&str_value);
 
2776
  return null_value ? 0 : check_well_formed_result(&tmp_value);
2732
2777
}
2733
2778
 
2734
2779
void Item_func_conv_charset::fix_length_and_dec()
2870
2915
      return 0;
2871
2916
    ptr= longlong2str(dec,ans,16);
2872
2917
    if (str->copy(ans,(uint32) (ptr-ans),default_charset()))
2873
 
      return &my_empty_string;                  // End of memory
 
2918
      return make_empty_result();                       // End of memory
2874
2919
    return str;
2875
2920
  }
2876
2921
 
2960
3005
                   MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
2961
3006
 
2962
3007
  /* Read only allowed from within dir specified by secure_file_priv */
2963
 
  if (opt_secure_file_priv &&
2964
 
      strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
 
3008
  if (!is_secure_file_path(path))
2965
3009
    goto err;
2966
3010
 
2967
3011
  if (!my_stat(path, &stat_info, MYF(0)))
3095
3139
  if ((null_value= (args[0]->null_value || n > (ulonglong) LL(4294967295))))
3096
3140
    return 0;                                   // Null value
3097
3141
 
 
3142
  str->set_charset(collation.collation);
3098
3143
  str->length(0);
3099
3144
  int4store(buf,n);
3100
3145
 
3170
3215
  }
3171
3216
 
3172
3217
  arg_length= arg->length();
3173
 
  new_length= arg_length+2; /* for beginning and ending ' signs */
3174
3218
 
3175
 
  for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++)
3176
 
    new_length+= get_esc_bit(escmask, (uchar) *from);
 
3219
  if (collation.collation->mbmaxlen == 1)
 
3220
  {
 
3221
    new_length= arg_length + 2; /* for beginning and ending ' signs */
 
3222
    for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++)
 
3223
      new_length+= get_esc_bit(escmask, (uchar) *from);
 
3224
  }
 
3225
  else
 
3226
  {
 
3227
    new_length= (arg_length * 2) +  /* For string characters */
 
3228
                (2 * collation.collation->mbmaxlen); /* For quotes */
 
3229
  }
3177
3230
 
3178
3231
  if (tmp_value.alloc(new_length))
3179
3232
    goto null;
3180
3233
 
 
3234
  if (collation.collation->mbmaxlen > 1)
 
3235
  {
 
3236
    CHARSET_INFO *cs= collation.collation;
 
3237
    int mblen;
 
3238
    uchar *to_end;
 
3239
    to= (char*) tmp_value.ptr();
 
3240
    to_end= (uchar*) to + new_length;
 
3241
 
 
3242
    /* Put leading quote */
 
3243
    if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0)
 
3244
      goto null;
 
3245
    to+= mblen;
 
3246
 
 
3247
    for (start= (char*) arg->ptr(), end= start + arg_length; start < end; )
 
3248
    {
 
3249
      my_wc_t wc;
 
3250
      bool escape;
 
3251
      if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) start, (uchar*) end)) <= 0)
 
3252
        goto null;
 
3253
      start+= mblen;
 
3254
      switch (wc) {
 
3255
        case 0:      escape= 1; wc= '0'; break;
 
3256
        case '\032': escape= 1; wc= 'Z'; break;
 
3257
        case '\'':   escape= 1; break;
 
3258
        case '\\':   escape= 1; break;
 
3259
        default:     escape= 0; break;
 
3260
      }
 
3261
      if (escape)
 
3262
      {
 
3263
        if ((mblen= cs->cset->wc_mb(cs, '\\', (uchar*) to, to_end)) <= 0)
 
3264
          goto null;
 
3265
        to+= mblen;
 
3266
      }
 
3267
      if ((mblen= cs->cset->wc_mb(cs, wc, (uchar*) to, to_end)) <= 0)
 
3268
        goto null;
 
3269
      to+= mblen;
 
3270
    }
 
3271
 
 
3272
    /* Put trailing quote */
 
3273
    if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0)
 
3274
      goto null;
 
3275
    to+= mblen;
 
3276
    new_length= to - tmp_value.ptr();
 
3277
    goto ret;
 
3278
  }
 
3279
 
3181
3280
  /*
3182
3281
    We replace characters from the end to the beginning
3183
3282
  */
3209
3308
    }
3210
3309
  }
3211
3310
  *to= '\'';
 
3311
 
 
3312
ret:
3212
3313
  tmp_value.length(new_length);
3213
3314
  tmp_value.set_charset(collation.collation);
3214
3315
  null_value= 0;
3365
3466
    push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
3366
3467
                        ER_TOO_BIG_FOR_UNCOMPRESS,
3367
3468
                        ER(ER_TOO_BIG_FOR_UNCOMPRESS),
3368
 
                        current_thd->variables.max_allowed_packet);
 
3469
                        static_cast<int>(current_thd->variables.
 
3470
                                         max_allowed_packet));
3369
3471
    goto err;
3370
3472
  }
3371
3473
  if (buffer.realloc((uint32)new_size))