diff options
Diffstat (limited to 'strings')
-rw-r--r-- | strings/ctype-simple.c | 22 | ||||
-rw-r--r-- | strings/ctype-ucs2.c | 14 | ||||
-rw-r--r-- | strings/ctype-utf8.c | 6 | ||||
-rw-r--r-- | strings/int2str.c | 15 | ||||
-rw-r--r-- | strings/json_lib.c | 2 | ||||
-rw-r--r-- | strings/longlong2str.c | 15 | ||||
-rw-r--r-- | strings/str2int.c | 10 | ||||
-rw-r--r-- | strings/string.doc | 4 |
8 files changed, 67 insertions, 21 deletions
diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 94dc7228..83a36602 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -451,7 +451,11 @@ long my_strntol_8bit(CHARSET_INFO *cs, else if (c>='A' && c<='Z') c = c - 'A' + 10; else if (c>='a' && c<='z') + { c = c - 'a' + 10; + if (base > 36) + c += 26; + } else break; if (c >= base) @@ -546,7 +550,11 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs, else if (c>='A' && c<='Z') c = c - 'A' + 10; else if (c>='a' && c<='z') + { c = c - 'a' + 10; + if (base > 36) + c += 26; + } else break; if (c >= base) @@ -634,7 +642,11 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)), else if (c>='A' && c<='Z') c = c - 'A' + 10; else if (c>='a' && c<='z') + { c = c - 'a' + 10; + if (base > 36) + c += 26; + } else break; if (c >= base) @@ -656,8 +668,12 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)), if (negative) { - if (i > (ulonglong) LONGLONG_MIN) + if (i >= (ulonglong) LONGLONG_MIN) + { + if (i == (ulonglong) LONGLONG_MIN) + return LONGLONG_MIN; overflow = 1; + } } else if (i > (ulonglong) LONGLONG_MAX) overflow = 1; @@ -731,7 +747,11 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs, else if (c>='A' && c<='Z') c = c - 'A' + 10; else if (c>='a' && c<='z') + { c = c - 'a' + 10; + if (base > 36) + c += 26; + } else break; if (c >= base) diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 5d67762a..b68613e6 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -462,7 +462,11 @@ bs: else if ( wc>='A' && wc<='Z') wc = wc - 'A' + 10; else if ( wc>='a' && wc<='z') + { wc = wc - 'a' + 10; + if (base > 36) + wc += 26; + } else break; if ((int)wc >= base) @@ -500,8 +504,12 @@ bs: if (negative) { - if (res > (ulonglong) LONGLONG_MIN) + if (res >= (ulonglong) LONGLONG_MIN) + { + if (res == (ulonglong) LONGLONG_MIN) + return LONGLONG_MIN; overflow = 1; + } } else if (res > (ulonglong) LONGLONG_MAX) overflow = 1; @@ -575,7 +583,11 @@ bs: else if ( wc>='A' && wc<='Z') wc = wc - 'A' + 10; else if ( wc>='a' && wc<='z') + { wc = wc - 'a' + 10; + if (base > 36) + wc += 26; + } else break; if ((int)wc >= base) diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index ef7139ef..b7bdd0e9 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1243,7 +1243,8 @@ MY_CHARSET_HANDLER my_charset_utf8mb3_handler= struct charset_info_st my_charset_utf8mb3_general_ci= { 33,0,0, /* number */ - MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM|MY_CS_UNICODE, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM|MY_CS_UNICODE| + MY_CS_UPPER_EQUAL_AS_EQUAL, /* state */ { charset_name_utf8mb3, charset_name_utf8mb3_length }, /* cs name */ { STRING_WITH_LEN(MY_UTF8MB3 "_general_ci") }, /* name */ "", /* comment */ @@ -3573,7 +3574,8 @@ MY_CHARSET_HANDLER my_charset_utf8mb4_handler= struct charset_info_st my_charset_utf8mb4_general_ci= { 45,0,0, /* number */ - MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_UNICODE_SUPPLEMENT, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM|MY_CS_UNICODE| + MY_CS_UNICODE_SUPPLEMENT|MY_CS_UPPER_EQUAL_AS_EQUAL, /* state */ { charset_name_utf8mb4, charset_name_utf8mb4_length}, /* cs name */ { STRING_WITH_LEN(MY_UTF8MB4_GENERAL_CI) }, /* name */ "UTF-8 Unicode", /* comment */ diff --git a/strings/int2str.c b/strings/int2str.c index 9d099d2e..7fc60817 100644 --- a/strings/int2str.c +++ b/strings/int2str.c @@ -31,6 +31,8 @@ /* _dig_vec arrays are public because they are used in several outer places. */ +const char _dig_vec_base62[] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; const char _dig_vec_upper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char _dig_vec_lower[] = @@ -50,7 +52,7 @@ const char _dig_vec_lower[] = DESCRIPTION Converts the (long) integer value to its character form and moves it to the destination buffer followed by a terminating NUL. - If radix is -2..-36, val is taken to be SIGNED, if radix is 2..36, val is + If radix is -2..-62, val is taken to be SIGNED, if radix is 2..62, val is taken to be UNSIGNED. That is, val is signed if and only if radix is. All other radixes treated as bad and nothing will be changed in this case. @@ -68,12 +70,17 @@ int2str(register long int val, register char *dst, register int radix, char buffer[65]; register char *p; long int new_val; - const char *dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower; + const char *dig_vec; ulong uval= (ulong) val; + if (radix < -36 || radix > 36) + dig_vec= _dig_vec_base62; + else + dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower; + if (radix < 0) { - if (radix < -36 || radix > -2) + if (radix < -62 || radix > -2) return NullS; if (val < 0) { @@ -83,7 +90,7 @@ int2str(register long int val, register char *dst, register int radix, } radix = -radix; } - else if (radix > 36 || radix < 2) + else if (radix > 62 || radix < 2) return NullS; /* diff --git a/strings/json_lib.c b/strings/json_lib.c index 31d58074..e1203296 100644 --- a/strings/json_lib.c +++ b/strings/json_lib.c @@ -1093,7 +1093,7 @@ static int json_path_transitions[N_PATH_STATES][N_PATH_CLASSES]= /* AS */ { JE_EOS, JE_SYN, JE_SYN, JE_SYN, PS_T, PS_PT, JE_SYN, PS_NEG, PS_Z, PS_INT, PS_LAST, PS_AS, JE_SYN, JE_SYN, JE_SYN, JE_NOT_JSON_CHR, JE_BAD_CHR}, -/* KEY */ { JE_EOS, PS_KNM, PS_KWD, JE_SYN, PS_KNM, PS_KNM, JE_SYN, JE_SYN, +/* KEY */ { JE_EOS, PS_KNM, PS_KWD, JE_SYN, PS_KNM, PS_KNM, JE_SYN, PS_KNM, PS_KNM, PS_KNM, PS_KNM, PS_KNM, PS_KNM, JE_SYN, PS_KEYX, PS_KNM, JE_NOT_JSON_CHR, JE_BAD_CHR}, /* KNM */ { PS_KOK, PS_KNM, PS_AST, PS_EAR, PS_KNM, PS_KNM, PS_EKY, PS_KNM, diff --git a/strings/longlong2str.c b/strings/longlong2str.c index ab46353d..9477e01b 100644 --- a/strings/longlong2str.c +++ b/strings/longlong2str.c @@ -35,8 +35,8 @@ result is normally a pointer to this NUL character, but if the radix is dud the result will be NullS and nothing will be changed. - If radix is -2..-36, val is taken to be SIGNED. - If radix is 2.. 36, val is taken to be UNSIGNED. + If radix is -2..-62, val is taken to be SIGNED. + If radix is 2.. 62, val is taken to be UNSIGNED. That is, val is signed if and only if radix is. You will normally use radix -10 only through itoa and ltoa, for radix 2, 8, or 16 unsigned is what you generally want. @@ -63,12 +63,17 @@ char *ll2str(longlong val,char *dst,int radix, int upcase) char buffer[65]; register char *p; long long_val; - const char *dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower; + const char *dig_vec; ulonglong uval= (ulonglong) val; + if (radix < -36 || radix > 36) + dig_vec= _dig_vec_base62; + else + dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower; + if (radix < 0) { - if (radix < -36 || radix > -2) return (char*) 0; + if (radix < -62 || radix > -2) return (char*) 0; if (val < 0) { *dst++ = '-'; /* Avoid integer overflow in (-val) for LONGLONG_MIN (BUG#31799). */ @@ -78,7 +83,7 @@ char *ll2str(longlong val,char *dst,int radix, int upcase) } else { - if (radix > 36 || radix < 2) return (char*) 0; + if (radix > 62 || radix < 2) return (char*) 0; } if (uval == 0) { diff --git a/strings/str2int.c b/strings/str2int.c index 439a50dd..ab91e862 100644 --- a/strings/str2int.c +++ b/strings/str2int.c @@ -55,9 +55,9 @@ #include "my_sys.h" /* defines errno */ #include <errno.h> -#define char_val(X) (X >= '0' && X <= '9' ? X-'0' :\ +#define char_val(X, Y) (X >= '0' && X <= '9' ? X-'0' :\ X >= 'A' && X <= 'Z' ? X-'A'+10 :\ - X >= 'a' && X <= 'z' ? X-'a'+10 :\ + X >= 'a' && X <= 'z' ? (Y <= 36 ? X-'a'+10 : X-'a'+36) :\ '\177') char *str2int(register const char *src, register int radix, long int lower, @@ -76,10 +76,10 @@ char *str2int(register const char *src, register int radix, long int lower, *val = 0; - /* Check that the radix is in the range 2..36 */ + /* Check that the radix is in the range 2..62 */ #ifndef DBUG_OFF - if (radix < 2 || radix > 36) { + if (radix < 2 || radix > 62) { errno=EDOM; return NullS; } @@ -126,7 +126,7 @@ char *str2int(register const char *src, register int radix, long int lower, to left in order to avoid overflow. Answer is after last digit. */ - for (n = 0; (digits[n]=char_val(*src)) < radix && n < 20; n++,src++) ; + for (n = 0; (digits[n]=char_val(*src, radix)) < radix && n < 20; n++,src++) ; /* Check that there is at least one digit */ diff --git a/strings/string.doc b/strings/string.doc index 3e5b6073..4050f6af 100644 --- a/strings/string.doc +++ b/strings/string.doc @@ -22,8 +22,8 @@ Speciella användbara nya string-rutiner: the destination string "dst" followed by a terminating NUL. The result is normally a pointer to this NUL character, but if the radix is dud the result will be NullS and nothing will be changed. - If radix is -2..-36, val is taken to be SIGNED. - If radix is 2.. 36, val is taken to be UNSIGNED. + If radix is -2..-62, val is taken to be SIGNED. + If radix is 2.. 62, val is taken to be UNSIGNED. That is, val is signed if and only if radix is. You will normally use radix -10 only through itoa and ltoa, for radix 2, 8, or 16 unsigned is what you generally want. |