mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
my_strntod_ucs2 and my_strntol_ucs2 fixes
This commit is contained in:
parent
e1cb867968
commit
ec7c4ea78d
1 changed files with 115 additions and 101 deletions
|
@ -22,7 +22,7 @@
|
|||
#include "m_string.h"
|
||||
#include "m_ctype.h"
|
||||
#include "my_sys.h" /* defines errno */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_CHARSET_utf8
|
||||
#define HAVE_UNIDATA
|
||||
|
@ -2118,7 +2118,7 @@ static int my_ucs2_uni (CHARSET_INFO *cs __attribute__((unused)) ,
|
|||
my_wc_t * pwc, const uchar *s, const uchar *e)
|
||||
{
|
||||
if (s+2 > e) /* Need 2 characters */
|
||||
return MY_CS_ILSEQ;
|
||||
return MY_CS_TOOFEW(0);
|
||||
|
||||
*pwc= ((unsigned char)s[0]) * 256 + ((unsigned char)s[1]);
|
||||
return 2;
|
||||
|
@ -2441,118 +2441,114 @@ static int my_snprintf_ucs2(CHARSET_INFO *cs __attribute__((unused))
|
|||
return my_vsnprintf_ucs2(to, n, fmt, args);
|
||||
}
|
||||
|
||||
#define MY_ERRNO(x)
|
||||
|
||||
long my_strntol_ucs2(CHARSET_INFO *cs,
|
||||
const char *nptr, uint l, char **endptr, int base)
|
||||
{
|
||||
int negative;
|
||||
register ulong cutoff;
|
||||
int negative=0;
|
||||
int overflow;
|
||||
int cnv;
|
||||
my_wc_t wc;
|
||||
register unsigned int cutlim;
|
||||
register ulong i;
|
||||
register const char *s;
|
||||
register unsigned char c;
|
||||
const char *save, *e;
|
||||
int overflow;
|
||||
register ulong cutoff;
|
||||
register ulong res;
|
||||
register const char *s=nptr;
|
||||
register const char *e=nptr+l;
|
||||
const char *save;
|
||||
|
||||
if (base < 0 || base == 1 || base > 36)
|
||||
do {
|
||||
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
|
||||
{
|
||||
switch (wc)
|
||||
{
|
||||
case ' ' : break;
|
||||
case '\t': break;
|
||||
case '-' : negative= !negative; break;
|
||||
case '+' : break;
|
||||
default : goto bs;
|
||||
}
|
||||
}
|
||||
else /* No more characters or bad multibyte sequence */
|
||||
{
|
||||
if (endptr !=NULL )
|
||||
*endptr = (char*)s;
|
||||
my_errno = (cnv==MY_CS_ILSEQ) ? EILSEQ : EDOM;
|
||||
return 0;
|
||||
}
|
||||
s+=cnv;
|
||||
} while (1);
|
||||
|
||||
bs:
|
||||
|
||||
if (base <= 0 || base == 1 || base > 36)
|
||||
base = 10;
|
||||
|
||||
s = nptr;
|
||||
e = nptr+l;
|
||||
|
||||
for ( ; s<e && my_isspace(cs, *s) ; s++);
|
||||
|
||||
if (s == e)
|
||||
{
|
||||
goto noconv;
|
||||
}
|
||||
|
||||
/* Check for a sign. */
|
||||
if (*s == '-')
|
||||
{
|
||||
negative = 1;
|
||||
++s;
|
||||
}
|
||||
else if (*s == '+')
|
||||
{
|
||||
negative = 0;
|
||||
++s;
|
||||
}
|
||||
else
|
||||
negative = 0;
|
||||
|
||||
if (base == 16 && s[0] == '0' && my_toupper(cs,s[1]) == 'X')
|
||||
s += 2;
|
||||
|
||||
if (base == 0)
|
||||
{
|
||||
if (*s == '0')
|
||||
{
|
||||
if (my_toupper(cs,s[1]) == 'X')
|
||||
{
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
else
|
||||
base = 8;
|
||||
}
|
||||
else
|
||||
base = 10;
|
||||
}
|
||||
|
||||
overflow = 0;
|
||||
res = 0;
|
||||
save = s;
|
||||
cutoff = ((ulong)~0L) / (unsigned long int) base;
|
||||
cutlim = (uint) (((ulong)~0L) % (unsigned long int) base);
|
||||
|
||||
overflow = 0;
|
||||
i = 0;
|
||||
for (c = *s; s != e; c = *++s)
|
||||
{
|
||||
if (my_isdigit(cs,c))
|
||||
c -= '0';
|
||||
else if (my_isalpha(cs,c))
|
||||
c = my_toupper(cs,c) - 'A' + 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (i > cutoff || (i == cutoff && c > cutlim))
|
||||
overflow = 1;
|
||||
|
||||
do {
|
||||
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
|
||||
{
|
||||
s+=cnv;
|
||||
if ( wc>='0' && wc<='9')
|
||||
wc -= '0';
|
||||
else if ( wc>='A' && wc<='Z')
|
||||
wc = wc - 'A' + 10;
|
||||
else if ( wc>='a' && wc<='z')
|
||||
wc = wc - 'a' + 10;
|
||||
else
|
||||
break;
|
||||
if ((int)wc >= base)
|
||||
break;
|
||||
if (res > cutoff || (res == cutoff && wc > cutlim))
|
||||
overflow = 1;
|
||||
else
|
||||
{
|
||||
res *= (ulong) base;
|
||||
res += wc;
|
||||
}
|
||||
}
|
||||
else if (cnv==MY_CS_ILSEQ)
|
||||
{
|
||||
if (endptr !=NULL )
|
||||
*endptr = (char*)s;
|
||||
my_errno=EILSEQ;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i *= (ulong) base;
|
||||
i += c;
|
||||
/* No more characters */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (s == save)
|
||||
goto noconv;
|
||||
} while(1);
|
||||
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *) s;
|
||||
|
||||
if (s == save)
|
||||
{
|
||||
my_errno=EDOM;
|
||||
return 0L;
|
||||
}
|
||||
|
||||
if (negative)
|
||||
{
|
||||
if (i > (ulong) LONG_MIN)
|
||||
if (res > (ulong) LONG_MIN)
|
||||
overflow = 1;
|
||||
}
|
||||
else if (i > (ulong) LONG_MAX)
|
||||
else if (res > (ulong) LONG_MAX)
|
||||
overflow = 1;
|
||||
|
||||
if (overflow)
|
||||
{
|
||||
MY_ERRNO(ERANGE);
|
||||
my_errno=(ERANGE);
|
||||
return negative ? LONG_MIN : LONG_MAX;
|
||||
}
|
||||
|
||||
return (negative ? -((long) i) : (long) i);
|
||||
|
||||
noconv:
|
||||
MY_ERRNO(EDOM);
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *) nptr;
|
||||
return 0L;
|
||||
return (negative ? -((long) res) : (long) res);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2646,14 +2642,14 @@ ulong my_strntoul_ucs2(CHARSET_INFO *cs,
|
|||
|
||||
if (overflow)
|
||||
{
|
||||
MY_ERRNO(ERANGE);
|
||||
my_errno=(ERANGE);
|
||||
return ((ulong)~0L);
|
||||
}
|
||||
|
||||
return (negative ? -((long) i) : (long) i);
|
||||
|
||||
noconv:
|
||||
MY_ERRNO(EDOM);
|
||||
my_errno=(EDOM);
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *) nptr;
|
||||
return 0L;
|
||||
|
@ -2759,14 +2755,14 @@ longlong my_strntoll_ucs2(CHARSET_INFO *cs __attribute__((unused)),
|
|||
|
||||
if (overflow)
|
||||
{
|
||||
MY_ERRNO(ERANGE);
|
||||
my_errno=(ERANGE);
|
||||
return negative ? LONGLONG_MIN : LONGLONG_MAX;
|
||||
}
|
||||
|
||||
return (negative ? -((longlong) i) : (longlong) i);
|
||||
|
||||
noconv:
|
||||
MY_ERRNO(EDOM);
|
||||
my_errno=(EDOM);
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *) nptr;
|
||||
return 0L;
|
||||
|
@ -2864,35 +2860,53 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs,
|
|||
|
||||
if (overflow)
|
||||
{
|
||||
MY_ERRNO(ERANGE);
|
||||
my_errno=(ERANGE);
|
||||
return (~(ulonglong) 0);
|
||||
}
|
||||
|
||||
return (negative ? -((longlong) i) : (longlong) i);
|
||||
|
||||
noconv:
|
||||
MY_ERRNO(EDOM);
|
||||
my_errno=(EDOM);
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *) nptr;
|
||||
return 0L;
|
||||
}
|
||||
|
||||
double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
|
||||
const char *s, uint l, char **e)
|
||||
const char *nptr, uint l, char **endptr)
|
||||
{
|
||||
char buf[256];
|
||||
double res;
|
||||
char buf[256];
|
||||
double res;
|
||||
register char *b=buf;
|
||||
register const char *s=nptr;
|
||||
register const char *e=nptr+l;
|
||||
my_wc_t wc;
|
||||
int cnv;
|
||||
|
||||
if((l+1)>sizeof(buf))
|
||||
{
|
||||
if (e)
|
||||
memcpy(*e,s,sizeof(s));
|
||||
if (endptr)
|
||||
*endptr=(char*)nptr;
|
||||
my_errno=ERANGE;
|
||||
return 0;
|
||||
}
|
||||
strncpy(buf,s,l);
|
||||
buf[l]='\0';
|
||||
res=strtod(buf,e);
|
||||
if (e)
|
||||
memcpy(*e,*e-buf+s,sizeof(s));
|
||||
|
||||
while ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
|
||||
{
|
||||
s+=cnv;
|
||||
if (wc < 128)
|
||||
{
|
||||
*b++=wc;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
*b='\0';
|
||||
|
||||
res=strtod(buf,endptr);
|
||||
if (endptr)
|
||||
*endptr=(char*) (*endptr-buf+nptr);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue