From 71dae7b71ea5b7b37c72a8c6c4bdc10ab03cf952 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Sun, 23 Mar 2014 19:44:30 +0100 Subject: [PATCH 1/8] Add ol.array.safeExtend --- src/ol/array.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/ol/array.js b/src/ol/array.js index 882a501262..9e4ffc1da2 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -37,6 +37,25 @@ ol.array.binaryFindNearest = function(arr, target) { }; +/** + * Safe version of goog.array.extend that does not risk to overflow the stack + * even if `array2` contains a large number of elements. + * + * @param {Array.} array1 Array 1. + * @param {Array.} array2 Array 2. + * @template T + */ +ol.array.safeExtend = function(array1, array2) { + // goog.array.extend uses Array.prototype.push.apply, which can overflow the + // stack if array2 contains too many elements. Repeatedly calling push + // performs as well on modern browsers. + var i, ii; + for (i = 0, ii = array2.length; i < ii; ++i) { + array1.push(array2[i]); + } +}; + + /** * @param {Array.} arr Array. * @param {number} target Target. From de2ee2451e2f8ebc4546971cfd5f365ffbd12044 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Sun, 23 Mar 2014 19:44:55 +0100 Subject: [PATCH 2/8] Use ol.array.safeExtend in ol.geom.LineString --- src/ol/geom/linestring.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ol/geom/linestring.js b/src/ol/geom/linestring.js index 83bed93c14..6dc2319725 100644 --- a/src/ol/geom/linestring.js +++ b/src/ol/geom/linestring.js @@ -2,6 +2,7 @@ goog.provide('ol.geom.LineString'); goog.require('goog.array'); goog.require('goog.asserts'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryType'); goog.require('ol.geom.SimpleGeometry'); @@ -63,7 +64,7 @@ ol.geom.LineString.prototype.appendCoordinate = function(coordinate) { if (goog.isNull(this.flatCoordinates)) { this.flatCoordinates = coordinate.slice(); } else { - goog.array.extend(this.flatCoordinates, coordinate); + ol.array.safeExtend(this.flatCoordinates, coordinate); } this.dispatchChangeEvent(); }; From 765985c5a9492740d3f56c91ee296f6716639055 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Sun, 23 Mar 2014 19:45:02 +0100 Subject: [PATCH 3/8] Use ol.array.safeExtend in ol.geom.MultiLineString --- src/ol/geom/multilinestring.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ol/geom/multilinestring.js b/src/ol/geom/multilinestring.js index a415be1ed2..abe2ca7f5a 100644 --- a/src/ol/geom/multilinestring.js +++ b/src/ol/geom/multilinestring.js @@ -2,6 +2,7 @@ goog.provide('ol.geom.MultiLineString'); goog.require('goog.array'); goog.require('goog.asserts'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryType'); goog.require('ol.geom.LineString'); @@ -57,7 +58,7 @@ ol.geom.MultiLineString.prototype.appendLineString = function(lineString) { if (goog.isNull(this.flatCoordinates)) { this.flatCoordinates = lineString.getFlatCoordinates().slice(); } else { - goog.array.extend( + ol.array.safeExtend( this.flatCoordinates, lineString.getFlatCoordinates().slice()); } this.ends_.push(this.flatCoordinates.length); @@ -202,7 +203,7 @@ ol.geom.MultiLineString.prototype.getFlatMidpoints = function() { var end = ends[i]; var midpoint = ol.geom.flat.interpolate.lineString( flatCoordinates, offset, end, stride, 0.5); - goog.array.extend(midpoints, midpoint); + ol.array.safeExtend(midpoints, midpoint); offset = end; } return midpoints; @@ -293,7 +294,7 @@ ol.geom.MultiLineString.prototype.setLineStrings = function(lineStrings) { // FIXME better handle the case of non-matching layouts goog.asserts.assert(lineString.getLayout() == layout); } - goog.array.extend(flatCoordinates, lineString.getFlatCoordinates()); + ol.array.safeExtend(flatCoordinates, lineString.getFlatCoordinates()); ends.push(flatCoordinates.length); } this.setFlatCoordinates(layout, flatCoordinates, ends); From b9a6048791e697ae8994b0e14a1883b230f9c05c Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Sun, 23 Mar 2014 19:45:12 +0100 Subject: [PATCH 4/8] Use ol.array.safeExtend in ol.geom.MultiPoint --- src/ol/geom/multipoint.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ol/geom/multipoint.js b/src/ol/geom/multipoint.js index 54c7a8e170..19326bd8ed 100644 --- a/src/ol/geom/multipoint.js +++ b/src/ol/geom/multipoint.js @@ -2,6 +2,7 @@ goog.provide('ol.geom.MultiPoint'); goog.require('goog.array'); goog.require('goog.asserts'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryType'); goog.require('ol.geom.Point'); @@ -34,7 +35,7 @@ ol.geom.MultiPoint.prototype.appendPoint = function(point) { if (goog.isNull(this.flatCoordinates)) { this.flatCoordinates = point.getFlatCoordinates().slice(); } else { - goog.array.extend(this.flatCoordinates, point.getFlatCoordinates()); + ol.array.safeExtend(this.flatCoordinates, point.getFlatCoordinates()); } this.dispatchChangeEvent(); }; From c1d37195f5af45c13a0758141239d0e432def9e3 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Sun, 23 Mar 2014 19:45:19 +0100 Subject: [PATCH 5/8] Use ol.array.safeExtend in ol.geom.MultiPolygon --- src/ol/geom/multipolygon.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ol/geom/multipolygon.js b/src/ol/geom/multipolygon.js index bf694bc460..659e1bf12f 100644 --- a/src/ol/geom/multipolygon.js +++ b/src/ol/geom/multipolygon.js @@ -2,6 +2,7 @@ goog.provide('ol.geom.MultiPolygon'); goog.require('goog.array'); goog.require('goog.asserts'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryType'); goog.require('ol.geom.MultiPoint'); @@ -91,7 +92,7 @@ ol.geom.MultiPolygon.prototype.appendPolygon = function(polygon) { this.endss_.push(); } else { var offset = this.flatCoordinates.length; - goog.array.extend(this.flatCoordinates, polygon.getFlatCoordinates()); + ol.array.safeExtend(this.flatCoordinates, polygon.getFlatCoordinates()); ends = polygon.getEnds().slice(); var i, ii; for (i = 0, ii = ends.length; i < ii; ++i) { @@ -373,7 +374,7 @@ ol.geom.MultiPolygon.prototype.setPolygons = function(polygons) { for (j = 0, jj = ends.length; j < jj; ++j) { ends[j] += offset; } - goog.array.extend(flatCoordinates, polygon.getFlatCoordinates()); + ol.array.safeExtend(flatCoordinates, polygon.getFlatCoordinates()); endss.push(ends); } this.setFlatCoordinates(layout, flatCoordinates, endss); From dbc4f4e6214428d10e51c8349bc627d22c92d43d Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Sun, 23 Mar 2014 19:45:28 +0100 Subject: [PATCH 6/8] Use ol.array.safeExtend in ol.geom.Polygon --- src/ol/geom/polygon.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ol/geom/polygon.js b/src/ol/geom/polygon.js index 1ab9f13818..f3694430be 100644 --- a/src/ol/geom/polygon.js +++ b/src/ol/geom/polygon.js @@ -2,6 +2,7 @@ goog.provide('ol.geom.Polygon'); goog.require('goog.array'); goog.require('goog.asserts'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryType'); goog.require('ol.geom.LinearRing'); @@ -85,7 +86,7 @@ ol.geom.Polygon.prototype.appendLinearRing = function(linearRing) { if (goog.isNull(this.flatCoordinates)) { this.flatCoordinates = linearRing.getFlatCoordinates().slice(); } else { - goog.array.extend(this.flatCoordinates, linearRing.getFlatCoordinates()); + ol.array.safeExtend(this.flatCoordinates, linearRing.getFlatCoordinates()); } this.ends_.push(this.flatCoordinates.length); this.dispatchChangeEvent(); From 82b703f3f041a1eecb4359e61cfc7ba88edb3ff2 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Sun, 23 Mar 2014 19:45:41 +0100 Subject: [PATCH 7/8] Use ol.array.safeExtend in ol.format.GML --- src/ol/format/gmlformat.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ol/format/gmlformat.js b/src/ol/format/gmlformat.js index 6c3d3935c5..b98ad70adc 100644 --- a/src/ol/format/gmlformat.js +++ b/src/ol/format/gmlformat.js @@ -7,6 +7,7 @@ goog.require('goog.dom.NodeType'); goog.require('goog.object'); goog.require('goog.string'); goog.require('ol.Feature'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.format.XMLFeature'); goog.require('ol.format.XSD'); @@ -576,7 +577,7 @@ ol.format.GML.readPolygon_ = function(node, objectStack) { var ends = [flatCoordinates.length]; var i, ii; for (i = 1, ii = flatLinearRings.length; i < ii; ++i) { - goog.array.extend(flatCoordinates, flatLinearRings[i]); + ol.array.safeExtend(flatCoordinates, flatLinearRings[i]); ends.push(flatCoordinates.length); } polygon.setFlatCoordinates( @@ -607,7 +608,7 @@ ol.format.GML.readSurface_ = function(node, objectStack) { var ends = [flatCoordinates.length]; var i, ii; for (i = 1, ii = flatLinearRings.length; i < ii; ++i) { - goog.array.extend(flatCoordinates, flatLinearRings[i]); + ol.array.safeExtend(flatCoordinates, flatLinearRings[i]); ends.push(flatCoordinates.length); } polygon.setFlatCoordinates( From 369c20388ee412e522d759bd954a5fae6744e097 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Sun, 23 Mar 2014 19:45:48 +0100 Subject: [PATCH 8/8] Use ol.array.safeExtend in ol.format.KML --- src/ol/format/kmlformat.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ol/format/kmlformat.js b/src/ol/format/kmlformat.js index 6e049f3416..4c2deba5c7 100644 --- a/src/ol/format/kmlformat.js +++ b/src/ol/format/kmlformat.js @@ -12,6 +12,7 @@ goog.require('goog.math'); goog.require('goog.object'); goog.require('goog.string'); goog.require('ol.Feature'); +goog.require('ol.array'); goog.require('ol.feature'); goog.require('ol.format.XMLFeature'); goog.require('ol.format.XSD'); @@ -762,7 +763,7 @@ ol.format.KML.readMultiGeometry_ = function(node, objectStack) { geometry = geometries[i]; goog.asserts.assertInstanceof(geometry, ol.geom.Point); goog.asserts.assert(geometry.getLayout() == layout); - goog.array.extend(flatCoordinates, geometry.getFlatCoordinates()); + ol.array.safeExtend(flatCoordinates, geometry.getFlatCoordinates()); } var multiPoint = new ol.geom.MultiPoint(null); multiPoint.setFlatCoordinates(layout, flatCoordinates); @@ -828,7 +829,7 @@ ol.format.KML.readPolygon_ = function(node, objectStack) { var ends = [flatCoordinates.length]; var i, ii; for (i = 1, ii = flatLinearRings.length; i < ii; ++i) { - goog.array.extend(flatCoordinates, flatLinearRings[i]); + ol.array.safeExtend(flatCoordinates, flatLinearRings[i]); ends.push(flatCoordinates.length); } polygon.setFlatCoordinates(