size_t dirname_length(const char *name) { char *pos, *gpos; #ifdef _WIN32 CHARSET_INFO *fs= fs_character_set(); #endif #ifdef FN_DEVCHAR if ((pos=(char*)strrchr(name,FN_DEVCHAR)) == 0) #endif pos=(char*) name-1; gpos= pos++; for ( ; *pos ; pos++) /* Find last FN_LIBCHAR */ { #ifdef _WIN32 uint l; if (use_mb(fs) && (l= my_ismbchar(fs, pos, pos + 3))) { pos+= l - 1; continue; } #endif if (*pos == FN_LIBCHAR || *pos == '/') gpos=pos; } return (size_t) (gpos+1-(char*) name); }
int my_casecmp(const char *s, const char *t, uint len) { #ifdef USE_MB if (use_mb(default_charset_info)) { register uint32 l; register const char *end=s+len; while (s<end) { if ((l=my_ismbchar(default_charset_info, s,end))) { while (l--) if (*s++ != *t++) return 1; } else if (my_ismbhead(default_charset_info, *t)) return 1; else if (toupper((uchar) *s++) != toupper((uchar) *t++)) return 1; } return 0; } else #endif { while (len-- != 0 && toupper(*s++) == toupper(*t++)) ; return (int) len+1; } }
int my_strcasecmp(const char *s, const char *t) { #ifdef USE_MB if (use_mb(default_charset_info)) { register uint32 l; register const char *end=s+strlen(s); while (s<end) { if ((l=my_ismbchar(default_charset_info, s,end))) { while (l--) if (*s++ != *t++) return 1; } else if (my_ismbhead(default_charset_info, *t)) return 1; else if (toupper((uchar) *s++) != toupper((uchar) *t++)) return 1; } return *t; } else #endif { while (toupper((uchar) *s) == toupper((uchar) *t++)) if (!*s++) return 0; return ((int) toupper((uchar) s[0]) - (int) toupper((uchar) t[-1])); } }
uint dirname_length(const char *name) { register my_string pos,gpos; #ifdef BASKSLASH_MBTAIL CHARSET_INFO *fs= fs_character_set(); #endif #ifdef FN_DEVCHAR if ((pos=(char*)strrchr(name,FN_DEVCHAR)) == 0) #endif pos=(char*) name-1; gpos= pos++; for ( ; *pos ; pos++) /* Find last FN_LIBCHAR */ { #ifdef BASKSLASH_MBTAIL uint l; if (use_mb(fs) && (l= my_ismbchar(fs, pos, pos + 3))) { pos+= l - 1; continue; } #endif if (*pos == FN_LIBCHAR || *pos == '/' #ifdef FN_C_AFTER_DIR || *pos == FN_C_AFTER_DIR || *pos == FN_C_AFTER_DIR_2 #endif ) gpos=pos; } return ((uint) (uint) (gpos+1-(char*) name)); }
char *convert_dirname(char *to, const char *from, const char *from_end) { char *to_org=to; #ifdef BACKSLASH_MBTAIL CHARSET_INFO *fs= fs_character_set(); #endif /* We use -2 here, becasue we need place for the last FN_LIBCHAR */ if (!from_end || (from_end - from) > FN_REFLEN-2) from_end=from+FN_REFLEN -2; #if FN_LIBCHAR != '/' || defined(FN_C_BEFORE_DIR_2) { for (; from != from_end && *from ; from++) { if (*from == '/') *to++= FN_LIBCHAR; #ifdef FN_C_BEFORE_DIR_2 else if (*from == FN_C_BEFORE_DIR_2) *to++= FN_C_BEFORE_DIR; else if (*from == FN_C_AFTER_DIR_2) *to++= FN_C_AFTER_DIR; #endif else { #ifdef BACKSLASH_MBTAIL uint l; if (use_mb(fs) && (l= my_ismbchar(fs, from, from + 3))) { memmove(to, from, l); to+= l; from+= l - 1; to_org= to; /* Don't look inside mbchar */ } else #endif { *to++= *from; } } } *to=0; } #else /* This is ok even if to == from, becasue we need to cut the string */ to= strmake(to, from, (uint) (from_end-from)); #endif /* Add FN_LIBCHAR to the end of directory path */ if (to != to_org && (to[-1] != FN_LIBCHAR && to[-1] != FN_DEVCHAR)) { *to++=FN_LIBCHAR; *to=0; } return to; /* Pointer to end of dir */ } /* convert_dirname */
size_t escape_quotes_for_mysql(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; #ifdef USE_MB my_bool use_mb_flag= use_mb(charset_info); #endif for (end= from + length; from < end; from++) { #ifdef USE_MB 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; } /* We don't have the same issue here with a non-multi-byte character being turned into a multi-byte character by the addition of an escaping character, because we are only escaping the ' character with itself. */ #endif if (*from == '\'') { if (to + 2 > to_end) { overflow= TRUE; break; } *to++= '\''; *to++= '\''; } else { if (to + 1 > to_end) { overflow= TRUE; break; } *to++= *from; } } *to= 0; return overflow ? (ulong)~0 : (ulong) (to - to_start); }
char *convert_dirname(char *to, const char *from, const char *from_end) { char *to_org=to; #ifdef _WIN32 CHARSET_INFO *fs= fs_character_set(); #endif DBUG_ENTER("convert_dirname"); /* We use -2 here, becasue we need place for the last FN_LIBCHAR */ if (!from_end || (from_end - from) > FN_REFLEN-2) from_end=from+FN_REFLEN -2; #if FN_LIBCHAR != '/' { for (; from != from_end && *from ; from++) { if (*from == '/') *to++= FN_LIBCHAR; else { #ifdef _WIN32 uint l; if (use_mb(fs) && (l= my_ismbchar(fs, from, from + 3))) { memmove(to, from, l); to+= l; from+= l - 1; to_org= to; /* Don't look inside mbchar */ } else #endif { *to++= *from; } } } *to=0; } #else /* This is ok even if to == from, becasue we need to cut the string */ to= strmake(to, from, (size_t) (from_end-from)); #endif /* Add FN_LIBCHAR to the end of directory path */ if (to != to_org && (to[-1] != FN_LIBCHAR && to[-1] != FN_DEVCHAR)) { *to++=FN_LIBCHAR; *to=0; } DBUG_RETURN(to); /* Pointer to end of dir */ } /* convert_dirname */
void my_casedn_str_mb(CHARSET_INFO * cs, char *str) { register uint32 l; register char *end=str+strlen(str); register uchar *map=cs->to_lower; while (*str) { if ((l=my_ismbchar(cs, str,end))) str+=l; else { *str=(char) map[(uchar)*str]; str++; } } }
void my_caseup_str_mb(CHARSET_INFO * cs, char *str) { register uint32 l; register char *end=str+strlen(str); /* BAR TODO: remove strlen() call */ register uchar *map=cs->to_upper; while (*str) { if ((l=my_ismbchar(cs, str,end))) str+=l; else { *str=(char) map[(uchar)*str]; str++; } } }
void casedn(my_string str, uint length) { #ifdef USE_MB if (use_mb(default_charset_info)) { register uint32 l; register char *end=str+length; while (str<end) { if ((l=my_ismbchar(default_charset_info, str,end))) str+=l; else *str=tolower(*str),++str; } } else #endif for ( ; length>0 ; length--, str++) *str= tolower(*str); } /* casedn */
size_t my_casedn_str_mb(CHARSET_INFO * cs, char *str) { register uint32 l; register uchar *map= cs->to_lower; char *str_orig= str; while (*str) { /* Pointing after the '\0' is safe here. */ if ((l= my_ismbchar(cs, str, str + cs->mbmaxlen))) str+= l; else { *str= (char) map[(uchar)*str]; str++; } } return (size_t) (str - str_orig); }
void casedn_str(my_string str) { #ifdef USE_MB if (use_mb(default_charset_info)) { register uint32 l; register char *end=str+strlen(str); while (*str) { if ((l=my_ismbchar(default_charset_info, str,end))) str+=l; else *str=tolower(*str),++str; } } else #endif while (*str!=0) /* iterate till the end of string */ { *str= tolower(*str); str++; } } /* casedn_str */
size_t my_copy_with_hex_escaping(CHARSET_INFO *cs, char *dst, size_t dstlen, const char *src, size_t srclen) { const char *srcend= src + srclen; char *dst0= dst; for ( ; src < srcend ; ) { size_t chlen; if ((chlen= my_ismbchar(cs, src, srcend))) { if (dstlen < chlen) break; /* purecov: inspected */ memcpy(dst, src, chlen); src+= chlen; dst+= chlen; dstlen-= chlen; } else if (*src & 0x80) { if (dstlen < 4) break; /* purecov: inspected */ *dst++= '\\'; *dst++= 'x'; *dst++= _dig_vec_upper[((unsigned char) *src) >> 4]; *dst++= _dig_vec_upper[((unsigned char) *src) & 15]; src++; dstlen-= 4; } else { if (dstlen < 1) break; /* purecov: inspected */ *dst++= *src++; dstlen--; } }
size_t cleanup_dirname(register char *to, const char *from) { reg5 size_t length; reg2 char * pos; reg3 char * from_ptr; reg4 char * start; char parent[5], /* for "FN_PARENTDIR" */ buff[FN_REFLEN+1],*end_parentdir; #ifdef BACKSLASH_MBTAIL CHARSET_INFO *fs= fs_character_set(); #endif DBUG_ENTER("cleanup_dirname"); DBUG_PRINT("enter",("from: '%s'",from)); start=buff; from_ptr=(char *) from; #ifdef FN_DEVCHAR if ((pos=strrchr(from_ptr,FN_DEVCHAR)) != 0) { /* Skip device part */ length=(size_t) (pos-from_ptr)+1; start=strnmov(buff,from_ptr,length); from_ptr+=length; } #endif parent[0]=FN_LIBCHAR; length=(size_t) (strmov(parent+1,FN_PARENTDIR)-parent); for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++) { #ifdef BACKSLASH_MBTAIL uint l; if (use_mb(fs) && (l= my_ismbchar(fs, from_ptr - 1, from_ptr + 2))) { for (l-- ; l ; *++pos= *from_ptr++, l--); start= pos + 1; /* Don't look inside multi-byte char */ continue; } #endif if (*pos == '/') *pos = FN_LIBCHAR; if (*pos == FN_LIBCHAR) { if ((size_t) (pos-start) > length && memcmp(pos-length,parent,length) == 0) { /* If .../../; skip prev */ pos-=length; if (pos != start) { /* not /../ */ pos--; if (*pos == FN_HOMELIB && (pos == start || pos[-1] == FN_LIBCHAR)) { if (!home_dir) { pos+=length+1; /* Don't unpack ~/.. */ continue; } pos=strmov(buff,home_dir)-1; /* Unpacks ~/.. */ if (*pos == FN_LIBCHAR) pos--; /* home ended with '/' */ } if (*pos == FN_CURLIB && (pos == start || pos[-1] == FN_LIBCHAR)) { if (my_getwd(curr_dir,FN_REFLEN,MYF(0))) { pos+=length+1; /* Don't unpack ./.. */ continue; } pos=strmov(buff,curr_dir)-1; /* Unpacks ./.. */ if (*pos == FN_LIBCHAR) pos--; /* home ended with '/' */ } end_parentdir=pos; while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */ pos--; if (pos[1] == FN_HOMELIB || (pos > start && memcmp(pos, parent, length) == 0)) { /* Don't remove ~user/ */ pos=strmov(end_parentdir+1,parent); *pos=FN_LIBCHAR; continue; } } } else if ((size_t) (pos-start) == length-1 && !memcmp(start,parent+1,length-1)) start=pos; /* Starts with "../" */ else if (pos-start > 0 && pos[-1] == FN_LIBCHAR) { #ifdef FN_NETWORK_DRIVES if (pos-start != 1) #endif pos--; /* Remove dupplicate '/' */ } else if (pos-start > 1 && pos[-1] == FN_CURLIB && pos[-2] == FN_LIBCHAR) pos-=2; /* Skip /./ */ else if (pos > buff+1 && pos[-1] == FN_HOMELIB && pos[-2] == FN_LIBCHAR) { /* Found ..../~/ */ buff[0]=FN_HOMELIB; buff[1]=FN_LIBCHAR; start=buff; pos=buff+1; } } } (void) strmov(to,buff); DBUG_PRINT("exit",("to: '%s'",to)); DBUG_RETURN((size_t) (pos-buff)); } /* cleanup_dirname */
size_t escape_string_for_mysql(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; #ifdef USE_MB my_bool use_mb_flag= use_mb(charset_info); #endif for (end= from + length; from < end; from++) { char escape= 0; #ifdef USE_MB 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 = \) */ if (use_mb_flag && (tmp_length= my_mbcharlen(charset_info, *from)) > 1) escape= *from; else #endif 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); }