@@ -205,3 +205,46 @@ test('https://github.com/mapbox/vector-tile-js/issues/60', () => {
205205 }
206206 }
207207} ) ;
208+
209+ test ( 'does not mutate prototypes via a "__proto__" layer name or property key' , ( ) => {
210+ // Hand-build a minimal MVT tile containing a layer named "__proto__"
211+ // with one feature whose properties include a "__proto__" key.
212+ const pbf = new Protobuf ( ) ;
213+
214+ pbf . writeMessage ( 3 , ( _ , p ) => { // Tile.layers
215+ p . writeVarintField ( 15 , 2 ) ; // version
216+ p . writeStringField ( 1 , '__proto__' ) ; // name
217+ p . writeMessage ( 2 , ( _ , p ) => { // feature
218+ p . writeVarintField ( 1 , 1 ) ; // id
219+ p . writePackedVarint ( 2 , [ 0 , 0 ] ) ; // tags: key[0] -> value[0]
220+ p . writeVarintField ( 3 , 1 ) ; // type = POINT
221+ p . writePackedVarint ( 4 , [ 9 , 0 , 0 ] ) ; // geometry: moveTo(0,0)
222+ } , null ) ;
223+ p . writeStringField ( 3 , '__proto__' ) ; // keys[0]
224+ p . writeMessage ( 4 , ( _ , p ) => { // values[0]
225+ p . writeStringField ( 1 , 'evil' ) ;
226+ } , null ) ;
227+ p . writeVarintField ( 5 , 4096 ) ; // extent
228+ } , null ) ;
229+
230+ const tile = new VectorTile ( new Protobuf ( pbf . finish ( ) ) ) ;
231+
232+ // tile.layers must keep a null prototype — i.e. its prototype wasn't
233+ // hijacked by `layers["__proto__"] = layer`.
234+ assert . equal ( Object . getPrototypeOf ( tile . layers ) , null ) ;
235+
236+ // The "__proto__" layer is still reachable as an own property.
237+ // eslint-disable-next-line no-proto, dot-notation
238+ const layer = tile . layers [ '__proto__' ] ;
239+ assert . ok ( layer instanceof VectorTileLayer ) ;
240+ assert . equal ( layer . name , '__proto__' ) ;
241+
242+ // Feature.properties must also keep a null prototype.
243+ const feature = layer . feature ( 0 ) ;
244+ assert . equal ( Object . getPrototypeOf ( feature . properties ) , null ) ;
245+ // eslint-disable-next-line no-proto, dot-notation
246+ assert . equal ( feature . properties [ '__proto__' ] , 'evil' ) ;
247+
248+ // Sanity: a fresh {} elsewhere is untouched (no global pollution either).
249+ assert . equal ( ( { } ) . evil , undefined ) ;
250+ } ) ;
0 commit comments