fix sonarqube findings
Sonarqube Scanner / Prepare environment (push) Successful in 7s
Sonarqube Scanner / Build and test (push) Successful in 24s
Sonarqube Scanner / SonarQube analysis (push) Successful in 1m12s
Sonarqube Scanner / Deploy to Server (push) Successful in 6s

This commit is contained in:
Florian Zumpe
2026-10-03 12:59:58 +02:00
parent cf4170f590
commit edfe227641
3 changed files with 63 additions and 5 deletions
+53
View File
@@ -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.
+2 -2
View File
@@ -409,8 +409,8 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {};
}
function appendPosition(document, position, routeName) {
const lat = position.lat == null ? NaN : Number(position.lat);
const lon = position.lon == null ? NaN : Number(position.lon);
const lat = position.lat == null ? Number.NaN : Number(position.lat);
const lon = position.lon == null ? Number.NaN : Number(position.lon);
const timestamp = new Date(position.timestamp ?? Date.now()).toISOString();
if (!Number.isFinite(lat) || !Number.isFinite(lon) || Math.abs(lat) > 90 || Math.abs(lon) > 180) {
const root = document.documentElement;
+8 -3
View File
@@ -52,7 +52,8 @@ export function parseGpx(xml, replacementPoints = null) {
const points = replacementPoints ?? (routed.length ? routed : simplifyTrack(recorded));
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.');
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,
minLat: null, minLon: null, maxLat: null, maxLon: null,
distanceM: 0, elevationGainM: 0, pointCount: 0
@@ -63,6 +64,8 @@ export function parseGpx(xml, replacementPoints = null) {
delete gpx.rte;
// GPX 1.1 order: metadata, waypoints, route, extensions.
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' };
if (points.length) normalized.rte = { ...(name ? { name } : {}), rtept: points.map(point => ({
'@_lat': point.lat, '@_lon': point.lon,
@@ -75,13 +78,15 @@ export function parseGpx(xml, replacementPoints = null) {
export function gpxWithWaypoints(xml, pois) {
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,
...(poi.description ? { desc: poi.description } : {}),
extensions: { 'wegwichtel:poiId': poi.id } });
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 { 'wegwichtel:pendingWaypoint': _oldPending, ...extra } = extensions;
const extra = { ...extensions };
delete extra['wegwichtel:pendingWaypoint'];
if (pending.length) extra['wegwichtel:pendingWaypoint'] = pending.map(poi => ({ name: poi.title,
...(poi.description ? { desc: poi.description } : {}), extensions: { 'wegwichtel:poiId': poi.id } }));
const normalized = { ...base, '@_xmlns:wegwichtel': 'urn:wegwichtel:poi',