@@ -44,6 +44,12 @@ const SEGMENT = {
4444 FIRST_ARC: 0x03
4545}; */
4646
47+ const ensureBytes = ( buffer , needed ) => {
48+ if ( buffer . position + needed > buffer . length ) {
49+ throw new Error ( `Corrupt or truncated spatial data: expected ${ needed } bytes at position ${ buffer . position } , but only ${ buffer . length - buffer . position } bytes remain` )
50+ }
51+ }
52+
4753class Point {
4854 constructor ( ) {
4955 this . x = 0
@@ -64,6 +70,8 @@ const parsePoints = (buffer, count, isGeometryPoint) => {
6470 return points
6571 }
6672
73+ ensureBytes ( buffer , count * 16 )
74+
6775 if ( isGeometryPoint ) {
6876 // GEOMETRY POINT (s2.1.6): x then y.
6977 for ( let i = 1 ; i <= count ; i ++ ) {
@@ -101,6 +109,8 @@ const parseZ = (buffer, points) => {
101109 return
102110 }
103111
112+ ensureBytes ( buffer , points . length * 8 )
113+
104114 points . forEach ( point => {
105115 point . z = buffer . readDoubleLE ( buffer . position )
106116 buffer . position += 8
@@ -114,6 +124,8 @@ const parseM = (buffer, points) => {
114124 return
115125 }
116126
127+ ensureBytes ( buffer , points . length * 8 )
128+
117129 points . forEach ( point => {
118130 point . m = buffer . readDoubleLE ( buffer . position )
119131 buffer . position += 8
@@ -139,6 +151,8 @@ const parseFigures = (buffer, count, properties) => {
139151 pointOffset : 0
140152 } )
141153 } else {
154+ ensureBytes ( buffer , count * 5 )
155+
142156 for ( let i = 1 ; i <= count ; i ++ ) {
143157 figures . push ( {
144158 attribute : buffer . readUInt8 ( buffer . position ) ,
@@ -173,6 +187,8 @@ const parseShapes = (buffer, count, properties) => {
173187 type : 0x02
174188 } )
175189 } else {
190+ ensureBytes ( buffer , count * 9 )
191+
176192 for ( let i = 1 ; i <= count ; i ++ ) {
177193 shapes . push ( {
178194 parentOffset : buffer . readInt32LE ( buffer . position ) ,
@@ -195,6 +211,8 @@ const parseSegments = (buffer, count) => {
195211 return segments
196212 }
197213
214+ ensureBytes ( buffer , count )
215+
198216 for ( let i = 1 ; i <= count ; i ++ ) {
199217 segments . push ( { type : buffer . readUInt8 ( buffer . position ) } )
200218
@@ -207,6 +225,8 @@ const parseSegments = (buffer, count) => {
207225const parseGeography = ( buffer , isUsingGeometryPoints ) => {
208226 // s2.1.1 + s.2.1.2
209227
228+ ensureBytes ( buffer , 6 )
229+
210230 const srid = buffer . readInt32LE ( 0 )
211231 if ( srid === - 1 ) {
212232 return null
@@ -220,9 +240,6 @@ const parseGeography = (buffer, isUsingGeometryPoints) => {
220240 const flags = buffer . readUInt8 ( 5 )
221241 buffer . position = 6
222242
223- // console.log("srid", srid)
224- // console.log("version", version)
225-
226243 const properties = {
227244 Z : ( flags & ( 1 << 0 ) ) > 0 ,
228245 M : ( flags & ( 1 << 1 ) ) > 0 ,
@@ -232,23 +249,20 @@ const parseGeography = (buffer, isUsingGeometryPoints) => {
232249 }
233250
234251 if ( value . version === 2 ) {
235- properties . H = ( flags & ( 1 << 3 ) ) > 0
252+ properties . H = ( flags & ( 1 << 5 ) ) > 0
236253 }
237254
238- // console.log("properties", properties);
239-
240255 let numberOfPoints
241256 if ( properties . P ) {
242257 numberOfPoints = 1
243258 } else if ( properties . L ) {
244259 numberOfPoints = 2
245260 } else {
261+ ensureBytes ( buffer , 4 )
246262 numberOfPoints = buffer . readUInt32LE ( buffer . position )
247263 buffer . position += 4
248264 }
249265
250- // console.log("numberOfPoints", numberOfPoints)
251-
252266 value . points = parsePoints ( buffer , numberOfPoints , isUsingGeometryPoints )
253267
254268 if ( properties . Z ) {
@@ -259,49 +273,37 @@ const parseGeography = (buffer, isUsingGeometryPoints) => {
259273 parseM ( buffer , value . points )
260274 }
261275
262- // console.log("points", points)
263-
264276 let numberOfFigures
265277 if ( properties . P ) {
266278 numberOfFigures = 1
267279 } else if ( properties . L ) {
268280 numberOfFigures = 1
269281 } else {
282+ ensureBytes ( buffer , 4 )
270283 numberOfFigures = buffer . readUInt32LE ( buffer . position )
271284 buffer . position += 4
272285 }
273286
274- // console.log("numberOfFigures", numberOfFigures)
275-
276287 value . figures = parseFigures ( buffer , numberOfFigures , properties )
277288
278- // console.log("figures", figures)
279-
280289 let numberOfShapes
281290 if ( properties . P ) {
282291 numberOfShapes = 1
283292 } else if ( properties . L ) {
284293 numberOfShapes = 1
285294 } else {
295+ ensureBytes ( buffer , 4 )
286296 numberOfShapes = buffer . readUInt32LE ( buffer . position )
287297 buffer . position += 4
288298 }
289299
290- // console.log("numberOfShapes", numberOfShapes)
291-
292300 value . shapes = parseShapes ( buffer , numberOfShapes , properties )
293301
294- // console.log( "shapes", shapes)
295-
296- if ( value . version === 2 && buffer . position < buffer . length ) {
302+ if ( value . version === 2 && buffer . position + 4 <= buffer . length ) {
297303 const numberOfSegments = buffer . readUInt32LE ( buffer . position )
298304 buffer . position += 4
299305
300- // console.log("numberOfSegments", numberOfSegments)
301-
302306 value . segments = parseSegments ( buffer , numberOfSegments )
303-
304- // console.log("segments", segments)
305307 } else {
306308 value . segments = [ ]
307309 }
0 commit comments