diff --git a/index.js b/index.js index 1e05689..7caf82a 100644 --- a/index.js +++ b/index.js @@ -41,6 +41,7 @@ function parse(_) { white(); var depth = 0, rings = [], stack = [rings], pointer = rings, elem; + while (elem = $(/^(\()/) || $(/^(\))/) || @@ -49,21 +50,25 @@ function parse(_) { if (elem == '(') { stack.push(pointer); pointer = []; - stack[stack.length-1].push(pointer); + stack[stack.length - 1].push(pointer); depth++; } else if (elem == ')') { pointer = stack.pop(); + // the stack was empty, input was malformed + if (!pointer) return; depth--; - if (depth == 0) break; + if (depth === 0) break; } else if (elem === ',') { pointer = []; - stack[stack.length-1].push(pointer); - } else { + stack[stack.length - 1].push(pointer); + } else if (!isNaN(parseFloat(elem))) { pointer.push(parseFloat(elem)); + } else { + return null; } white(); } - stack.length = 0; + if (depth !== 0) return null; return rings; } @@ -91,6 +96,7 @@ function parse(_) { white(); if (!$(/^(\()/)) return null; var c = coords(); + if (!c) return null; white(); if (!$(/^(\))/)) return null; return { @@ -103,6 +109,7 @@ function parse(_) { if (!$(/^(multipoint)/i)) return null; white(); var c = multicoords(); + if (!c) return null; white(); return { type: 'MultiPoint', @@ -114,6 +121,7 @@ function parse(_) { if (!$(/^(multilinestring)/i)) return null; white(); var c = multicoords(); + if (!c) return null; white(); return { type: 'MultiLineString', @@ -126,6 +134,7 @@ function parse(_) { white(); if (!$(/^(\()/)) return null; var c = coords(); + if (!c) return null; if (!$(/^(\))/)) return null; return { type: 'LineString', diff --git a/package.json b/package.json index 731499b..aaec865 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,8 @@ "devDependencies": { "tape": "~2.4.2", "brfs": "~0.2.1", - "testling": "~1.6.0" + "testling": "~1.6.0", + "fuzzer": "~0.1.0" }, "dependencies": { "concat-stream": "~1.0.1", @@ -46,4 +47,3 @@ "sharkdown": "0.0.1" } } - diff --git a/test/wellknown.test.js b/test/wellknown.test.js index 4b51037..45c639b 100644 --- a/test/wellknown.test.js +++ b/test/wellknown.test.js @@ -1,6 +1,7 @@ var parse = require('../'), -fs = require('fs'), -test = require('tape').test; + fs = require('fs'), + fuzzer = require('fuzzer'), + test = require('tape').test; test('wellknown', function(t) { t.deepEqual(parse('POINT (1 1)'), { @@ -192,3 +193,23 @@ test('wellknown', function(t) { t.end(); }); + +test('fuzz', function(t) { + fuzzer.seed(0); + var inputs = [ + 'MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)), ((15 5, 40 10, 10 20, 5 10, 15 5)))', + 'POINT(1.1 1.1)', + 'LINESTRING (30 10, 10 30, 40 40)', + 'GeometryCollection(POINT(4 6),\nLINESTRING(4 6,7 10))']; + inputs.forEach(function(str) { + for (var i = 0; i < 10000; i++) { + try { + var input = fuzzer.mutate.string(str); + parse(input); + } catch(e) { + t.fail('could not parse ' + input + ', exception ' + e + '\n' + e.stack); + } + } + }); + t.end(); +});