summaryrefslogtreecommitdiffhomepage
path: root/src/load.c
diff options
context:
space:
mode:
authorKOBAYASHI Shuji <[email protected]>2019-01-08 20:31:29 +0900
committerKOBAYASHI Shuji <[email protected]>2019-01-08 20:43:23 +0900
commit68735d12614ef72b620736a5cd3052fb79445483 (patch)
treeb829d0e0e27fb250f9df3b873df2e253043c1efd /src/load.c
parent817436c33b556ba4129ae6cf45998d51ff7b9351 (diff)
downloadmruby-68735d12614ef72b620736a5cd3052fb79445483.tar.gz
mruby-68735d12614ef72b620736a5cd3052fb79445483.zip
Fix dump/load float leteral evaluate to infinity
Example: # example.rb p(2e308) p(-2e308) Good: $ bin/mruby example.rb inf -inf Bad: $ bin/mrbc example.rb $ bin/mruby -b example.mrb 0 -0 Cause: Float infinity representation is `inf` on dump and it is converted by corresponding `String#to_f` on load. Treatment: - Introduce new representations (`i`: +infinity, `I`: -infinity) - Allow old representations (`inf`, `-inf`, `infinity`, `-infinity`) too - Raise error for unknown representations (use corresponding `Kernel#Float`)
Diffstat (limited to 'src/load.c')
-rw-r--r--src/load.c20
1 files changed, 19 insertions, 1 deletions
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