size_t my_strcspn(const CHARSET_INFO *cs, const char *str, const char *str_end, const char *reject, size_t reject_length) { const char *ptr_str, *ptr_reject; const char *reject_end= reject + reject_length; uint mbl= 0; for (ptr_str= str; ptr_str < str_end; ptr_str+= mbl) { mbl= my_mbcharlen_ptr(cs, ptr_str, str_end); if (mbl == 0) return 0; if (mbl == 1) { for (ptr_reject= reject; ptr_reject < reject_end; ++ptr_reject) { if (*ptr_reject == *ptr_str) return (size_t) (ptr_str - str); } } } return (size_t) (ptr_str - str); }
char *my_strchr(const CHARSET_INFO *cs, const char *str, const char *end, pchar c) { while (str < end) { uint mbl= my_mbcharlen_ptr(cs, str, end); if (mbl == 0) return NULL; if (mbl == 1) { if (*str == c) return((char *)str); str++; } else str+= mbl; } return(0); }
static char *backtick_string(const CHARSET_INFO *cs, char *to, char *end, char *par, size_t par_len, char quote_char) { uint char_len; char *start= to; char *par_end= par + par_len; size_t buff_length= (size_t) (end - to); if (buff_length <= par_len) goto err; *start++= quote_char; for ( ; par < par_end; par+= char_len) { if (!(char_len= my_mbcharlen_ptr(cs, par, par_end))) goto err; if (char_len == 1 && *par == quote_char) { if (start + 1 >= end) goto err; *start++= quote_char; } if (start + char_len >= end) goto err; start= my_stpnmov(start, par, char_len); } if (start + 1 >= end) goto err; *start++= quote_char; return start; err: *to='\0'; return to; }
size_t escape_string_for_mysql(const CHARSET_INFO *charset_info, char *to, size_t to_length, const char *from, size_t length) { const char *to_start= to; const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length); my_bool overflow= FALSE; my_bool use_mb_flag= use_mb(charset_info); for (end= from + length; from < end; from++) { char escape= 0; int tmp_length; if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end))) { if (to + tmp_length > to_end) { overflow= TRUE; break; } while (tmp_length--) *to++= *from++; from--; continue; } /* If the next character appears to begin a multi-byte character, we escape that first byte of that apparent multi-byte character. (The character just looks like a multi-byte character -- if it were actually a multi-byte character, it would have been passed through in the test above.) Without this check, we can create a problem by converting an invalid multi-byte character into a valid one. For example, 0xbf27 is not a valid GBK character, but 0xbf5c is. (0x27 = ', 0x5c = \) */ tmp_length= use_mb_flag ? my_mbcharlen_ptr(charset_info, from, end) : 0; if (tmp_length > 1) escape= *from; else switch (*from) { case 0: /* Must be escaped for 'mysql' */ escape= '0'; break; case '\n': /* Must be escaped for logs */ escape= 'n'; break; case '\r': escape= 'r'; break; case '\\': escape= '\\'; break; case '\'': escape= '\''; break; case '"': /* Better safe than sorry */ escape= '"'; break; case '\032': /* This gives problems on Win32 */ escape= 'Z'; break; } if (escape) { if (to + 2 > to_end) { overflow= TRUE; break; } *to++= '\\'; *to++= escape; } else { if (to + 1 > to_end) { overflow= TRUE; break; } *to++= *from; } } *to= 0; return overflow ? (size_t) -1 : (size_t) (to - to_start); }