diff --git a/TODO.md b/TODO.md index b9c9222..c84f8f8 100644 --- a/TODO.md +++ b/TODO.md @@ -400,15 +400,15 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis - `edit.php`: raw `SELECT license_id, access_type_id, context_note FROM theses WHERE id = ?` → expose these via `getThesis()` (already returns `v_theses_full` which has `license_id`) - `formulaire.php`: raw identifier-generation query + all junction-table INSERTs → encapsulate in `Database::createThesis(array $data): int` -- [ ] **`sanitize_string()` in `formulaire.php` applies `htmlspecialchars` at write time** — +- [x] **`sanitize_string()` in `formulaire.php` applies `htmlspecialchars` at write time** — HTML-escaping belongs at render time (in the template), not at storage time. Storing `&` or `<` in the DB means search, export, and any non-HTML consumer sees corrupt data. - Remove `htmlspecialchars` from `sanitize_string()`; keep only `trim()`. The templates already + Remove `htmlspecialchars` from `sanitize_string()`; keep only `strip_tags(trim())`. The templates already call `htmlspecialchars()` on output. -- [ ] **Dead variable `$problematique`** — `formulaire.php` line 84 reads `$_POST["problématique"]` +- [x] **Dead variable `$problematique`** — `formulaire.php` line 84 reads `$_POST["problématique"]` into `$problematique` but the value is **never used** (no matching column, no INSERT reference). - Delete it. + Deleted. - [ ] **`setThesisJury()` not wrapped in a transaction** — the method does a DELETE then multiple INSERTs with no transaction guard of its own. If called from outside a transaction (e.g. a diff --git a/public/admin/actions/formulaire.php b/public/admin/actions/formulaire.php index 2c01bac..af09280 100644 --- a/public/admin/actions/formulaire.php +++ b/public/admin/actions/formulaire.php @@ -25,7 +25,9 @@ require_once __DIR__ . '/../../src/Database.php'; // Helper function to sanitize string input function sanitize_string($input) { - return htmlspecialchars(strip_tags(trim($input)), ENT_QUOTES, 'UTF-8'); + // Trim and strip raw HTML tags only — htmlspecialchars belongs at render time, not storage time. + // PDO parameterised queries handle SQL injection; the templates call htmlspecialchars() on output. + return strip_tags(trim($input)); } // Helper function to validate required field @@ -81,7 +83,6 @@ try { $titre = validate_required(sanitize_string($_POST["titre"] ?? ''), "Titre du mémoire"); $subtitle = sanitize_string($_POST["subtitle"] ?? ''); $synopsis = validate_required(sanitize_string($_POST["synopsis"] ?? ''), "Synopsis"); - $problematique = sanitize_string($_POST["problématique"] ?? ''); $durationInfo = sanitize_string($_POST["duration_info"] ?? ''); // Jury members