on master help sign in
Disallow non-integer numbers to be passed to Int ports

Adds additonal checks performed when accepting a value to an incoming port of type Int. The check is based on a polyfill for Number.isInteger, documented at [1]. NaN and infinite values are handled correctly. [1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger

commit3b5542df6883fe671241a68d8ce840320d2c35b5 authorJan Dudek <jd@jandudek.com> dateSat 14 Nov 2015, 00:38 (11 years ago) parent433e20c
3 files changed+14−4
src/Generate/JavaScript/Port.hs+10−1 tests/test-files/good-expected-js/Declarations/Ports.elm.js+3−2 tests/test-files/good/Declarations/Ports.elm+1−1
src/Generate/JavaScript/Port.hs+10−1
@@ -27,6 +27,7 @@ task name expr portType =
2727
2828data JSType
2929 = JSNumber
30+ | JSIntNumber
3031 | JSBoolean
3132 | JSString
3233 | JSArray
@@ -37,6 +38,7 @@ typeToString :: JSType -> String
3738typeToString tipe =
3839 case tipe of
3940 JSNumber -> "a number"
41+ JSIntNumber -> "an integer"
4042 JSBoolean -> "a boolean (true or false)"
4143 JSString -> "a string"
4244 JSArray -> "an array"
@@ -82,12 +84,19 @@ check x jsType continue =
8284 checks =
8385 case jsType of
8486 JSNumber -> [typeof "number"]
87+ JSIntNumber ->
88+ [jsFold OpLAnd (typeof "number" : intChecks)]
8589 JSBoolean -> [typeof "boolean"]
8690 JSString -> [typeof "string", instanceof "String"]
8791 JSArray -> [instanceof "Array"]
8892 JSObject fields ->
8993 [jsFold OpLAnd (typeof "object" : map member fields)]
9094
95+ intChecks =
96+ [ \x -> (ref "isFinite") `call` [x]
97+ , \x -> equal (obj ["Math","floor"] `call` [x]) x
98+ ]
99+
91100
92101-- INBOUND
93102
@@ -127,8 +136,8 @@ toType tipe x =
127136 toType (T.dealias args t) x
128137
129138 T.Type (Var.Canonical Var.BuiltIn name)
130− | name == "Int" -> from JSNumber
131139 | name == "Float" -> from JSNumber
140+ | name == "Int" -> from JSIntNumber
132141 | name == "Bool" -> from JSBoolean
133142 | name == "String" -> from JSString
134143 where
tests/test-files/good-expected-js/Declarations/Ports.elm.js+3−2
@@ -31,7 +31,7 @@ Elm.Main.make = function (_elm) {
3131 v.y)} : _U.badPort("an object with fields `x`, `y`",v);
3232 });
3333 var array = Elm.Native.Port.make(_elm).inbound("array",
34− "List Int",
34+ "List Float",
3535 function (v) {
3636 return typeof v === "object" && v instanceof Array ? Elm.Native.List.make(_elm).fromArray(v.map(function (v) {
3737 return typeof v === "number" ? v : _U.badPort("a number",v);
@@ -49,7 +49,8 @@ Elm.Main.make = function (_elm) {
4949 var number = Elm.Native.Port.make(_elm).inbound("number",
5050 "Int",
5151 function (v) {
52− return typeof v === "number" ? v : _U.badPort("a number",v);
52+ return typeof v === "number" && isFinite(v) && Math.floor(v) === v ? v : _U.badPort("an integer",
53+ v);
5354 });
5455 var userID = Elm.Native.Port.make(_elm).inbound("userID",
5556 "String",
tests/test-files/good/Declarations/Ports.elm+1−1
@@ -3,7 +3,7 @@
33port userID : String
44port number : Int
55port tuple : (Float,Bool)
6−port array : List Int
6+port array : List Float
77port record : { x:Float, y:Float }
88
99-- outgoing