diff --git a/tests/core/test_export.py b/tests/core/test_export.py index b999997e..3b8d805f 100644 --- a/tests/core/test_export.py +++ b/tests/core/test_export.py @@ -310,3 +310,20 @@ def test_uppercase_content_key_is_stored_lowercase(tmp_path: Path, caplog: pytes titles = read_export(export)["titles"] assert titles[0]["keys"] == {KID.hex: "aa" * 16} assert "different key" not in caplog.text + + +@pytest.mark.parametrize("key", ["zz" * 16, "aa" * 8, "aa" * 32]) +def test_malformed_content_key_skips_the_key_not_the_download( + tmp_path: Path, caplog: pytest.LogCaptureFixture, key: str +) -> None: + """A key that is not 16 bytes of hex, as a new DRM system's tool might return, must not stop licensing.""" + export = tmp_path / "export.json" + title = make_title() + title.tracks.manifest_url = "https://example.test/m.mpd" + runner = make_dl() + + with caplog.at_level(logging.WARNING, logger="download"): + runner.write_export(export, title, title.tracks.videos[0], KeyDRM(key)) + + assert "keys" not in entry(export) + assert f"Not exporting the key for KID {KID.hex}" in caplog.text diff --git a/unshackle/commands/dl.py b/unshackle/commands/dl.py index 0abd1d9e..7ca03888 100644 --- a/unshackle/commands/dl.py +++ b/unshackle/commands/dl.py @@ -4001,10 +4001,18 @@ class dl: self.log.warning( f"KID {kid.hex} already has a different key in {export}, keeping the existing one" ) - else: + continue + try: entry.add_key(kid.hex, key) + except mediaexport.ExportError as e: + # a key the format cannot hold (not 16 bytes of hex) costs the export that key, + # never the download + self.log.warning(f"Not exporting the key for KID {kid.hex}: {e}") - mediaexport.write(export, doc) + try: + mediaexport.write(export, doc) + except (mediaexport.ExportError, OSError) as e: + self.log.warning(f"Could not write export {export}: {e}") def export_entry(self, title: Title_T) -> mediaexport.Entry: """A mediaexport entry for ``title``: manifests, chapters, a small track list, no keys yet."""