Compare commits

...
4 Commits
Author SHA1 Message Date
adminandClaude Opus 5 37270acb23 .htaccess: Git-Verzeichnis auch ohne mod_rewrite und mod_alias sperren
Die Regel gegen Punkt-Pfade stand ausschliesslich in IfModule-Bloecken fuer
mod_rewrite und mod_alias. Ist keines der beiden geladen, entfaellt sie
ersatzlos und ohne Fehlermeldung, und .git waere wieder abrufbar - genau das
Fail-Open, das derselbe Commit-Satz bei restricted/.htaccess beseitigen
sollte.

Ergaenzt um eine Notbremse aus Kern-Direktiven, die immer verfuegbar sind:
FilesMatch auf die Einstiegsdateien eines Git-Verzeichnisses (HEAD, config,
index, packed-refs und weitere) sowie pack und idx in der Typenliste. Ohne
diese Dateien laesst sich das Verzeichnis nicht aufrollen, weil die
Objektdateien hexadezimale Namen tragen.

FilesMatch passt nur auf Dateinamen, nicht auf Pfadbestandteile, und kann
.git deshalb nicht vollstaendig sperren. Der Kommentar in der Datei sagt das
und benennt die belastbare Loesung: .git und restricted/ ausserhalb des
Dokumentenbaums legen.

Gegengeprueft: von den 40 Adressen, die die Seiten laden, faellt keine unter
die neuen Regeln; in .git greifen sie zusaetzlich fuer 13 Dateien.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:16:26 +02:00
adminandClaude Opus 5 f17d010d5f fillElementArray(): auch den Wert-Cache verwerfen
Die Funktion soll laut eigener Beschreibung den Zwischenspeicher verwerfen,
falls das SVG neu gezeichnet wird, leerte aber nur svgElements. letzterWert
blieb gefuellt, sodass setText, setAttr und setDisplay jeden Schreibzugriff
danach als "unveraendert" ueberspringen: die Knoten werden zwar neu
nachgeschlagen, aber nie beschrieben. Das frische SVG behaelt dann seine
Platzhalter, bis sich der jeweilige Messwert zufaellig aendert - bei den
Boegen mit auf volle Grad gerundeten Winkeln kann das dauern.

Nachgestellt: nach dem Verwerfen nur der Knoten bleibt die Anzeige auf "--",
mit geleertem letzterWert wird wieder geschrieben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:15:24 +02:00
adminandClaude Opus 5 405162ed47 setFlowWidth(): negative Breite bedeutet kein Fluss, nicht Fluss rueckwaerts
Die Funktion bildete die uebergebene Breite mit Math.abs() ab. Die Aufrufer
rechnen 55*(1-exp(x)); kehrt sich das Vorzeichen der Messgroesse um, wird der
Ausdruck negativ. Frueher setzte das eine negative stroke-width und die Linie
blieb leer. Mit Math.abs() erschien stattdessen eine Animation voller Staerke
in unveraenderter Laufrichtung - das Diagramm zeigte einen Fluss, den es nicht
gab.

Beispiel: speist die EG-Etage mit 900 W zurueck, ergibt 55*(1-exp(900/2000))
den Wert -31,3. Math.abs machte daraus eine 31,3 breite laufende Linie, jetzt
sind es 0 und die Linie ruht.

Positive Breiten und die Schwelle von 0,5 bleiben unveraendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:14:54 +02:00
adminandClaude Opus 5 dc85f33e9f ipInNetwork(): Praefixlaenge pruefen statt ungeprueft uebernehmen
Die Laenge wurde mit intval() aus dem CIDR-String uebernommen. Bei einem
Tippfehler in LOCAL_NETWORKS lief die Funktion damit fail-open: "/-5" ergibt
intdiv(-5,8)=0 ganze Bytes und chr((0xFF << 13) & 0xFF)=Nullbyte, womit beide
maskierten Bytes gleich sind und jede Adresse in jedem Netz liegt. isLocal()
haette dann jede Anfrage aus dem Internet als lokal gewertet - und damit als
angemeldet, inklusive Freigabe der Passkey-Registrierung.

Die Laenge muss jetzt aus reinen Ziffern bestehen und darf die Adressbreite
nicht ueberschreiten; sonst liefert die Funktion false. "/-5", "/244", "/abc"
und "/" fallen damit durch, gueltige Angaben bleiben unveraendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:14:25 +02:00
3 changed files with 51 additions and 5 deletions
+22 -1
View File
@@ -20,7 +20,28 @@
# --- Dateitypen, die der Browser nie anfordert ---
# Konfiguration, Python-Skripte, Datenhaltung, Vorlagen und Archive. Die
# Seite laedt ausschliesslich .php, .css, .js, Bilder und Schriften.
<FilesMatch "\.(ini|py|pyc|json|md|log|bak|example|sql|sqlite|db|tgz|gz|zip|yml|yaml)$">
<FilesMatch "\.(ini|py|pyc|json|md|log|bak|example|sql|sqlite|db|tgz|gz|zip|yml|yaml|pack|idx)$">
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order allow,deny
Deny from all
</IfModule>
</FilesMatch>
# --- Notbremse ohne Modulabhaengigkeit ---
# Die Punkt-Regel oben braucht mod_rewrite oder mod_alias. Fehlen beide, faellt
# sie ersatzlos und ohne Fehlermeldung aus - und .git waere wieder abrufbar.
# FilesMatch gehoert zum Kern und ist immer verfuegbar. Es passt allerdings nur
# auf Dateinamen, nicht auf Pfadbestandteile, kann .git also nicht vollstaendig
# sperren. Es nimmt den ueblichen Auslesewerkzeugen aber den Einstieg: ohne
# HEAD, config, index und packed-refs laesst sich das Verzeichnis nicht
# aufrollen, weil die Objektdateien hexadezimale Namen tragen.
#
# Belastbar waere nur, .git und restricted/ ausserhalb des Dokumentenbaums zu
# legen. Diese Regeln sind Schadensbegrenzung, keine Grenze.
<FilesMatch "^(HEAD|ORIG_HEAD|FETCH_HEAD|MERGE_HEAD|COMMIT_EDITMSG|config|index|packed-refs|description|shallow|gitattributes|gitignore|gitmodules)$">
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
+14 -1
View File
@@ -20,7 +20,20 @@ function ipInNetwork($ip, $cidr)
if ($adresse === false || $netz === false || strlen($adresse) !== strlen($netz)) {
return false; // ungueltig oder verschiedene Adressfamilien
}
$bits = isset($teile[1]) ? intval($teile[1]) : strlen($adresse) * 8;
// Praefixlaenge streng pruefen. Ohne das macht ein Tippfehler in
// LOCAL_NETWORKS die Funktion fail-open: "/-5" etwa liefert eine
// Nullmaske, und dann liegt jede Adresse in jedem Netz.
if (isset($teile[1])) {
if (!ctype_digit($teile[1])) {
return false;
}
$bits = intval($teile[1]);
if ($bits > strlen($adresse) * 8) {
return false;
}
} else {
$bits = strlen($adresse) * 8;
}
$ganzeBytes = intdiv($bits, 8);
$restBits = $bits % 8;
if ($ganzeBytes > 0 && strncmp($adresse, $netz, $ganzeBytes) !== 0) {
+15 -3
View File
@@ -126,17 +126,29 @@ function setDisplay(id, wert) { schreibe("d:" + id, wert, s => { svgElement(i
// eine eigene Compositor-Ebene an, und die kostet Speicher.
function setFlowWidth(id, width) {
const flow = svgElement(id);
const sichtbar = Math.abs(width) >= 0.5;
flow.style.setProperty("--w", (sichtbar ? Math.abs(width) : 0) + "px");
// Eine negative Breite heisst "kein Fluss in dieser Richtung" - die
// Aufrufer rechnen 55*(1-exp(x)), was bei umgekehrtem Vorzeichen negativ
// wird. Frueher zeichnete eine negative stroke-width schlicht nichts.
// Math.max haelt das bei; Math.abs wuerde stattdessen einen Fluss in der
// falschen Richtung mit voller Staerke anzeigen.
const breite = Math.max(0, width);
const sichtbar = breite >= 0.5;
flow.style.setProperty("--w", breite + "px");
flow.style.animationPlayState = sichtbar ? "running" : "paused";
flow.style.willChange = sichtbar ? "transform" : "auto";
}
const solarSVG = {
updateCnt: 99,
/** Cache verwerfen - noetig, falls das SVG neu gezeichnet wird. */
/**
* Beide Zwischenspeicher verwerfen - noetig, falls das SVG neu gezeichnet
* wird. Nur die Knoten zu vergessen reicht nicht: letzterWert wuerde dann
* jeden Schreibzugriff als "unveraendert" ueberspringen und das frische
* SVG behielte seine Platzhalter.
*/
fillElementArray: function () {
for (const id in svgElements) delete svgElements[id];
letzterWert.clear();
},
updateValuesMQTT: function (mqttData) {