Merge pull request #1022 from rudycelekli/contrib/gods-001-coordinate-empty-components-20261011-reviewed

fix(search): refuse empty coordinate components instead of silently dropping them
This commit is contained in:
Sameh Khamis authored and GitHub committed 2026-10-14 11:27:26 -07:00
commit 5209421973
4 files changed
+18 -2

No files matched your search

+2
View File
@@ -1,5 +1,7 @@
# Changelog
- Coordinate searches refuse empty latitude or longitude components instead of navigating to an unintended location.
- Bing Aerial and Bing Labels request HTTPS tiles on HTTP localhost through
their ion-backed providers, retaining ion and per-tile attribution without
widening the Content Security Policy.
+2
View File
@@ -4320,6 +4320,8 @@ and unreachable upstream (502/504) separately from road geometry.
### Place-search providers
Coordinate input requires exactly two nonempty components; extra comma or semicolon separators decline to geocoding rather than silently choosing a location.
Location search/fly-to, annotations and Radio location lookup receive one
`placeSearch.geocode(query, { bias, signal })` service. `src/standalone` composes
two offline providers first — a strict decimal-degree coordinate reader and an
@@ -0,0 +1,12 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { parseCoordinateQuery } from './coordinateParser.js';
test('search refuses omitted components and repeated separators', () => {
for (const q of ['30,, -97', ',30,-97', '30,-97,', '30;; -97', '30,; -97'])
assert.equal(parseCoordinateQuery(q), null, q);
for (const q of ['30,-97', '30; -97', '30 -97', 'N 30, W 97'])
assert.deepEqual(
[parseCoordinateQuery(q).lat, parseCoordinateQuery(q).lon],
[30, -97],
);
});
+2 -2
View File
@@ -49,8 +49,8 @@ function splitComponents(query) {
const parts = /[,;]/.test(text)
? text.split(/[,;]/)
: text.split(/\s+(?=[+-]?[.\d]|[NSEW]\s*[+-]?[.\d])/i);
const trimmed = parts.map((part) => part.trim()).filter(Boolean);
return trimmed.length === 2 ? trimmed : null;
const trimmed = parts.map((part) => part.trim());
return trimmed.length === 2 && trimmed.every(Boolean) ? trimmed : null;
}
/** Present a parsed pair the way a coordinate is normally written. */