mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
fix(share): reject inherited style keys during restore
This commit is contained in:
1 parent
de2138e84c
commit
d49877ad2e
6 files changed
+50
-2
No files matched your search
@@ -1,5 +1,10 @@
|
||||
# God's Eye View Current State
|
||||
|
||||
Share links and structured views accept only own keys in their style registries.
|
||||
Inherited names such as `constructor` and `__proto__` fall back to the existing
|
||||
normal/null defaults without interrupting other restored fields. Programmatic
|
||||
visual-style calls ignore unknown or non-string values before mutating state.
|
||||
|
||||
Shared distance checks use `src/geoDistance.js` with `{ lat, lon }` points and
|
||||
the IUGG mean spherical Earth radius, 6371.0088 km. `greatCircleKm` is
|
||||
canonical; `greatCircleMeters` is its exact metre conversion. Missing,
|
||||
|
||||
@@ -778,3 +778,20 @@ test('visual input listeners are revoked before asynchronous UI teardown', () =>
|
||||
assert.match(VisualSettings.prototype.stop.toString(), /this\._styleParameters\?\.destroy\(\)/);
|
||||
assert.match(VisualSettings.prototype.stop.toString(), /this\._visualEffects\.stop\(\)/);
|
||||
});
|
||||
|
||||
|
||||
test('share restore rejects inherited styles while continuing later fields', () => {
|
||||
for (const style of ['constructor', '__proto__', 'toString', 'hasOwnProperty', 'unknown']) {
|
||||
const restored = makeManager(`#lat=10&lon=20&style=${style}&cr=1`).parseInitialHash();
|
||||
assert.equal(restored.style, 'normal');
|
||||
assert.equal(restored.celestialRing, true);
|
||||
}
|
||||
});
|
||||
|
||||
test('programmatic invalid styles are ignored before changing visual state', () => {
|
||||
const target = { activeStyle: 'normal' };
|
||||
for (const value of ['constructor', '__proto__', 'toString', 'hasOwnProperty', 'unknown', {}, null, () => {}]) {
|
||||
assert.doesNotThrow(() => VisualSettings.prototype.setStyle.call(target, value));
|
||||
assert.equal(target.activeStyle, 'normal');
|
||||
}
|
||||
});
|
||||
+3
-1
@@ -175,7 +175,9 @@ export class ShareLinkManager {
|
||||
parseOr(params.get('dd'), 50),
|
||||
50,
|
||||
);
|
||||
const style = URL_TO_STYLE[params.get('style')] || 'normal';
|
||||
const style = Object.hasOwn(URL_TO_STYLE, params.get('style'))
|
||||
? URL_TO_STYLE[params.get('style')]
|
||||
: 'normal';
|
||||
const decodedLayerState = decodeLayerStateParams(params);
|
||||
const state = {
|
||||
lat,
|
||||
|
||||
@@ -1539,6 +1539,11 @@ export class VisualSettings {
|
||||
preserveCyberRestore = false,
|
||||
} = {},
|
||||
) {
|
||||
if (
|
||||
typeof styleName !== 'string' ||
|
||||
(styleName !== 'normal' && !Object.hasOwn(STYLES, styleName))
|
||||
)
|
||||
return;
|
||||
const { setDetectionStyle } = this.services;
|
||||
if (!restore) this.shareLinkManager?.claimRestoreLane?.('visual');
|
||||
if (this.hud.getVariant() === 'cyber') {
|
||||
|
||||
+3
-1
@@ -370,7 +370,9 @@ export function viewFromParams(params) {
|
||||
pitch_deg: number('pitch'),
|
||||
},
|
||||
layers: state?.enabledLayerIds ?? [],
|
||||
style: STYLES_BY_URL_NAME[params.get('style')] ?? null,
|
||||
style: Object.hasOwn(STYLES_BY_URL_NAME, params.get('style'))
|
||||
? STYLES_BY_URL_NAME[params.get('style')]
|
||||
: null,
|
||||
map: VIEW_MAPS.includes(map) ? map : null,
|
||||
follow,
|
||||
annotations: annotationsFromParams(params),
|
||||
|
||||
@@ -126,3 +126,20 @@ test('annotations travel in the link, keeping only what the app draws', async ()
|
||||
// Too long for a link: the view keeps them, the link leaves them out.
|
||||
assert.equal(viewToParams(many).has('an'), false);
|
||||
});
|
||||
|
||||
test('inherited and unknown style keys do not corrupt a restored view', () => {
|
||||
for (const style of [
|
||||
'constructor',
|
||||
'__proto__',
|
||||
'toString',
|
||||
'hasOwnProperty',
|
||||
'unknown',
|
||||
]) {
|
||||
const view = viewFromParams(
|
||||
new URLSearchParams({ lat: '10', lon: '20', style, map: 'osm' }),
|
||||
);
|
||||
assert.equal(view.style, null);
|
||||
assert.equal(view.map, 'osm');
|
||||
assert.equal(view.camera.lat, 10);
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user