Skip to content

Commit dc5bebd

Browse files
author
Peter Rushforth
committed
Add code+test to ensure that TemplatedFeaturesOrTilesLayer.js does not
allow dynamic content loaded by a <map-link rel=features> to contain a map-extent
1 parent 24ed56f commit dc5bebd

File tree

4 files changed

+133
-1
lines changed

4 files changed

+133
-1
lines changed

src/mapml/layers/TemplatedFeaturesOrTilesLayer.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,17 @@ export var TemplatedFeaturesOrTilesLayer = LayerGroup.extend({
207207
let parser = new DOMParser();
208208
mapml = parser.parseFromString(text, 'application/xml');
209209
let frag = document.createDocumentFragment();
210-
let elements = mapml.querySelectorAll('map-head > *, map-body > *');
210+
const legalContentQuery = `
211+
map-head > map-link,
212+
map-body > map-link,
213+
map-head > map-meta,
214+
map-body > map-meta,
215+
map-head > map-style,
216+
map-body > map-style,
217+
map-tile,
218+
map-feature
219+
`.trim(); // excludes map-extent
220+
let elements = mapml.querySelectorAll(legalContentQuery);
211221
for (let i = 0; i < elements.length; i++) {
212222
frag.appendChild(elements[i]);
213223
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<mapml- xmlns="http://www.w3.org/1999/xhtml">
2+
<map-head>
3+
<map-title>map-feature, map-tile, map-extent</map-title>
4+
<map-meta name="projection" content="CBMTILE"></map-meta>
5+
</map-head>
6+
<map-body>
7+
<!-- this SHOULD appear in the shadow root of the <map-layer> AND shadow root of <map-link> -->
8+
<map-feature data-testid="pcrsgeometry" >
9+
<map-properties>
10+
<h1>Test</h1>
11+
</map-properties>
12+
<map-geometry cs="pcrs">
13+
<map-polygon>
14+
<map-coordinates>257421 -3567196 -271745 1221771 -3896544 242811 -3183549 -2613313</map-coordinates>
15+
</map-polygon>
16+
</map-geometry>
17+
</map-feature>
18+
<!-- this SHOULD appear in the shadow root of the <map-layer> AND shadow root of <map-link> -->
19+
<map-feature data-testid="tcrsgeometry" >
20+
<map-properties>
21+
<h1>Test</h1>
22+
</map-properties>
23+
<map-geometry cs="tcrs">
24+
<map-polygon>
25+
<map-coordinates>2771 3106 2946 3113 2954 3210 2815 3192</map-coordinates>
26+
</map-polygon>
27+
</map-geometry>
28+
</map-feature>
29+
<!-- this SHOULD appear in the shadow root of the <map-layer> AND shadow root of <map-link> -->
30+
<map-feature data-testid="tilematrixgeometry" >
31+
<map-properties>
32+
<h1>Test Cube</h1>
33+
</map-properties>
34+
<map-geometry cs="tilematrix">
35+
<map-polygon>
36+
<map-coordinates>11 11 12 11 12 12 11 12</map-coordinates>
37+
</map-polygon>
38+
</map-geometry>
39+
</map-feature>
40+
<!-- this SHOULD appear in the shadow root of the <map-layer> AND shadow root of <map-link> -->
41+
<map-feature data-testid="defaultcsgeometry" >
42+
<map-properties>
43+
<h1>Alabama</h1>
44+
</map-properties>
45+
<map-geometry>
46+
<map-polygon>
47+
<map-coordinates>-87.359296 35.00118 -85.606675 34.984749 -85.431413 34.124869 -85.184951 32.859696 -85.069935 32.580372 -84.960397 32.421541 -85.004212 32.322956 -84.889196 32.262709 -85.058981 32.13674 -85.053504 32.01077 -85.141136 31.840985 -85.042551 31.539753 -85.113751 31.27686 -85.004212 31.003013 -85.497137 30.997536 -87.600282 30.997536 -87.633143 30.86609 -87.408589 30.674397 -87.446927 30.510088 -87.37025 30.427934 -87.518128 30.280057 -87.655051 30.247195 -87.90699 30.411504 -87.934375 30.657966 -88.011052 30.685351 -88.10416 30.499135 -88.137022 30.318396 -88.394438 30.367688 -88.471115 31.895754 -88.241084 33.796253 -88.098683 34.891641 -88.202745 34.995703 -87.359296 35.00118</map-coordinates>
48+
</map-polygon>
49+
</map-geometry>
50+
</map-feature>
51+
52+
<!-- this SHOULD appear in the shadow root of the <map-layer> AND shadow root of <map-link> -->
53+
<map-tile data-testid="test-tile" zoom="0" row="3" col="3" src="data/cbmt/0/c3_r3.png"></map-tile>
54+
55+
<!-- this SHOULD appear in the shadow root of the <map-layer> AND SHOULD NOT appear in shadow root of <map-link> -->
56+
<map-extent data-test-id="test-extent" units="CBMTILE" checked="checked" >
57+
<map-input name="z" type="zoom" min="0" max="18" value="0" ></map-input>
58+
<map-input name="xmin" type="location" units="gcrs" axis="longitude" position="top-left" min="-76" max="-74" ></map-input>
59+
<map-input name="ymin" type="location" units="gcrs" axis="latitude" position="bottom-right" min="45" max="46" ></map-input>
60+
<map-input name="xmax" type="location" units="gcrs" axis="longitude" position="bottom-right" min="-76" max="-74" ></map-input>
61+
<map-input name="ymax" type="location" units="gcrs" axis="latitude" position="top-left" min="45" max="46" ></map-input>
62+
<!-- refers to itself, actually, so could cause "STACK OVERFLOW" if included -->
63+
<!-- in any case, the shadow root of the map-link SHOULD NOT contain this map-extent, or this link -->
64+
<map-link data-testid="test-link" rel="features" tref="./features-tiles-extents.mapml?{xmin}{ymin}{xmax}{ymax}{z}" ></map-link>
65+
</map-extent>
66+
67+
68+
</map-body>
69+
</mapml->
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<title>templatedFeaturesOrTiles.html</title>
5+
<meta charset="UTF-8">
6+
<script type="module" src="mapml.js"></script>
7+
</head>
8+
<body>
9+
<mapml-viewer data-testid="map" style="width: 500px;height: 500px;" projection="CBMTILE" zoom="0" lat="45.5052040" lon="-75.2202344" controls>
10+
<!-- This layer "includes itself" (via a map-extent/map-link rel=features)
11+
While the shadow root of the map-layer should contain the map-extent,
12+
tests should confirm that the <map-link rel=features> shadow root does not
13+
contain the map-extent again (It's bad enough that the author points
14+
the layer to itself to recursively load (some of) the same content, but
15+
that shouldn't be a "show stopper" / blow the stack / recurse forever). -->
16+
<map-layer data-testid="test-layer" checked src="data/features-tiles-extents.mapml"></map-layer>
17+
</mapml-viewer>
18+
</body>
19+
</html>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { test, expect, chromium } from '@playwright/test';
2+
3+
test.describe('Tests to confirm that content cannot be recursively loaded', () => {
4+
let page;
5+
let context;
6+
test.beforeAll(async () => {
7+
context = await chromium.launchPersistentContext('', { slowMo: 250 });
8+
page = await context.newPage();
9+
await page.goto('templatedFeaturesOrTiles.html');
10+
});
11+
12+
test.afterAll(async function () {
13+
await context.close();
14+
});
15+
test('Contents of features-tiles-extents.mapml copied to map-layer shadow root', async () => {
16+
await page.waitForTimeout(500);
17+
const layer = page.getByTestId('test-layer');
18+
const featuresTilesAndExtentCopied = await layer.evaluate(
19+
(l) =>
20+
l.shadowRoot.querySelectorAll('map-feature, map-tile, map-extent')
21+
.length === 6
22+
);
23+
expect(featuresTilesAndExtentCopied).toBe(true);
24+
});
25+
test('Contents of features-tiles-extents.mapml SELECTIVELY copied to map-link shadow root', async () => {
26+
const mapLinks = await page.getByTestId('test-link').all();
27+
expect(mapLinks.length).toBe(1);
28+
const mapLink = page.getByTestId('test-link');
29+
const featuresAndTilesCopied = await mapLink.evaluate(
30+
(l) => l.shadowRoot.querySelectorAll('map-feature, map-tile').length === 5
31+
);
32+
expect(featuresAndTilesCopied).toBe(true);
33+
});
34+
});

0 commit comments

Comments
 (0)