@@ -120,6 +120,47 @@ static void report_conversion_error(const CHARSET_INFO *to_cs, const char *from,
120120           to_name);
121121}
122122
123+ /* *
124+   Convert and/or validate input_string according to charset 'to_cs'. 
125+ 
126+   If input_string needs conversion to 'to_cs' then do the conversion, 
127+   and verify the result. 
128+   Otherwise, if input_string has charset my_charset_bin, then verify 
129+   that it contains a valid string according to 'to_cs'. 
130+ 
131+   Will call my_error() in case conversion/validation fails. 
132+ 
133+   @param input_string        string to be converted/validated. 
134+   @param to_cs               result character set 
135+   @param output_string [out] output result variable 
136+ 
137+   @return nullptr in case of error, otherwise pointer to result. 
138+  */  
139+ static  String *convert_or_validate_string (String *input_string,
140+                                           const  CHARSET_INFO *to_cs,
141+                                           String *output_string) {
142+   String *retval = input_string;
143+   if  (input_string->needs_conversion (to_cs)) {
144+     uint errors = 0 ;
145+     output_string->copy (input_string->ptr (), input_string->length (),
146+                         input_string->charset (), to_cs, &errors);
147+     if  (errors) {
148+       report_conversion_error (to_cs, input_string->ptr (),
149+                               input_string->length (), input_string->charset ());
150+       return  nullptr ;
151+     }
152+     retval = output_string;
153+   } else  if  (to_cs != &my_charset_bin &&
154+              input_string->charset () == &my_charset_bin) {
155+     if  (!input_string->is_valid_string (to_cs)) {
156+       report_conversion_error (to_cs, input_string->ptr (),
157+                               input_string->length (), input_string->charset ());
158+       return  nullptr ;
159+     }
160+   }
161+   return  retval;
162+ }
163+ 
123164/* 
124165  For the Items which have only val_str_ascii() method 
125166  and don't have their own "native" val_str(), 
@@ -1127,33 +1168,14 @@ String *Item_func_replace::val_str(String *str) {
11271168  tmp_value_res.set_charset (collation.collation );
11281169  String *result = &tmp_value_res;
11291170
1130-   char  res2_buff[STRING_BUFFER_USUAL_SIZE];
1131-   String res2_converted (res2_buff, sizeof (res2_buff), nullptr );
1132-   char  res3_buff[STRING_BUFFER_USUAL_SIZE];
1133-   String res3_converted (res3_buff, sizeof (res3_buff), nullptr );
1134-   uint errors = 0 ;
1171+   StringBuffer<STRING_BUFFER_USUAL_SIZE> res2_converted (nullptr );
1172+   StringBuffer<STRING_BUFFER_USUAL_SIZE> res3_converted (nullptr );
11351173
1136-   if  (res2->needs_conversion (collation.collation )) {
1137-     res2_converted.copy (res2->ptr (), res2->length (), res2->charset (),
1138-                         collation.collation , &errors);
1139-     if  (errors) {
1140-       report_conversion_error (collation.collation , res2->ptr (), res2->length (),
1141-                               res2->charset ());
1142-       return  error_str ();
1143-     }
1144-     res2 = &res2_converted;
1145-   }
1174+   res2 = convert_or_validate_string (res2, collation.collation , &res2_converted);
1175+   if  (res2 == nullptr ) return  error_str ();
11461176
1147-   if  (res3->needs_conversion (collation.collation )) {
1148-     res3_converted.copy (res3->ptr (), res3->length (), res3->charset (),
1149-                         collation.collation , &errors);
1150-     if  (errors) {
1151-       report_conversion_error (collation.collation , res3->ptr (), res3->length (),
1152-                               res3->charset ());
1153-       return  error_str ();
1154-     }
1155-     res3 = &res3_converted;
1156-   }
1177+   res3 = convert_or_validate_string (res3, collation.collation , &res3_converted);
1178+   if  (res3 == nullptr ) return  error_str ();
11571179
11581180  THD *thd = current_thd;
11591181  const  unsigned  long  max_size = thd->variables .max_allowed_packet ;
@@ -1520,21 +1542,11 @@ String *Item_func_substr_index::val_str(String *str) {
15201542
15211543  res->set_charset (collation.collation );
15221544
1523-   char  delimiter_buff[STRING_BUFFER_USUAL_SIZE];
1524-   String delimiter_converted (delimiter_buff, sizeof (delimiter_buff), nullptr );
1525-   uint errors = 0 ;
1526-   if  (delimiter->needs_conversion (collation.collation )) {
1527-     delimiter_converted.copy (delimiter->ptr (), delimiter->length (),
1528-                              delimiter->charset (), collation.collation ,
1529-                              &errors);
1530-     if  (errors) {
1531-       report_conversion_error (collation.collation , delimiter->ptr (),
1532-                               delimiter->length (), delimiter->charset ());
1533-       return  error_str ();
1534-     }
1535-     delimiter = &delimiter_converted;
1536-     delimiter_length = delimiter->length ();
1537-   }
1545+   StringBuffer<STRING_BUFFER_USUAL_SIZE> delimiter_converted (nullptr );
1546+   delimiter = convert_or_validate_string (delimiter, collation.collation ,
1547+                                          &delimiter_converted);
1548+   if  (delimiter == nullptr ) return  error_str ();
1549+   delimiter_length = delimiter->length ();
15381550
15391551  Integer_value count_val (count, args[2 ]->unsigned_flag );
15401552
@@ -1636,26 +1648,16 @@ String *Item_func_trim::val_str(String *str) {
16361648
16371649  char  buff[MAX_FIELD_WIDTH];
16381650  String tmp (buff, sizeof (buff), system_charset_info);
1639-   const   String *remove_str = &remove;  //  Default value.
1651+   String *remove_str = &remove;  //  Default value.
16401652
1641-   char  remove_buff[STRING_BUFFER_USUAL_SIZE];
1642-   String remove_converted (remove_buff, sizeof (remove_buff), nullptr );
1643-   uint errors = 0 ;
1653+   StringBuffer<STRING_BUFFER_USUAL_SIZE> remove_converted (nullptr );
16441654
16451655  if  (arg_count == 2 ) {
16461656    remove_str = args[1 ]->val_str (&tmp);
16471657    if  ((null_value = args[1 ]->null_value )) return  NULL ;
1648-     if  (remove_str->needs_conversion (collation.collation )) {
1649-       remove_converted.copy (remove_str->ptr (), remove_str->length (),
1650-                             remove_str->charset (), collation.collation ,
1651-                             &errors);
1652-       if  (errors) {
1653-         report_conversion_error (collation.collation , remove_str->ptr (),
1654-                                 remove_str->length (), remove_str->charset ());
1655-         return  error_str ();
1656-       }
1657-       remove_str = &remove_converted;
1658-     }
1658+     remove_str = convert_or_validate_string (remove_str, collation.collation ,
1659+                                             &remove_converted);
1660+     if  (remove_str == nullptr ) return  error_str ();
16591661  }
16601662
16611663  const  size_t  remove_length = remove_str->length ();
0 commit comments