chore(python): deprecate uploading language blob during firmware update
What changed, and why it matters
This commit removes a feature from Trezor's Python tools that let users upload a language translation file during a firmware update. It is a routine cleanup (chore) that deprecates the language-blob upload option and simplifies the code. There is no indication of a security fix or vulnerability.
No security action needed. Treat as a normal feature deprecation and verify dependent tooling no longer relies on the removed `--language` option.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch removes the --language CLI option and the associated language_data handling from trezorlib/cli/firmware.py, and drops the language_data parameter and chunked upload logic from reboot_to_bootloader() in trezorlib/device.py. The changelog fragment labels it as a removal/deprecation. No security relevance is stated or implied.
Changed components
python/src/trezorlib/cli/firmware.pypython/src/trezorlib/device.pyInspect captured patch +5 / −32
diff --git a/python/.changelog.d/6103.removed b/python/.changelog.d/6103.removed
new file mode 100644
index 00000000..10a30829
--- /dev/null
+++ b/python/.changelog.d/6103.removed
@@ -0,0 +1 @@
+Deprecate uploading language blob during firmware update.
diff --git a/python/src/trezorlib/cli/firmware.py b/python/src/trezorlib/cli/firmware.py
index 1489a9df..a29649e6 100644
--- a/python/src/trezorlib/cli/firmware.py
+++ b/python/src/trezorlib/cli/firmware.py
@@ -17,7 +17,6 @@
import os
import sys
import time
-from pathlib import Path
from typing import (
TYPE_CHECKING,
Any,
@@ -614,7 +613,6 @@ def download(
@click.option("-v", "--version", help="Which version to download")
@click.option("-s", "--skip-check", is_flag=True, help="Do not validate firmware integrity")
@click.option("-n", "--dry-run", is_flag=True, help="Perform all steps but do not actually upload the firmware")
-@click.option("-l", "--language", help="Language code, blob, or URL")
@click.option("--bitcoin-only/--universal", is_flag=True, default=None, help="Download bitcoin-only or universal firmware (defaults to universal)")
@click.option("--raw", is_flag=True, help="Push raw firmware data to Trezor")
@click.option("--fingerprint", help="Expected firmware fingerprint in hex")
@@ -630,7 +628,6 @@ def update(
raw: bool,
dry_run: bool,
bitcoin_only: Optional[bool],
- language: Optional[str],
) -> None:
"""Upload new firmware to device.
@@ -649,23 +646,6 @@ def update(
click.echo("You can use only one of: filename, url, version.")
sys.exit(1)
- language_data = b""
- if language is not None:
- if client.features.bootloader_mode:
- click.echo("Language data cannot be uploaded in bootloader mode.")
- sys.exit(1)
-
- assert language is not None
- try:
- language_data = Path(language).read_bytes()
- except Exception:
- try:
- language_data = requests.get(language).content
- except Exception:
- raise click.ClickException(
- f"Failed to load translations from {language}"
- ) from None
-
if filename:
firmware_data = filename.read()
else:
@@ -703,13 +683,8 @@ def update(
seedless_session,
boot_command=messages.BootCommand.INSTALL_UPGRADE,
firmware_header=firmware_data[:header_size],
- language_data=language_data,
)
else:
- if language_data:
- click.echo(
- "WARNING: Seamless installation not possible, language data will not be uploaded."
- )
device.reboot_to_bootloader(seedless_session)
click.echo("Waiting for bootloader...")
diff --git a/python/src/trezorlib/device.py b/python/src/trezorlib/device.py
index bdcf5427..779bd30e 100644
--- a/python/src/trezorlib/device.py
+++ b/python/src/trezorlib/device.py
@@ -605,18 +605,15 @@ def reboot_to_bootloader(
session: "Session",
boot_command: messages.BootCommand = messages.BootCommand.STOP_AND_WAIT,
firmware_header: Optional[bytes] = None,
- language_data: bytes = b"",
) -> str | None:
- response = session.call(
+ ret = session.call(
messages.RebootToBootloader(
boot_command=boot_command,
firmware_header=firmware_header,
- language_data_length=len(language_data),
- )
+ ),
+ expect=messages.Success,
)
- if isinstance(response, messages.DataChunkRequest):
- response = _send_chunked_data(session, response, language_data)
- return _return_success(messages.Success(message=""))
+ return _return_success(ret)
def show_device_tutorial(session: "Session") -> str | None:
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.