mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Canonicalize string conversion of nan, inf, -inf.
This commit is contained in:
parent
c7a3103f41
commit
926f688cd0
@ -413,8 +413,7 @@ LJLIB_CF(print)
|
|||||||
size = strV(o)->len;
|
size = strV(o)->len;
|
||||||
} else if (shortcut && tvisnum(o)) {
|
} else if (shortcut && tvisnum(o)) {
|
||||||
char buf[LUAI_MAXNUMBER2STR];
|
char buf[LUAI_MAXNUMBER2STR];
|
||||||
lua_Number n = numV(o);
|
size = lj_str_bufnum(buf, o);
|
||||||
size = (size_t)lua_number2str(buf, n);
|
|
||||||
str = buf;
|
str = buf;
|
||||||
} else {
|
} else {
|
||||||
copyTV(L, L->top+1, o);
|
copyTV(L, L->top+1, o);
|
||||||
|
@ -734,9 +734,23 @@ LJLIB_CF(string_format)
|
|||||||
addintlen(form);
|
addintlen(form);
|
||||||
sprintf(buff, form, (unsigned LUA_INTFRM_T)lj_lib_checknum(L, arg));
|
sprintf(buff, form, (unsigned LUA_INTFRM_T)lj_lib_checknum(L, arg));
|
||||||
break;
|
break;
|
||||||
case 'e': case 'E': case 'f': case 'g': case 'G':
|
case 'e': case 'E': case 'f': case 'g': case 'G': {
|
||||||
sprintf(buff, form, (double)lj_lib_checknum(L, arg));
|
TValue tv;
|
||||||
|
tv.n = lj_lib_checknum(L, arg);
|
||||||
|
if (LJ_UNLIKELY((tv.u32.hi << 1) >= 0xffe00000)) {
|
||||||
|
/* Canonicalize output of non-finite values. */
|
||||||
|
size_t len = lj_str_bufnum(buff, &tv);
|
||||||
|
if (strfrmt[-1] == 'E' || strfrmt[-1] == 'G') {
|
||||||
|
buff[len-3] = buff[len-3] - 0x20;
|
||||||
|
buff[len-2] = buff[len-2] - 0x20;
|
||||||
|
buff[len-1] = buff[len-1] - 0x20;
|
||||||
|
}
|
||||||
|
luaL_addlstring(&b, buff, len);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sprintf(buff, form, (double)tv.n);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'q':
|
case 'q':
|
||||||
addquoted(L, &b, arg);
|
addquoted(L, &b, arg);
|
||||||
continue;
|
continue;
|
||||||
|
32
src/lj_str.c
32
src/lj_str.c
@ -173,13 +173,27 @@ parsedbl:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Print number to buffer. Canonicalizes non-finite values. */
|
||||||
|
size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o)
|
||||||
|
{
|
||||||
|
if (LJ_LIKELY((o->u32.hi << 1) < 0xffe00000)) { /* Finite? */
|
||||||
|
lua_Number n = o->n;
|
||||||
|
return (size_t)lua_number2str(s, n);
|
||||||
|
} else if (((o->u32.hi & 0x000fffff) | o->u32.lo) != 0) {
|
||||||
|
s[0] = 'n'; s[1] = 'a'; s[2] = 'n'; return 3;
|
||||||
|
} else if ((o->u32.hi & 0x80000000) == 0) {
|
||||||
|
s[0] = 'i'; s[1] = 'n'; s[2] = 'f'; return 3;
|
||||||
|
} else {
|
||||||
|
s[0] = '-'; s[1] = 'i'; s[2] = 'n'; s[3] = 'f'; return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert number to string. */
|
/* Convert number to string. */
|
||||||
GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np)
|
GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np)
|
||||||
{
|
{
|
||||||
char s[LUAI_MAXNUMBER2STR];
|
char buf[LUAI_MAXNUMBER2STR];
|
||||||
lua_Number n = *np;
|
size_t len = lj_str_bufnum(buf, (TValue *)np);
|
||||||
size_t len = (size_t)lua_number2str(s, n);
|
return lj_str_new(L, buf, len);
|
||||||
return lj_str_new(L, s, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LJ_HASJIT
|
#if LJ_HASJIT
|
||||||
@ -252,10 +266,12 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'f': {
|
case 'f': {
|
||||||
char buff[LUAI_MAXNUMBER2STR];
|
char buf[LUAI_MAXNUMBER2STR];
|
||||||
lua_Number n = cast_num(va_arg(argp, LUAI_UACNUMBER));
|
TValue tv;
|
||||||
MSize len = (MSize)lua_number2str(buff, n);
|
MSize len;
|
||||||
addstr(L, sb, buff, len);
|
tv.n = cast_num(va_arg(argp, LUAI_UACNUMBER));
|
||||||
|
len = (MSize)lj_str_bufnum(buf, &tv);
|
||||||
|
addstr(L, sb, buf, len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'p': {
|
case 'p': {
|
||||||
|
@ -22,6 +22,7 @@ LJ_FUNC void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s);
|
|||||||
/* Type conversions. */
|
/* Type conversions. */
|
||||||
LJ_FUNC int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n);
|
LJ_FUNC int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n);
|
||||||
LJ_FUNC int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n);
|
LJ_FUNC int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n);
|
||||||
|
LJ_FUNC size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o);
|
||||||
LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np);
|
LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np);
|
||||||
#if LJ_HASJIT
|
#if LJ_HASJIT
|
||||||
LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k);
|
LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k);
|
||||||
|
Loading…
Reference in New Issue
Block a user