summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2019-01-08 21:42:50 +0900
committerGitHub <[email protected]>2019-01-08 21:42:50 +0900
commit712a8bb1b2afd48a695933a671c118f9dfa372a4 (patch)
tree2b71f09ce2bff059e35d8ca8bf5cd12267944a45
parentb575d0c45ef21f0f51fc31be8612333fe16e8a8e (diff)
parent68735d12614ef72b620736a5cd3052fb79445483 (diff)
downloadmruby-712a8bb1b2afd48a695933a671c118f9dfa372a4.tar.gz
mruby-712a8bb1b2afd48a695933a671c118f9dfa372a4.zip
Merge pull request #4219 from shuujii/fix-dump-load-float-literal-evaluate-to-infinity
Fix dump/load float leteral evaluate to infinity
-rw-r--r--mrbgems/mruby-bin-mruby/bintest/mruby.rb7
-rw-r--r--src/dump.c17
-rw-r--r--src/load.c20
3 files changed, 41 insertions, 3 deletions
diff --git a/mrbgems/mruby-bin-mruby/bintest/mruby.rb b/mrbgems/mruby-bin-mruby/bintest/mruby.rb
index a7fb63fa2..f3c7d8761 100644
--- a/mrbgems/mruby-bin-mruby/bintest/mruby.rb
+++ b/mrbgems/mruby-bin-mruby/bintest/mruby.rb
@@ -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')
diff --git a/src/dump.c b/src/dump.c
index 6ce9c4eb9..11eba4e40 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -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
diff --git a/src/load.c b/src/load.c
index 559fff1d4..55e0845f3 100644
--- a/src/load.c
+++ b/src/load.c
@@ -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