fix sonarqube findings
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
# SonarQube-Auswertung vom 3. Oktober 2026
|
||||||
|
|
||||||
|
Basis: Export `Wegwichtel-sonarqube-export(17).json`, Repository `cf4170f`.
|
||||||
|
Von 119 exportierten Issues sind fünf offen; die übrigen sind bereits geschlossen.
|
||||||
|
|
||||||
|
## Code-Korrekturen
|
||||||
|
|
||||||
|
- `javascript:S7773`, `public/js/local-routes.js`: beide globalen `NaN` durch
|
||||||
|
`Number.NaN` ersetzt. Fehlende Positionen bleiben weiterhin ungültige Zahlen
|
||||||
|
und werden als GPS-Lücken gespeichert.
|
||||||
|
- `javascript:S3358`, `src/services/gpx.js`: Auswahl der Punkte für die
|
||||||
|
Metrikberechnung in eine eigene Variable ausgelagert. Keine verschachtelte
|
||||||
|
bedingte Operation mehr; die bisherigen Fälle bleiben erhalten.
|
||||||
|
- `javascript:S1481`, `src/services/gpx.js`: die beiden unbenutzten Variablen
|
||||||
|
`_oldWaypoints` und `_oldPending` entfernt. Alte Wegpunkte und unvollständige
|
||||||
|
Stationen werden gezielt entfernt, bevor die aktuelle Stationsliste entsteht.
|
||||||
|
Andere Erweiterungen bleiben erhalten.
|
||||||
|
|
||||||
|
Das bereits korrigierte Moderationsskript bleibt unverändert.
|
||||||
|
|
||||||
|
## Security-Hotspot mit notwendiger Bewertung in SonarQube
|
||||||
|
|
||||||
|
- Schlüssel: `7854386c-ec53-4e14-b374-d7d356accf23`
|
||||||
|
- Datei: `src/services/gpx.js`
|
||||||
|
- Regel: `javascript:S5332`
|
||||||
|
- Meldung: Verwendung des HTTP-Protokolls
|
||||||
|
- Empfohlene Bewertung nach Prüfung: **Safe**
|
||||||
|
|
||||||
|
Begründung zum Einfügen in SonarQube:
|
||||||
|
|
||||||
|
> Die Zeichenfolge `http://www.topografix.com/GPX/1/1` ist der offizielle
|
||||||
|
> XML-Namespace von GPX 1.1. Die Funktion schreibt sie als xmlns-Attribut in die
|
||||||
|
> erzeugte GPX-Datei. Sie stellt keine HTTP-Verbindung her und überträgt keine
|
||||||
|
> Daten an diese Adresse. Ein Wechsel zu https würde einen anderen Namespace
|
||||||
|
> erzeugen und die GPX-Kompatibilität beeinträchtigen. Daher besteht an dieser
|
||||||
|
> Stelle kein unverschlüsselter Datentransport.
|
||||||
|
|
||||||
|
Offizielle Referenz: https://www.topografix.com/GPX/1/1/
|
||||||
|
|
||||||
|
Der gleiche Namespace in `public/js/local-routes.js` wurde laut Export bereits
|
||||||
|
als **Safe** bewertet. Der neue Hotspot ist weiterhin **TO_REVIEW**; ein
|
||||||
|
Code-Kommentar oder dieses Dokument ändert seinen Status in SonarQube nicht.
|
||||||
|
Es wurden keine Regeln deaktiviert und keine Findings per Suppression verborgen.
|
||||||
|
|
||||||
|
## Quality Gate laut Export
|
||||||
|
|
||||||
|
- Neue Coverage: 87,8 %, bestanden (mindestens 80 %).
|
||||||
|
- Neue Duplikate: rund 0,35 %, bestanden (höchstens 3 %).
|
||||||
|
- Neue offene Findings: fünf, durch die Code-Korrekturen adressiert.
|
||||||
|
- Geprüfte Security-Hotspots: 50 %, noch nicht bestanden (erforderlich 100 %).
|
||||||
|
|
||||||
|
Die abschließende Bewertung des Quality Gates benötigt einen neuen Scan und
|
||||||
|
die Bewertung des genannten Hotspots in SonarQube.
|
||||||
@@ -409,8 +409,8 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {};
|
|||||||
}
|
}
|
||||||
|
|
||||||
function appendPosition(document, position, routeName) {
|
function appendPosition(document, position, routeName) {
|
||||||
const lat = position.lat == null ? NaN : Number(position.lat);
|
const lat = position.lat == null ? Number.NaN : Number(position.lat);
|
||||||
const lon = position.lon == null ? NaN : Number(position.lon);
|
const lon = position.lon == null ? Number.NaN : Number(position.lon);
|
||||||
const timestamp = new Date(position.timestamp ?? Date.now()).toISOString();
|
const timestamp = new Date(position.timestamp ?? Date.now()).toISOString();
|
||||||
if (!Number.isFinite(lat) || !Number.isFinite(lon) || Math.abs(lat) > 90 || Math.abs(lon) > 180) {
|
if (!Number.isFinite(lat) || !Number.isFinite(lon) || Math.abs(lat) > 90 || Math.abs(lon) > 180) {
|
||||||
const root = document.documentElement;
|
const root = document.documentElement;
|
||||||
|
|||||||
+8
-3
@@ -52,7 +52,8 @@ export function parseGpx(xml, replacementPoints = null) {
|
|||||||
const points = replacementPoints ?? (routed.length ? routed : simplifyTrack(recorded));
|
const points = replacementPoints ?? (routed.length ? routed : simplifyTrack(recorded));
|
||||||
const waypoints = validPoints(asList(gpx.wpt));
|
const waypoints = validPoints(asList(gpx.wpt));
|
||||||
if (!points.length && !waypoints.length && !gpx.extensions?.['wegwichtel:gpsGap'] && !gpx.extensions?.['wegwichtel:pendingWaypoint']) throw new HttpError(400, 'Die GPX-Datei enthält keine verwertbaren Punkte.');
|
if (!points.length && !waypoints.length && !gpx.extensions?.['wegwichtel:gpsGap'] && !gpx.extensions?.['wegwichtel:pendingWaypoint']) throw new HttpError(400, 'Die GPX-Datei enthält keine verwertbaren Punkte.');
|
||||||
const metrics = points.length || waypoints.length ? routeMetrics(points.length ? points : waypoints) : {
|
const metricPoints = points.length ? points : waypoints;
|
||||||
|
const metrics = metricPoints.length ? routeMetrics(metricPoints) : {
|
||||||
startLat: null, startLon: null, centerLat: null, centerLon: null,
|
startLat: null, startLon: null, centerLat: null, centerLon: null,
|
||||||
minLat: null, minLon: null, maxLat: null, maxLon: null,
|
minLat: null, minLon: null, maxLat: null, maxLon: null,
|
||||||
distanceM: 0, elevationGainM: 0, pointCount: 0
|
distanceM: 0, elevationGainM: 0, pointCount: 0
|
||||||
@@ -63,6 +64,8 @@ export function parseGpx(xml, replacementPoints = null) {
|
|||||||
delete gpx.rte;
|
delete gpx.rte;
|
||||||
// GPX 1.1 order: metadata, waypoints, route, extensions.
|
// GPX 1.1 order: metadata, waypoints, route, extensions.
|
||||||
const { extensions, ...base } = gpx;
|
const { extensions, ...base } = gpx;
|
||||||
|
// GPX 1.1 namespace identifier: this URI is written into XML, never fetched.
|
||||||
|
// Its exact spelling is part of the GPX standard; HTTPS would be another namespace.
|
||||||
const normalized = { ...base, '@_version': '1.1', '@_creator': 'Wegwichtel', '@_xmlns': 'http://www.topografix.com/GPX/1/1' };
|
const normalized = { ...base, '@_version': '1.1', '@_creator': 'Wegwichtel', '@_xmlns': 'http://www.topografix.com/GPX/1/1' };
|
||||||
if (points.length) normalized.rte = { ...(name ? { name } : {}), rtept: points.map(point => ({
|
if (points.length) normalized.rte = { ...(name ? { name } : {}), rtept: points.map(point => ({
|
||||||
'@_lat': point.lat, '@_lon': point.lon,
|
'@_lat': point.lat, '@_lon': point.lon,
|
||||||
@@ -75,13 +78,15 @@ export function parseGpx(xml, replacementPoints = null) {
|
|||||||
|
|
||||||
export function gpxWithWaypoints(xml, pois) {
|
export function gpxWithWaypoints(xml, pois) {
|
||||||
const gpx = parseXml(xml).gpx;
|
const gpx = parseXml(xml).gpx;
|
||||||
const { wpt: _oldWaypoints, rte, trk, extensions = {}, ...base } = gpx;
|
delete gpx.wpt;
|
||||||
|
const { rte, trk, extensions = {}, ...base } = gpx;
|
||||||
const waypoint = poi => ({ '@_lat': poi.lat, '@_lon': poi.lon, name: poi.title,
|
const waypoint = poi => ({ '@_lat': poi.lat, '@_lon': poi.lon, name: poi.title,
|
||||||
...(poi.description ? { desc: poi.description } : {}),
|
...(poi.description ? { desc: poi.description } : {}),
|
||||||
extensions: { 'wegwichtel:poiId': poi.id } });
|
extensions: { 'wegwichtel:poiId': poi.id } });
|
||||||
const located = pois.filter(poi => Number.isFinite(poi.lat) && Number.isFinite(poi.lon));
|
const located = pois.filter(poi => Number.isFinite(poi.lat) && Number.isFinite(poi.lon));
|
||||||
const pending = pois.filter(poi => !Number.isFinite(poi.lat) || !Number.isFinite(poi.lon));
|
const pending = pois.filter(poi => !Number.isFinite(poi.lat) || !Number.isFinite(poi.lon));
|
||||||
const { 'wegwichtel:pendingWaypoint': _oldPending, ...extra } = extensions;
|
const extra = { ...extensions };
|
||||||
|
delete extra['wegwichtel:pendingWaypoint'];
|
||||||
if (pending.length) extra['wegwichtel:pendingWaypoint'] = pending.map(poi => ({ name: poi.title,
|
if (pending.length) extra['wegwichtel:pendingWaypoint'] = pending.map(poi => ({ name: poi.title,
|
||||||
...(poi.description ? { desc: poi.description } : {}), extensions: { 'wegwichtel:poiId': poi.id } }));
|
...(poi.description ? { desc: poi.description } : {}), extensions: { 'wegwichtel:poiId': poi.id } }));
|
||||||
const normalized = { ...base, '@_xmlns:wegwichtel': 'urn:wegwichtel:poi',
|
const normalized = { ...base, '@_xmlns:wegwichtel': 'urn:wegwichtel:poi',
|
||||||
|
|||||||
Reference in New Issue
Block a user