about summary refs log tree commit diff
path: root/src/libexpr/json-to-value.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/json-to-value.cc')
-rw-r--r--src/libexpr/json-to-value.cc26
1 files changed, 15 insertions, 11 deletions
diff --git a/src/libexpr/json-to-value.cc b/src/libexpr/json-to-value.cc
index 1892b0bac1af..1daf84600dca 100644
--- a/src/libexpr/json-to-value.cc
+++ b/src/libexpr/json-to-value.cc
@@ -73,7 +73,7 @@ static void parseJSON(EvalState & state, const char * & s, Value & v)
         s++;
         state.mkList(v, values.size());
         for (size_t n = 0; n < values.size(); ++n)
-            v.list.elems[n] = values[n];
+            v.listElems()[n] = values[n];
     }
 
     else if (*s == '{') {
@@ -105,17 +105,21 @@ static void parseJSON(EvalState & state, const char * & s, Value & v)
         mkString(v, parseJSONString(s));
     }
 
-    else if (isdigit(*s) || *s == '-') {
-        bool neg = false;
-        if (*s == '-') {
-            neg = true;
-            if (!*++s) throw JSONParseError("unexpected end of JSON number");
+    else if (isdigit(*s) || *s == '-' || *s == '.' ) {
+        // Buffer into a string first, then use built-in C++ conversions
+        std::string tmp_number;
+        ValueType number_type = tInt;
+
+        while (isdigit(*s) || *s == '-' || *s == '.' || *s == 'e' || *s == 'E') {
+            if (*s == '.' || *s == 'e' || *s == 'E')
+                number_type = tFloat;
+            tmp_number += *s++;
         }
-        NixInt n = 0;
-        // FIXME: detect overflow
-        while (isdigit(*s)) n = n * 10 + (*s++ - '0');
-        if (*s == '.' || *s == 'e') throw JSONParseError("floating point JSON numbers are not supported");
-        mkInt(v, neg ? -n : n);
+
+        if (number_type == tFloat)
+            mkFloat(v, stod(tmp_number));
+        else
+            mkInt(v, stoi(tmp_number));
     }
 
     else if (strncmp(s, "true", 4) == 0) {