mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
fix(imagery): refuse blank box edges at every conversion
Share-link integers and Cesium radians were converted before normalizeBox
checked them, so a blank edge still became 0°. Edges are now accepted only as
numbers or non-blank numeric strings, which also refuses [] and {}. Tests cover
all four edges through validateBox, dequantizeBox, boxFromRectangle and
searchHls.
This commit is contained in:
1 parent
9c9c80a7ed
commit
6ffbf7f524
3 files changed
+57
-18
No files matched your search
@@ -1,6 +1,13 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { validateBox, boxCentre } from './model.js';
|
||||
import {
|
||||
boxCentre,
|
||||
boxFromRectangle,
|
||||
dequantizeBox,
|
||||
validateBox,
|
||||
} from './model.js';
|
||||
import { searchHls } from './catalog.js';
|
||||
|
||||
test('missing imagery edges do not turn into invented zero coordinates', () => {
|
||||
for (const value of [null, undefined, '', ' ', false, true]) {
|
||||
const box = { west: value, south: 0, east: 1, north: 1 };
|
||||
@@ -14,3 +21,28 @@ test('missing imagery edges do not turn into invented zero coordinates', () => {
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
test('every edge and every box entry point refuses a missing edge', async () => {
|
||||
const blanks = [null, undefined, '', ' ', false, [], {}];
|
||||
for (const edge of ['west', 'south', 'east', 'north']) {
|
||||
for (const value of blanks) {
|
||||
const box = { west: 1, south: 1, east: 2, north: 2, [edge]: value };
|
||||
assert.equal(validateBox(box).ok, false, `${edge}=${String(value)}`);
|
||||
// Share-link integers and Cesium radians are converted per edge.
|
||||
assert.equal(dequantizeBox(box), null, `share ${edge}`);
|
||||
assert.equal(boxFromRectangle(box), null, `radians ${edge}`);
|
||||
}
|
||||
}
|
||||
let fetched = false;
|
||||
await assert.rejects(
|
||||
searchHls({
|
||||
box: { west: ' ', south: 1, east: 2, north: 2 },
|
||||
fetchImpl: async () => {
|
||||
fetched = true;
|
||||
},
|
||||
}),
|
||||
TypeError,
|
||||
);
|
||||
assert.equal(fetched, false);
|
||||
assert.ok(dequantizeBox({ west: 0, south: 0, east: 100000, north: 100000 }));
|
||||
});
|
||||
@@ -75,20 +75,23 @@ const pad2 = (value) => String(value).padStart(2, '0');
|
||||
* east are not swapped: west > east crosses the dateline and `validateBox`
|
||||
* rejects it. Null when any edge is nonfinite.
|
||||
*/
|
||||
/** A box edge as a number, or null when it is missing, blank or not numeric. */
|
||||
function edgeNumber(value) {
|
||||
if (typeof value === 'number') return Number.isFinite(value) ? value : null;
|
||||
if (typeof value !== 'string' || !value.trim()) return null;
|
||||
const number = Number(value);
|
||||
return Number.isFinite(number) ? number : null;
|
||||
}
|
||||
|
||||
function normalizeBox(box) {
|
||||
if (!box || typeof box !== 'object') return null;
|
||||
const edges = [box.west, box.south, box.east, box.north];
|
||||
if (
|
||||
edges.some(
|
||||
(value) =>
|
||||
value == null ||
|
||||
typeof value === 'boolean' ||
|
||||
(typeof value === 'string' && !value.trim()),
|
||||
)
|
||||
)
|
||||
return null;
|
||||
const [west, south, east, north] = edges.map(Number);
|
||||
if (![west, south, east, north].every(Number.isFinite)) return null;
|
||||
const [west, south, east, north] = [
|
||||
box.west,
|
||||
box.south,
|
||||
box.east,
|
||||
box.north,
|
||||
].map(edgeNumber);
|
||||
if ([west, south, east, north].some((edge) => edge == null)) return null;
|
||||
return {
|
||||
west,
|
||||
south: Math.min(south, north),
|
||||
@@ -216,11 +219,16 @@ export function boxFromPin(lon, lat, sideKm = PIN_BOX_SIDE_KM) {
|
||||
|
||||
function mapBox(box, fn) {
|
||||
if (!box || typeof box !== 'object') return null;
|
||||
// Converting first would turn a blank edge into 0 before normalizeBox sees it.
|
||||
const edge = (value) => {
|
||||
const number = edgeNumber(value);
|
||||
return number == null ? null : fn(number);
|
||||
};
|
||||
return normalizeBox({
|
||||
west: fn(box.west),
|
||||
south: fn(box.south),
|
||||
east: fn(box.east),
|
||||
north: fn(box.north),
|
||||
west: edge(box.west),
|
||||
south: edge(box.south),
|
||||
east: edge(box.east),
|
||||
north: edge(box.north),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user