diff --git a/editor/js/ui/clipboard.js b/editor/js/ui/clipboard.js
index 0d7519e10..e4350a464 100644
--- a/editor/js/ui/clipboard.js
+++ b/editor/js/ui/clipboard.js
@@ -276,9 +276,20 @@ RED.clipboard = (function() {
if (typeof value !== "string" ) {
value = JSON.stringify(value, function(key,value) {
if (value !== null && typeof value === 'object') {
- if (value.__encoded__ && value.hasOwnProperty('data') && value.hasOwnProperty('length')) {
- truncated = value.data.length !== value.length;
- return value.data;
+ if (value.__encoded__) {
+ if (value.hasOwnProperty('data') && value.hasOwnProperty('length')) {
+ truncated = value.data.length !== value.length;
+ return value.data;
+ }
+ if (value.type === 'function' || value.type === 'internal') {
+ return undefined
+ }
+ if (value.type === 'number') {
+ // Handle NaN and Infinity - they are not permitted
+ // in JSON. We can either substitute with a String
+ // representation or null
+ return null;
+ }
}
}
return value;
diff --git a/editor/js/ui/utils.js b/editor/js/ui/utils.js
index 4f84da8ba..e64a33996 100644
--- a/editor/js/ui/utils.js
+++ b/editor/js/ui/utils.js
@@ -36,6 +36,8 @@ RED.utils = (function() {
result = $('').text('array['+value.length+']');
} else if (value.hasOwnProperty('type') && value.type === 'function') {
result = $('').text('function');
+ } else if (value.hasOwnProperty('type') && value.type === 'number') {
+ result = $('').text(value.data);
} else {
result = $('object');
}
@@ -47,6 +49,8 @@ RED.utils = (function() {
subvalue = sanitize(value);
}
result = $('').html('"'+formatString(subvalue)+'"');
+ } else if (typeof value === 'number') {
+ result = $('').text(""+value);
} else {
result = $('').text(""+value);
}
@@ -300,6 +304,8 @@ RED.utils = (function() {
}
if (obj === null || obj === undefined) {
$(''+obj+'').appendTo(entryObj);
+ } else if (obj.__encoded__ && obj.type === 'number') {
+ e = $('').text(obj.data).appendTo(entryObj);
} else if (typeHint === "function" || (obj.__encoded__ && obj.type === 'function')) {
e = $('').text("function").appendTo(entryObj);
} else if (typeHint === "internal" || (obj.__encoded__ && obj.type === 'internal')) {
@@ -799,6 +805,10 @@ RED.utils = (function() {
function decodeObject(payload,format) {
if ((format === 'number') && (payload === "NaN")) {
payload = Number.NaN;
+ } else if ((format === 'number') && (payload === "Infinity")) {
+ payload = Infinity;
+ } else if ((format === 'number') && (payload === "-Infinity")) {
+ payload = -Infinity;
} else if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number' ) {
payload = JSON.parse(payload);
} else if (/error/i.test(format)) {
diff --git a/red/runtime/util.js b/red/runtime/util.js
index 022faa65d..1d49641df 100644
--- a/red/runtime/util.js
+++ b/red/runtime/util.js
@@ -469,6 +469,14 @@ function encodeObject(msg,opts) {
__encoded__: true,
type: "function"
}
+ } else if (typeof value === 'number') {
+ if (isNaN(value) || value === Infinity || value === -Infinity) {
+ value = {
+ __encoded__: true,
+ type: "number",
+ data: value.toString()
+ }
+ }
} else if (value && value.constructor) {
if (value.type === "Buffer") {
value.__encoded__ = true;