" --------------------------------- $maliciousTitle = 'Vidéo test'; $videoData = [ 'thumbnailPath' => '/static/thumbnails/test.jpg', ]; $video = [ 'id' => '9c5de94d-8e1a-4b3c-9d2e-1234567890ab', 'title' => $maliciousTitle, 'description' => 'Une description', 'duration' => 120, 'channel' => 'Chaîne ', 'views' => 42, 'date' => '2024-01-15 10:00:00', 'tags' => ['test'], ]; $jsonLd = generateVideoObjectJsonLd($videoData, $video); assertNotContains('', $jsonLd, 'generateVideoObjectJsonLd ne reproduit pas "" en clair'); // L'équivalent encodé de "" (séquences \u00XX via JSON_HEX_TAG) // doit apparaître à la place de la balise en clair $encodedClosingTag = trim(json_encode('', JSON_UNESCAPED_SLASHES | JSON_HEX_TAG), '"'); assertContains( $encodedClosingTag, $jsonLd, 'generateVideoObjectJsonLd encode "<" et ">" en séquences unicode (JSON_HEX_TAG)' ); $decoded = json_decode($jsonLd, true); assertTrue(is_array($decoded), 'Le JSON-LD VideoObject reste un JSON valide'); assertEquals( $maliciousTitle, $decoded['name'], 'Le titre malveillant est préservé à l\'identique après décodage JSON' ); // Les autres générateurs JSON-LD bénéficient des mêmes drapeaux d'encodage $websiteLd = generateWebSiteJsonLd(); assertNotContains('', $websiteLd, 'generateWebSiteJsonLd ne contient pas ""'); assertTrue(json_decode($websiteLd, true) !== null, 'generateWebSiteJsonLd produit un JSON valide'); $breadcrumbLd = generateBreadcrumbJsonLd([ ['name' => 'Accueil', 'url' => 'https://test.local'], ['name' => 'Page ', 'url' => 'https://test.local/page'], ]); assertNotContains('', $breadcrumbLd, 'generateBreadcrumbJsonLd neutralise "" dans un nom de fil d\'Ariane'); $collectionLd = generateVideoCollectionJsonLd('Collection ', 'Description', [$video], 'https://test.local/col'); assertNotContains('', $collectionLd, 'generateVideoCollectionJsonLd neutralise "" dans le nom de collection'); $podcastLd = generatePodcastJsonLd([ [ 'title' => 'Épisode ', 'link' => 'https://podcast.example/ep1', 'pubDate' => '2024-01-01', ], ]); assertNotContains('', $podcastLd, 'generatePodcastJsonLd neutralise "" dans un titre d\'épisode'); assertTrue(json_decode($podcastLd, true) !== null, 'generatePodcastJsonLd produit un JSON valide'); // --- isValidAppHostName ------------------------------------------------------- assertTrue(isValidAppHostName('example.com'), 'isValidAppHostName accepte un nom de domaine'); assertTrue(isValidAppHostName('test.local'), 'isValidAppHostName accepte un domaine local'); assertTrue(isValidAppHostName('localhost'), 'isValidAppHostName accepte localhost'); assertTrue(isValidAppHostName('127.0.0.1:8080'), 'isValidAppHostName accepte une IPv4 avec port'); assertTrue(isValidAppHostName('sub.example-site.com'), 'isValidAppHostName accepte sous-domaines et tirets'); assertFalse(isValidAppHostName(''), 'isValidAppHostName refuse une chaîne vide'); assertFalse(isValidAppHostName('evil.com">'; $_SERVER['HTTPS'] = 'on'; assertEquals( 'https://' . APP_HOST_NAME, getBaseUrl(), 'getBaseUrl utilise APP_HOST_NAME et ignore un HTTP_HOST malveillant' ); assertNotContains('evil.example', getBaseUrl(), 'getBaseUrl ne reflète pas l\'en-tête Host'); assertEquals(APP_HOST_NAME, getAppHostName(), 'getAppHostName retourne APP_HOST_NAME validé'); unset($_SERVER['HTTPS']); assertEquals('http://' . APP_HOST_NAME, getBaseUrl(), 'getBaseUrl retombe en http sans HTTPS'); // --- getCurrentUrl : REQUEST_URI assaini -------------------------------------- $_SERVER['REQUEST_URI'] = '/video.php?id=abc">'; $currentUrl = getCurrentUrl(); assertNotContains('"', $currentUrl, 'getCurrentUrl supprime les guillemets de REQUEST_URI'); assertNotContains('<', $currentUrl, 'getCurrentUrl supprime les chevrons de REQUEST_URI'); assertNotContains(' ', $currentUrl, 'getCurrentUrl supprime les espaces de REQUEST_URI'); assertEquals( 0, strpos($currentUrl, 'http://' . APP_HOST_NAME . '/video.php?id=abc'), 'getCurrentUrl préfixe par l\'hôte validé et conserve le chemin' ); $_SERVER['REQUEST_URI'] = 'sans-slash-initial'; assertEquals( 'http://' . APP_HOST_NAME . '/sans-slash-initial', getCurrentUrl(), 'getCurrentUrl ajoute le slash initial manquant' ); // Nettoyage des superglobales modifiées pour ne pas impacter d'autres tests unset($_SERVER['HTTPS']); $_SERVER['HTTP_HOST'] = APP_HOST_NAME; $_SERVER['REQUEST_URI'] = '/';