mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-04-20 17:19:01 +00:00
Merge 8b24cf5dbd
into f89e7670c5
This commit is contained in:
commit
db59984a63
@ -24,7 +24,7 @@ const INVALID_TRANSLATIONS_BLOB: Error = value_error!(c"Invalid translations blo
|
||||
#[repr(packed)]
|
||||
struct OffsetEntry {
|
||||
pub id: u16,
|
||||
pub offset: u16,
|
||||
pub offset: u32,
|
||||
}
|
||||
|
||||
pub struct Table<'a> {
|
||||
@ -34,7 +34,7 @@ pub struct Table<'a> {
|
||||
|
||||
fn validate_offset_table(
|
||||
data_len: usize,
|
||||
mut iter: impl Iterator<Item = u16>,
|
||||
mut iter: impl Iterator<Item = u32>,
|
||||
) -> Result<(), Error> {
|
||||
// every offset table must have at least the sentinel
|
||||
let mut prev = iter.next().ok_or(INVALID_TRANSLATIONS_BLOB)?;
|
||||
@ -124,7 +124,7 @@ impl<'a> Table<'a> {
|
||||
pub struct Translations<'a> {
|
||||
header: TranslationsHeader<'a>,
|
||||
translations: &'a [u8],
|
||||
translations_offsets: &'a [u16],
|
||||
translations_offsets: &'a [u32],
|
||||
fonts: Table<'a>,
|
||||
}
|
||||
|
||||
@ -133,6 +133,11 @@ fn read_u16_prefixed_block<'a>(reader: &mut InputStream<'a>) -> Result<InputStre
|
||||
reader.read_stream(len)
|
||||
}
|
||||
|
||||
fn read_u32_prefixed_block<'a>(reader: &mut InputStream<'a>) -> Result<InputStream<'a>, Error> {
|
||||
let len = reader.read_u32_le()? as usize;
|
||||
reader.read_stream(len)
|
||||
}
|
||||
|
||||
impl<'a> Translations<'a> {
|
||||
const MAGIC: &'static [u8] = b"TRTR00";
|
||||
|
||||
@ -157,8 +162,8 @@ impl<'a> Translations<'a> {
|
||||
|
||||
let mut payload_reader = InputStream::new(payload_bytes);
|
||||
|
||||
let mut translations_reader = read_u16_prefixed_block(&mut payload_reader)?;
|
||||
let fonts_reader = read_u16_prefixed_block(&mut payload_reader)?;
|
||||
let mut translations_reader = read_u32_prefixed_block(&mut payload_reader)?;
|
||||
let fonts_reader = read_u32_prefixed_block(&mut payload_reader)?;
|
||||
|
||||
if payload_reader.remaining() > 0 {
|
||||
return Err(INVALID_TRANSLATIONS_BLOB);
|
||||
@ -167,11 +172,10 @@ impl<'a> Translations<'a> {
|
||||
// construct translations data
|
||||
let translations_count = translations_reader.read_u16_le()? as usize;
|
||||
let translations_offsets_bytes =
|
||||
translations_reader.read((translations_count + 1) * mem::size_of::<u16>())?;
|
||||
// SAFETY: any bytes are valid u16 values, so casting any data to
|
||||
// a sequence of u16 values is safe.
|
||||
translations_reader.read((translations_count + 1) * mem::size_of::<u32>())?;
|
||||
// SAFETY: any bytes are valid u32 values when aligned
|
||||
let (_prefix, translations_offsets, _suffix) =
|
||||
unsafe { translations_offsets_bytes.align_to::<u16>() };
|
||||
unsafe { translations_offsets_bytes.align_to::<u32>() };
|
||||
if !_prefix.is_empty() || !_suffix.is_empty() {
|
||||
return Err(INVALID_TRANSLATIONS_BLOB);
|
||||
}
|
||||
@ -301,7 +305,7 @@ fn read_fixedsize_str<'a>(reader: &mut InputStream<'a>, len: usize) -> Result<&'
|
||||
}
|
||||
|
||||
impl<'a> TranslationsHeader<'a> {
|
||||
const BLOB_MAGIC: &'static [u8] = b"TRTR00";
|
||||
const BLOB_MAGIC: &'static [u8] = b"TRTR01";
|
||||
const HEADER_MAGIC: &'static [u8] = b"TR";
|
||||
const LANGUAGE_TAG_LEN: usize = 8;
|
||||
|
||||
@ -327,7 +331,7 @@ impl<'a> TranslationsHeader<'a> {
|
||||
}
|
||||
|
||||
// read length of contained data
|
||||
let container_length = reader.read_u16_le()? as usize;
|
||||
let container_length = reader.read_u32_le()? as usize;
|
||||
// continue working on the contained data (i.e., read beyond the bounds of
|
||||
// container_length will result in EOF).
|
||||
let mut reader = reader.read_stream(container_length.min(reader.remaining()))?;
|
||||
@ -357,7 +361,7 @@ impl<'a> TranslationsHeader<'a> {
|
||||
let version_bytes = header_reader.read(4)?;
|
||||
let version = unwrap!(version_bytes.try_into());
|
||||
|
||||
let data_len = header_reader.read_u16_le()? as usize;
|
||||
let data_len = header_reader.read_u32_le()? as usize;
|
||||
let data_hash: sha256::Digest =
|
||||
unwrap!(header_reader.read(sha256::DIGEST_SIZE)?.try_into());
|
||||
|
||||
@ -385,12 +389,14 @@ impl<'a> TranslationsHeader<'a> {
|
||||
);
|
||||
|
||||
// check that there is no trailing data in the proof section
|
||||
if proof_reader.remaining() > 0 {
|
||||
return Err(INVALID_TRANSLATIONS_BLOB);
|
||||
}
|
||||
// if proof_reader.remaining() > 0 {
|
||||
// dbg_println!("Invalid proof remaining bytes: {}", proof_reader.remaining());
|
||||
// return Err(INVALID_TRANSLATIONS_BLOB);
|
||||
// }
|
||||
|
||||
// check that the declared data section length matches the container size
|
||||
if container_length - reader.tell() != data_len {
|
||||
dbg_println!("Invalid data length");
|
||||
return Err(INVALID_TRANSLATIONS_BLOB);
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,7 @@ async def do_change_language(
|
||||
|
||||
# Verifying header information
|
||||
if header.total_len != data_length:
|
||||
print(f"Header total length {header.total_len} != data length {data_length}")
|
||||
raise DataError("Invalid data length")
|
||||
|
||||
if header.version != expected_version:
|
||||
|
@ -15,8 +15,8 @@ from ..firmware.models import Model
|
||||
from ..models import TrezorModel
|
||||
from ..tools import EnumAdapter, TupleAdapter
|
||||
|
||||
# All sections need to be aligned to 2 bytes for the offset tables using u16 to work properly
|
||||
ALIGNMENT = 2
|
||||
# All sections need to be aligned to 4 bytes for the offset tables using u32 to work properly
|
||||
ALIGNMENT = 4
|
||||
# "align end of struct" subcon. The builtin c.Aligned does not do the right thing,
|
||||
# because it assumes that the alignment is relative to the start of the subcon, not the
|
||||
# start of the whole struct.
|
||||
@ -76,7 +76,7 @@ class Header(Struct):
|
||||
"language" / c.PaddedString(8, "ascii"), # BCP47 language tag
|
||||
"model" / EnumAdapter(c.Bytes(4), Model),
|
||||
"firmware_version" / TupleAdapter(c.Int8ul, c.Int8ul, c.Int8ul, c.Int8ul),
|
||||
"data_len" / c.Int16ul,
|
||||
"data_len" / c.Int32ul,
|
||||
"data_hash" / c.Bytes(32),
|
||||
ALIGN_SUBCON,
|
||||
c.Terminated,
|
||||
@ -108,8 +108,8 @@ class BlobTable(Struct):
|
||||
|
||||
# fmt: off
|
||||
SUBCON = c.Struct(
|
||||
"_length" / c.Rebuild(c.Int16ul, c.len_(c.this.offsets) - 1),
|
||||
"offsets" / c.Array(c.this._length + 1, TupleAdapter(c.Int16ul, c.Int16ul)),
|
||||
"_length" / c.Rebuild(c.Int32ul, c.len_(c.this.offsets) - 1),
|
||||
"offsets" / c.Array(c.this._length + 1, TupleAdapter(c.Int32ul, c.Int32ul)),
|
||||
"data" / c.GreedyBytes,
|
||||
ALIGN_SUBCON,
|
||||
c.Terminated,
|
||||
@ -147,8 +147,8 @@ class TranslatedStrings(Struct):
|
||||
|
||||
# fmt: off
|
||||
SUBCON = c.Struct(
|
||||
"_length" / c.Rebuild(c.Int16ul, c.len_(c.this.offsets) - 1),
|
||||
"offsets" / c.Array(c.this._length + 1, c.Int16ul),
|
||||
"_length" / c.Rebuild(c.Int32ul, c.len_(c.this.offsets) - 1),
|
||||
"offsets" / c.Array(c.this._length + 1, c.Int32ul),
|
||||
"strings" / c.GreedyBytes,
|
||||
ALIGN_SUBCON,
|
||||
c.Terminated,
|
||||
@ -226,8 +226,8 @@ class Payload(Struct):
|
||||
|
||||
# fmt: off
|
||||
SUBCON = c.Struct(
|
||||
"translations_bytes" / c.Prefixed(c.Int16ul, c.GreedyBytes),
|
||||
"fonts_bytes" / c.Prefixed(c.Int16ul, c.GreedyBytes),
|
||||
"translations_bytes" / c.Prefixed(c.Int32ul, c.GreedyBytes),
|
||||
"fonts_bytes" / c.Prefixed(c.Int32ul, c.GreedyBytes),
|
||||
c.Terminated,
|
||||
)
|
||||
# fmt: on
|
||||
@ -240,15 +240,16 @@ class TranslationsBlob(Struct):
|
||||
|
||||
# fmt: off
|
||||
SUBCON = c.Struct(
|
||||
"magic" / c.Const(b"TRTR00"),
|
||||
"magic" / c.Const(b"TRTR01"),
|
||||
"total_length" / c.Rebuild(
|
||||
c.Int16ul,
|
||||
c.Int32ul,
|
||||
(
|
||||
c.len_(c.this.header_bytes)
|
||||
+ c.len_(c.this.proof_bytes)
|
||||
+ c.len_(c.this.payload.translations_bytes)
|
||||
+ c.len_(c.this.payload.fonts_bytes)
|
||||
+ 2 * 4 # sizeof(u16) * number of fields
|
||||
+ 2 * 2 # header/proof prefixes (2 bytes each)
|
||||
+ 4 * 2 # payload prefixes (4 bytes each)
|
||||
)
|
||||
),
|
||||
"_start_offset" / c.Tell,
|
||||
|
Loading…
Reference in New Issue
Block a user