mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge pull request #4219 from shuujii/fix-dump-load-float-literal-evaluate-to-infinity
Fix dump/load float leteral evaluate to infinity
This commit is contained in:
@@ -31,6 +31,13 @@ assert '$0 value' do
|
||||
assert_equal '"-e"', `#{cmd('mruby')} -e #{shellquote('p $0')}`.chomp
|
||||
end
|
||||
|
||||
assert('float literal') do
|
||||
script, bin = Tempfile.new('test.rb'), Tempfile.new('test.mrb')
|
||||
File.write script.path, 'p [3.21, 2e308.infinite?, -2e308.infinite?]'
|
||||
system "#{cmd('mrbc')} -g -o #{bin.path} #{script.path}"
|
||||
assert_equal "[3.21, 1, -1]", `#{cmd('mruby')} -b #{bin.path}`.chomp!
|
||||
end
|
||||
|
||||
assert '__END__', '8.6' do
|
||||
script = Tempfile.new('test.rb')
|
||||
|
||||
|
||||
+15
-2
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <mruby/dump.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/irep.h>
|
||||
@@ -90,6 +91,18 @@ write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf, uint8_t flags)
|
||||
return cur - buf;
|
||||
}
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
static mrb_value
|
||||
float_to_str(mrb_state *mrb, mrb_value flt)
|
||||
{
|
||||
mrb_float f = mrb_float(flt);
|
||||
|
||||
if (isinf(f)) {
|
||||
return f < 0 ? mrb_str_new_lit(mrb, "I") : mrb_str_new_lit(mrb, "i");
|
||||
}
|
||||
return mrb_float_to_str(mrb, flt, MRB_FLOAT_FMT);
|
||||
}
|
||||
#endif
|
||||
|
||||
static size_t
|
||||
get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
|
||||
@@ -116,7 +129,7 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT);
|
||||
str = float_to_str(mrb, irep->pool[pool_no]);
|
||||
{
|
||||
mrb_int len = RSTRING_LEN(str);
|
||||
mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
|
||||
@@ -165,7 +178,7 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */
|
||||
str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT);
|
||||
str = float_to_str(mrb, irep->pool[pool_no]);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
+19
-1
@@ -7,6 +7,7 @@
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <mruby/dump.h>
|
||||
#include <mruby/irep.h>
|
||||
#include <mruby/proc.h>
|
||||
@@ -40,6 +41,23 @@ offset_crc_body(void)
|
||||
return ((uint8_t *)header.binary_crc - (uint8_t *)&header) + sizeof(header.binary_crc);
|
||||
}
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
static double
|
||||
str_to_double(mrb_state *mrb, mrb_value str)
|
||||
{
|
||||
const char *p = RSTRING_PTR(str);
|
||||
mrb_int len = RSTRING_LEN(str);
|
||||
|
||||
/* `i`, `inf`, `infinity` */
|
||||
if (len > 0 && p[0] == 'i') return INFINITY;
|
||||
|
||||
/* `I`, `-inf`, `-infinity` */
|
||||
if (p[0] == 'I' || (len > 1 && p[0] == '-' && p[1] == 'i')) return -INFINITY;
|
||||
|
||||
return mrb_str_to_dbl(mrb, str, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
static mrb_irep*
|
||||
read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags)
|
||||
{
|
||||
@@ -125,7 +143,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
case IREP_TT_FLOAT:
|
||||
irep->pool[i] = mrb_float_pool(mrb, mrb_str_to_dbl(mrb, s, FALSE));
|
||||
irep->pool[i] = mrb_float_pool(mrb, str_to_double(mrb, s));
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user