# Correctif FluxMaster de Mediabunny 1.61.3

Fichier généré par `tools/vendor-mediabunny.mjs`. Ne pas le modifier à la main.

## Ce qui est retiré, et pourquoi

Mediabunny sait lire des contenus chiffrés quand on lui fournit les clés : segments HLS chiffrés en AES-128, échantillons MP4 et fMP4 chiffrés en CENC (AES-CTR) ou en cbcs, playlists HLS en SAMPLE-AES. FluxMaster refuse tous ces contenus et ne demande jamais de clé. Une règle du projet va plus loin : **aucun code de déchiffrement dans l'extension, même inatteignable** : ce qui n'est pas dans le paquet ne peut ni servir, ni être réactivé (PLAN.md, arbitrage 17).

Cette copie est donc privée de :

- tout le module AES-128 logiciel (tables, déchiffrement CBC, flux de déchiffrement des segments) ;
- les deux appels WebCrypto de la bibliothèque (import de la clé et déchiffrement AES-CTR) ;
- le déchiffrement des échantillons CENC et cbcs, et le cache des clés ;
- l'option qui permettait à l'appelant de fournir les clés, et son interception côté HLS ;
- la lecture des lignes de clé HLS (URI de clé, IV, données pssh) et le calcul de l'IV ;
- les outils qui ne servaient qu'aux clés et n'avaient plus d'usage : conversion hexadécimale des clés, formats de l'IV et des données de clé HLS, comparaison des boîtes pssh, groupe de cache des fichiers de clé ;
- le marquage des pistes Matroska chiffrées, remplacé par un refus explicite ;
- la lecture des paramètres de chiffrement des pistes et des échantillons MP4 (identifiant de clé par défaut, IV, découpage en sous-échantillons, contenu des boîtes pssh), et les champs qui les gardaient : les boîtes qui les portent lèvent désormais l'erreur de refus dès qu'elles sont lues.

## Comportement de cette copie

| Entrée | Résultat |
|---|---|
| Playlist HLS avec une ligne `#EXT-X-KEY` de méthode autre que `NONE` | Erreur « FluxMaster : contenu chiffré non pris en charge » dès la lecture de la playlist, avant toute requête de segment ou de clé |
| Playlist principale avec une ligne `#EXT-X-SESSION-KEY` de méthode autre que `NONE` | Même erreur (Mediabunny d'origine ignorait cette ligne) |
| MP4 ou fMP4 (fichier, segment d'initialisation ou segment HLS) qui contient une boîte `schm`, `tenc`, `pssh` ou `senc`, quel que soit le schéma (cenc, cens, cbc1, cbcs ou inconnu) | Même erreur dès que la boîte est lue, en général à la lecture des pistes : les métadonnées d'un fichier chiffré ne sont pas lisibles non plus |
| Matroska ou WebM dont une piste déclare un élément `ContentEncryption` | Même erreur dès la lecture des pistes (Mediabunny d'origine écartait la piste en silence) |
| Option de fourniture des clés passée par l'appelant | Ignorée |
| Contenu en clair | Inchangé : le chemin de lecture des segments et des échantillons en clair est repris à l'identique |

Ce qui reste, volontairement :

- la **reconnaissance** des boîtes qui décrivent un chiffrement : `schm`, `tenc`, `pssh` et `senc` lèvent l'erreur de refus dès qu'elles sont rencontrées, sans qu'aucun de leurs champs ne soit lu ; `saiz` et `saio`, boîtes génériques, sont ignorées ; `frma` (format d'origine, rangé dans `sinf` avant `schm`) ne sert qu'à nommer le codec ;
- MPEG-TS : Mediabunny lit les bits `transport_scrambling_control` sans les interpréter (un segment brouillé n'est pas déchiffré, il est lu tel quel). Le moteur de FluxMaster contrôle ces bits sur chaque segment avant l'assemblage (PLAN.md §5.2) ;
- en amont, `shared/box-scan.js` de FluxMaster refuse tout fichier ou segment d'initialisation qui contient `encv`, `enca`, `sinf`, `schm`, `tenc` ou `pssh`, quel que soit le schéma, et tout Matroska ou WebM chiffré (PLAN.md §5.1).

Défense en profondeur prévue par le plan : FluxMaster refuse les flux chiffrés avant même d'appeler Mediabunny (politique de refus, PLAN.md §5.1), et ne lui donne qu'une playlist locale écrite par son propre code, sans aucune ligne de clé. Cette copie modifiée est le dernier rempart, pas le seul.

## Correctif de mémoire (jalon M3)

Une seule étape ne touche pas au déchiffrement : P31. Elle réduit la mémoire retenue pendant l'assemblage d'un flux MPEG-TS à haut débit (condition G0 de l'essai M1 : moins de 400 Mo dans le document offscreen). Elle ne change ni les paquets lus ni leur ordre : seule la copie gardée comme point de référence pour la recherche perd ses octets, qui n'y étaient jamais relus.

## Étapes du correctif

| Étape | Objet | Zone (source d'origine) | Effet |
|---|---|---|---|
| P01 | Mention de modification | en-tête du fichier | Ajoute, sous l'en-tête MPL-2.0 d'origine (conservé tel quel), un bloc qui signale la modification et renvoie à PATCH.md et SOURCE.md. |
| P02 | Retrait du module AES-128 logiciel | src/aes.ts | Supprime tout le module : tables AES, contexte de déchiffrement CBC et flux de déchiffrement des segments HLS. Il est remplacé par la seule constante du message d'erreur de refus. |
| P03 | Retrait du cache des clés | src/isobmff/isobmff-demuxer.ts, constructeur | Supprime la table qui gardait les clés de déchiffrement déjà obtenues. |
| P04 | Refus des échantillons chiffrés (MP4 non fragmenté) | src/isobmff/isobmff-demuxer.ts, lecture d'un échantillon (table des échantillons) | Si la piste porte des informations de chiffrement, la lecture d'un échantillon lève l'erreur de refus au lieu de le déchiffrer. La lecture « métadonnées seules » n'est pas touchée. |
| P05 | Refus des échantillons chiffrés (MP4 fragmenté) | src/isobmff/isobmff-demuxer.ts, lecture d'un échantillon (fragment) | Même refus pour les échantillons lus dans un fragment (fMP4, segments HLS en fMP4). |
| P06 | Retrait du déchiffrement CENC et cbcs | src/isobmff/isobmff-demuxer.ts, fonctions de déchiffrement | Supprime la résolution des clés par le rappel de l'appelant, le déchiffrement CTR par WebCrypto, le déchiffrement cbcs par le module AES logiciel et le calcul des plages chiffrées. |
| P07 | Retrait du calcul de l'IV AES-128 | src/hls/hls-segmented-input.ts, segments de la playlist | Supprime le calcul du vecteur d'initialisation à partir du numéro de séquence. La clé d'un segment est toujours nulle, puisque toute ligne de clé est refusée (P09). |
| P08 | Retrait du contrôle d'IV avant #EXT-X-MAP | src/hls/hls-segmented-input.ts, #EXT-X-MAP | Supprime un contrôle qui n'avait de sens que pour un segment d'initialisation chiffré. |
| P09 | Refus de toute clé HLS | src/hls/hls-segmented-input.ts, #EXT-X-KEY | Une ligne #EXT-X-KEY de méthode NONE est acceptée ; toute autre méthode (AES-128, SAMPLE-AES, SAMPLE-AES-CTR ou inconnue) lève l'erreur de refus dès la lecture de la playlist, avant toute requête de segment. L'URI de la clé n'est jamais lue. |
| P10 | Retrait de l'interception des clés | src/hls/hls-segmented-input.ts, options passées à chaque segment | Supprime l'enveloppe qui ajoutait les données de clé de la playlist (pssh) au rappel de résolution des clés. Les options de format sont transmises telles quelles. |
| P11 | Retrait du déchiffrement des segments AES-128 | src/hls/hls-segmented-input.ts, lecture d'un segment | Supprime la branche qui téléchargeait la clé et déchiffrait le segment. Un segment marqué chiffré lève l'erreur de refus (cas déjà écarté par P09, garde gardée par prudence) ; le chemin des segments en clair est repris à l'identique. |
| P12 | Retrait du contrôle SAMPLE-AES | src/hls/hls-segmented-input.ts, format d'un segment | Supprime un contrôle qui ne servait qu'au déchiffrement SAMPLE-AES des segments ISOBMFF. |
| P13 | Retrait de l'option de résolution des clés | src/input-format.ts, validation des options | Supprime la validation de l'option qui permettait à l'appelant de fournir les clés. Si elle est passée, elle n'est plus lue. |
| P14 | Ajout de l'étiquette #EXT-X-SESSION-KEY | src/hls/hls-misc.ts, étiquettes | Déclare l'étiquette de clé de session, utilisée par P15. |
| P15 | Refus de toute clé de session HLS | src/hls/hls-demuxer.ts, playlist principale | Une ligne #EXT-X-SESSION-KEY de la playlist principale dont la méthode n'est pas NONE lève l'erreur de refus (Mediabunny d'origine l'ignorait). |
| P16 | Refus de toute boîte senc | src/isobmff/isobmff-demuxer.ts, boîte senc | La boîte senc (informations de chiffrement de chaque échantillon) lève l'erreur de refus dès qu'elle est lue, dans un MP4 non fragmenté comme dans un fragment, sans rien en extraire. Mediabunny d'origine y lisait l'IV et le découpage en sous-échantillons de chaque échantillon chiffré, et s'arrêtait sur un échec d'assertion sans message hors d'un fragment (MP4 chiffré non fragmenté écrit par ffmpeg). |
| P17 | Retrait de la conversion hexadécimale des clés | src/misc.ts, outils hexadécimaux | Supprime l'expression régulière et la fonction qui convertissaient en octets une clé fournie en hexadécimal par l'appelant. Elles ne servaient qu'au déchiffrement retiré (P06) et n'avaient plus aucun usage. |
| P18 | Retrait des formats de clé HLS | src/hls/hls-segmented-input.ts, constantes | Supprime les deux expressions régulières qui lisaient l'IV et les données de clé (URI data:) d'une ligne #EXT-X-KEY. Elles n'avaient plus d'usage depuis P09. |
| P19 | Retrait de la comparaison des boîtes pssh | src/isobmff/isobmff-misc.ts, boîtes pssh | Supprime la fonction qui comparait deux boîtes pssh pour les transmettre au rappel de résolution des clés. Elle n'avait plus d'usage depuis P10. |
| P20 | Retrait du groupe de cache des clés | src/input.ts, groupes du cache des sources | Supprime le numéro de groupe qui rangeait à part, dans le cache des sources, les fichiers de clé téléchargés. Il n'avait plus d'usage depuis P11. |
| P21 | Refus explicite des pistes Matroska et WebM chiffrées | src/matroska/matroska-demuxer.ts, élément ContentEncryption | Une piste Matroska ou WebM qui déclare un élément ContentEncryption lève l'erreur de refus dès la lecture des pistes. Mediabunny d'origine marquait la piste comme chiffrée, puis l'écartait en silence. |
| P22 | Refus de tout schéma de chiffrement MP4 | src/isobmff/isobmff-demuxer.ts, boîte schm | Une boîte schm (schéma de protection d'une piste, rangée dans sinf) lève l'erreur de refus dès la lecture des pistes, quel que soit le schéma : cenc, cens, cbc1, cbcs ou inconnu. Mediabunny d'origine gardait les paramètres de chiffrement des schémas qu'il reconnaît, et se contentait d'un avertissement pour les autres. Les métadonnées d'un fichier chiffré ne sont donc plus lisibles non plus. |
| P23 | Refus de toute boîte tenc | src/isobmff/isobmff-demuxer.ts, boîte tenc | La boîte tenc (paramètres de chiffrement par défaut d'une piste) lève l'erreur de refus dès qu'elle est lue. Mediabunny d'origine y lisait l'identifiant de clé par défaut, la taille de l'IV, l'IV constant et le motif de chiffrement. |
| P24 | Informations auxiliaires des échantillons jamais lues | src/isobmff/isobmff-demuxer.ts, boîtes saiz et saio | Les boîtes saiz et saio ne sont plus lues. Dans une piste chiffrée, elles situent l'IV et les sous-échantillons de chaque échantillon ; cette piste est déjà refusée par P16, P22 et P23. Ce sont des boîtes génériques : ailleurs, elles sont simplement ignorées, comme le faisait déjà Mediabunny d'origine pour une piste en clair. |
| P25 | Refus de toute boîte pssh | src/isobmff/isobmff-demuxer.ts, boîte pssh | La boîte pssh (données d'un système de protection) lève l'erreur de refus dès qu'elle est lue, sans rien en extraire. Mediabunny d'origine en tirait l'identifiant du système, les identifiants de clé et les données, gardés pour le rappel de résolution des clés retiré par P06. |
| P26 | Retrait de la lecture des boîtes pssh | src/isobmff/isobmff-misc.ts, boîtes pssh | Supprime la fonction qui lisait le contenu d'une boîte pssh (identifiant du système de protection, identifiants de clé, données). Elle n'avait plus d'usage depuis P25. |
| P27 | Retrait de la lecture des IV et des sous-échantillons | src/isobmff/isobmff-demuxer.ts, informations auxiliaires | Supprime les deux fonctions qui rassemblaient puis lisaient, à l'aide des boîtes saiz et saio, l'IV et le découpage en sous-échantillons de chaque échantillon chiffré. Elles n'avaient plus d'usage depuis P24. |
| P28 | Retrait du rattachement des IV aux échantillons | src/isobmff/isobmff-demuxer.ts, lecture d'un fragment | Supprime le passage qui rattachait l'IV et les sous-échantillons à chaque échantillon d'un fragment. Il n'avait plus d'usage depuis P24 et P27. |
| P29 | Retrait du report des informations auxiliaires | src/isobmff/isobmff-demuxer.ts, boîte traf | Supprime le report, d'un fragment de piste vers ses échantillons, des informations auxiliaires de chiffrement. Il n'avait plus d'usage depuis P24. |
| P30 | Retrait des champs qui gardaient ces données | src/isobmff/isobmff-demuxer.ts, pistes, fragments et échantillons | Supprime les champs, toujours vides désormais, qui gardaient les boîtes pssh lues (démultiplexeur et fragment), les informations auxiliaires de chiffrement (piste, état du fragment, données de piste du fragment) et les données de chiffrement de chaque échantillon. |
| P31 | Mémoire (M3) : points de référence MPEG-TS sans les octets du paquet | src/mpeg-ts/mpeg-ts-demuxer.ts, points de référence de la recherche | Hors déchiffrement. Le démultiplexeur MPEG-TS gardait, comme point de référence pour la recherche, le paquet PES entier (ses octets compris) tous les 256 paquets TS : pour un segment de 30 Mo à 60 Mb/s, presque chaque image, soit tout le segment, retenu par chaque segment encore ouvert (jusqu'à 110 Mo mesurés par instantané du tas pendant l'assemblage, banc tests/m3/memory-bench.mjs). Seuls la position et l'horodatage servent à la recherche : le point de référence n'en garde plus qu'une copie de ces champs. |

## Vérifications faites par le script à chaque génération

- Empreinte SHA-256 du fichier d'origine égale à celle de `SOURCE.md` ; sinon arrêt.
- Chaque texte cherché trouvé exactement le nombre de fois prévu ; pour un bloc retiré entre deux repères, chaque repère trouvé une seule fois, variables déclarées dans le bloc égales à la liste prévue.
- Après correctif : aucun marqueur de déchiffrement (liste de `tools/lib/markers.mjs`), aucune référence restante vers un identifiant retiré (y compris ceux des étapes P17 à P20 et P26 à P27), plus aucune trace du marquage des pistes Matroska chiffrées, aucune donnée d'entrée d'un déchiffreur (identifiants de clé, IV, sous-échantillons, boîtes pssh, informations auxiliaires de chiffrement), nombre exact de points de refus, syntaxe valide (`node --check`), mêmes exports que le fichier d'origine.
- Le diff unifié, réappliqué en mémoire au fichier d'origine, redonne exactement le fichier modifié.

## Licence (MPL-2.0)

- Ce fichier modifié reste sous MPL-2.0. L'en-tête d'origine est conservé tel quel, suivi d'une mention de modification. `LICENSE` est la copie exacte du texte de la licence fourni avec le paquet.
- Obligation : rendre disponibles le fichier modifié et le correctif. Lieu prévu : https://extensions.flavienhue.fr/sources/fluxmaster/ (à mettre en ligne avant l'envoi au Chrome Web Store), cité aussi dans `THIRD_PARTY_NOTICES.txt`.
- Le reste du code de FluxMaster n'est pas concerné par la MPL : seuls les fichiers de Mediabunny le sont.

## Mettre à jour Mediabunny

Changer la version dans `package.json`, puis lancer `npm run vendor`. Le script refuse un fichier d'origine dont l'empreinte diffère : relire alors chaque étape ci-dessus sur le nouveau fichier, adapter les textes cherchés, mettre à jour les empreintes dans le script, et repasser `npm run check` et `npm test`.
