Termine auf Prepared Statements umgebaut

Kalender, Terminliste, Terminformular und Terminzettel laufen ueber
db_abfrage() mit Platzhaltern; das Anlegen einer mehrtaegigen Terminreihe
liegt in einer Transaktion. Die Logik steckt jetzt in incs/termin.php,
sites/termin*.php rufen sie nur noch auf.

Dabei behoben:
- SQL-Injektion ueber die Suchbegriffe der Terminliste, ueber die
  Mehrfachauswahl (Ankreuzfelder del<N>/erl<N> gingen roh in DELETE bzw.
  UPDATE), ueber die Wiedervorlage-Tage (INTERVAL $folgedays DAY) und ueber
  ?action=terminshow&id=... in maketerminarray(), maketerminadresse(),
  maketelnrn() und makegooglestring()
- gespeichertes XSS: Beschreibung, Notiz, Termintyp, Ort, Kundenname und
  Mitarbeiterfarbe im Kalender, in der Terminliste und im Formular
- "or $err=error(...)" stand innerhalb des Abfrage-Strings, dadurch wurden
  die Nebenzeilen einer Terminreihe beim Loeschen nie entfernt
- die Abfrage zum Folgetermin las eine Spalte typ_id, die es in termin nicht
  gibt; Typ und Wiedervorlage fehlten deshalb beim Bearbeiten
- ein Folgetermin wurde mit termtime='' und termdauer='' angelegt, ein
  Termin ohne Folgetermin mit followed_by='' - im strikten Modus Fehler
- ein Termin ohne Datum landete auf dem 01.01.1970 und gab dabei
  "NICHTTERMINIERT!!" mitten in die Seite aus
- die Ueberschneidungspruefung verglich ab dem zweiten Tag gegen das Ende
  des ersten Tages
- eine unbekannte Registerkarte der Terminliste ergab ein leeres WHERE und
  damit einen SQL-Fehler; jetzt gilt die Standardansicht
- terminshow.php pruefte den Typ mit = statt ==
- der Kalender haengt nicht mehr an der Locale de_DE (strftime)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-22 00:04:38 +02:00
co-authored by Claude Opus 5
parent 3dfbf1c9c7
commit 490c4f12a4
12 changed files with 986 additions and 950 deletions
+3 -3
View File
@@ -5,7 +5,7 @@
{/if}
<h2>Termin für Kunde Nummer:</h2>
<span class='big'>{$kunde.partner_id}</span><br />
{$kunde.vname} {$kunde.nname} {$kunde.firma}<br />{$kunde.str} {$kunde.hnr}<br />{$kunde.plz} {$kunde.ort}
{$kunde.vname|escape} {$kunde.nname|escape} {$kunde.firma|escape}<br />{$kunde.str|escape} {$kunde.hnr|escape}<br />{$kunde.plz|escape} {$kunde.ort|escape}
{/if}
{if $user}
{$termin.user = $user}
@@ -45,10 +45,10 @@
</select><br />
{/if}
<label>Beschreibung:</label>
<input name='head' id='head' maxlength='100' value='{$termin.head}' />
<input name='head' id='head' maxlength='100' value='{$termin.head|escape}' />
<br />
<label kundeclass='artlabel'>Notizen:</label>
<textarea class='bigtextarea' id='text' name='text'>{$termin.text}</textarea><p>
<textarea class='bigtextarea' id='text' name='text'>{$termin.text|escape}</textarea><p>
<label class='checktext'><input type="checkbox" id='done' name="done" value="1" {if $termin.done == 1}checked="checked"{/if} />Termin ist erledigt</label>
</p>
<br />