diff options
Diffstat (limited to 'src/lib_string.c')
-rw-r--r-- | src/lib_string.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/src/lib_string.c b/src/lib_string.c index 1231aeb2..528b3d0e 100644 --- a/src/lib_string.c +++ b/src/lib_string.c | |||
@@ -734,9 +734,23 @@ LJLIB_CF(string_format) | |||
734 | addintlen(form); | 734 | addintlen(form); |
735 | sprintf(buff, form, (unsigned LUA_INTFRM_T)lj_lib_checknum(L, arg)); | 735 | sprintf(buff, form, (unsigned LUA_INTFRM_T)lj_lib_checknum(L, arg)); |
736 | break; | 736 | break; |
737 | case 'e': case 'E': case 'f': case 'g': case 'G': | 737 | case 'e': case 'E': case 'f': case 'g': case 'G': { |
738 | sprintf(buff, form, (double)lj_lib_checknum(L, arg)); | 738 | TValue tv; |
739 | tv.n = lj_lib_checknum(L, arg); | ||
740 | if (LJ_UNLIKELY((tv.u32.hi << 1) >= 0xffe00000)) { | ||
741 | /* Canonicalize output of non-finite values. */ | ||
742 | size_t len = lj_str_bufnum(buff, &tv); | ||
743 | if (strfrmt[-1] == 'E' || strfrmt[-1] == 'G') { | ||
744 | buff[len-3] = buff[len-3] - 0x20; | ||
745 | buff[len-2] = buff[len-2] - 0x20; | ||
746 | buff[len-1] = buff[len-1] - 0x20; | ||
747 | } | ||
748 | luaL_addlstring(&b, buff, len); | ||
749 | continue; | ||
750 | } | ||
751 | sprintf(buff, form, (double)tv.n); | ||
739 | break; | 752 | break; |
753 | } | ||
740 | case 'q': | 754 | case 'q': |
741 | addquoted(L, &b, arg); | 755 | addquoted(L, &b, arg); |
742 | continue; | 756 | continue; |