Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.

This project adheres to [Semantic Versioning](https://semver.org).

## [1.6.0] - 2026-01-16

- Fix GUI crash on certain types of invalid data
- Block size for decoding can now be configured

## [1.5.0] - 2025-12-18

- Fix bug that caused a variable number of blocks at the end of a file to not be decoded
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "infuse_decoder"
version = "1.5.0"
version = "1.6.0"
edition = "2024"

[[bin]]
Expand Down
2 changes: 1 addition & 1 deletion blocks/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use byteorder::{LittleEndian, ReadBytesExt};
use tdf::TdfOutput;

pub const BLOCK_SIZE: usize = 512;
pub const DEFAULT_BLOCK_SIZE: usize = 512;

#[derive(Hash, Copy, Clone, PartialEq, Eq)]
pub enum BlockTypes {
Expand Down
9 changes: 9 additions & 0 deletions scripts/tdf_decoder.rs.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ pub fn tdf_read_into_str(tdf_id: &u16, size: u8, cursor: &mut Cursor<&[u8]>) ->
};
let cursor_end = cursor.position();
let cursor_read = cursor_end - cursor_start;

if (size as u64) < cursor_read {
// Hande read overflow (more data read than specified)
return Result::Err(Error::new(
ErrorKind::InvalidData,
"Read overflow, corrupt data/metadata",
));
}

let underflow = size as u64 - cursor_read;

// Handle read underflow (more data specified than expected)
Expand Down
20 changes: 20 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use clap::ValueEnum;
use std::fmt;

#[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum)]
#[repr(usize)]
pub enum BlockSizeOptions {
#[value(name = "512")]
B512 = 512,
#[value(name = "4096")]
B4096 = 4096,
}

impl fmt::Display for BlockSizeOptions {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
BlockSizeOptions::B512 => write!(f, "512"),
BlockSizeOptions::B4096 => write!(f, "4096"),
}
}
}
15 changes: 11 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::thread;

use tdf::TdfOutput;

pub mod args;
pub mod fs_util;

pub trait ProgressReporter {
Expand Down Expand Up @@ -163,6 +164,7 @@ pub struct DecodeWorkerArgs {
pub output_unix_time: bool,
pub start_block: usize,
pub num_blocks: usize,
pub block_size: usize,
}

#[derive(Clone)]
Expand All @@ -189,15 +191,18 @@ pub fn worker_run_decode<T: ProgressReporter>(mut args: DecodeWorkerArgsReporter
// Open file
let file = File::open(args.decode_args.input_file.clone()).unwrap();
let mmap = unsafe { Mmap::map(&file).unwrap() };
let mmap_start = blocks::BLOCK_SIZE * args.decode_args.start_block;
let mmap_start = args.decode_args.block_size * args.decode_args.start_block;
let mmap_end =
blocks::BLOCK_SIZE * (args.decode_args.start_block + args.decode_args.num_blocks);
args.decode_args.block_size * (args.decode_args.start_block + args.decode_args.num_blocks);

// Range of the file for this worker
let mmap_slice = &mmap[mmap_start..mmap_end];

// Iterate over the blocks
for (index, block) in mmap_slice.chunks_exact(blocks::BLOCK_SIZE).enumerate() {
for (index, block) in mmap_slice
.chunks_exact(args.decode_args.block_size)
.enumerate()
{
match blocks::decode_block(&mut csv_writer, block) {
Ok(block_type) => *block_counter.entry(block_type).or_default() += 1,
Err(_) => *block_counter.entry(blocks::BlockTypes::ERROR).or_default() += 1,
Expand Down Expand Up @@ -237,6 +242,7 @@ pub fn worker_run_decode<T: ProgressReporter>(mut args: DecodeWorkerArgsReporter

pub struct RunArgs<T: ProgressReporter> {
pub device_id: u64,
pub block_size: usize,
pub input_files: Vec<PathBuf>,
pub output_folder: PathBuf,
pub output_prefix: String,
Expand Down Expand Up @@ -275,7 +281,7 @@ pub fn run<T: ProgressReporter + Clone + Send + 'static>(
(f, s)
};

let num_blocks = size / blocks::BLOCK_SIZE;
let num_blocks = size / args.block_size;
let max_workers = (num_blocks / 100) + 1;
let num_workers = std::cmp::min(max_workers, num_cpus::get());
let blocks_per_worker = num_blocks / num_workers;
Expand All @@ -299,6 +305,7 @@ pub fn run<T: ProgressReporter + Clone + Send + 'static>(
output_unix_time: args.output_unix_time,
start_block: idx * blocks_per_worker,
num_blocks: num,
block_size: args.block_size,
},
block_stats: stats_block.clone(),
tdf_stats: stats_tdf.clone(),
Expand Down
5 changes: 4 additions & 1 deletion src/main_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::path::PathBuf;

#[macro_use]
extern crate prettytable;
use prettytable::{format, Table};
use prettytable::{Table, format};

#[derive(Clone)]
pub struct IndicatifProgress {
Expand Down Expand Up @@ -59,6 +59,8 @@ struct Cli {
/// Verbose CLI output
#[arg(short, long)]
verbose: bool,
#[arg(long, default_value_t = infuse_decoder::args::BlockSizeOptions::B512)]
block_size: infuse_decoder::args::BlockSizeOptions,
}

fn main() -> io::Result<()> {
Expand Down Expand Up @@ -101,6 +103,7 @@ fn main() -> io::Result<()> {

let mut run_args = infuse_decoder::RunArgs {
device_id: *device_id,
block_size: args.block_size as usize,
input_files: files.clone(),
output_folder: args.output.clone(),
output_prefix: output_prefix,
Expand Down
42 changes: 30 additions & 12 deletions src/main_gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use egui_extras::{Column, TableBuilder};
use image::GenericImageView;
use rfd::FileDialog;

use infuse_decoder::args::BlockSizeOptions;

#[derive(PartialEq)]
enum TimeOutput {
UNIX,
Expand Down Expand Up @@ -77,6 +79,7 @@ impl infuse_decoder::ProgressReporter for SliderState {
struct MyApp {
time_mode: TimeOutput,
device_id: u64,
block_size: BlockSizeOptions,
input_path: Option<PathBuf>,
input_files: Option<HashMap<u64, Vec<PathBuf>>>,
output_folder: PathBuf,
Expand Down Expand Up @@ -121,6 +124,7 @@ impl Default for MyApp {
Self {
time_mode: TimeOutput::UTC,
device_id: 0,
block_size: BlockSizeOptions::B512,
input_path: None,
input_files: None,
output_folder: default_out.unwrap(),
Expand Down Expand Up @@ -236,18 +240,31 @@ fn core_options(app: &mut MyApp, _ctx: &egui::Context, ui: &mut egui::Ui) {
}

fn decode_options(app: &mut MyApp, _ctx: &egui::Context, ui: &mut egui::Ui) {
ui.vertical(|ui| {
ui.label("Time Output Format");
ui.radio_value(
&mut app.time_mode,
TimeOutput::UTC,
"UTC (2020-01-01T00:00:00.000000Z)",
);
ui.radio_value(
&mut app.time_mode,
TimeOutput::UNIX,
"UNIX (1577800800.000000)",
);
ui.horizontal(|ui| {
ui.vertical(|ui| {
ui.label("Time Output Format");
ui.radio_value(
&mut app.time_mode,
TimeOutput::UTC,
"UTC (2020-01-01T00:00:00.000000Z)",
);
ui.radio_value(
&mut app.time_mode,
TimeOutput::UNIX,
"UNIX (1577800800.000000)",
);
});
ui.separator();
ui.vertical(|ui| {
ui.label("Block Size");
egui::ComboBox::from_id_salt("Block Size")
.selected_text(format!("{:}", app.block_size))
.show_ui(ui, |ui| {
ui.selectable_value(&mut app.block_size, BlockSizeOptions::B512, "512");
ui.selectable_value(&mut app.block_size, BlockSizeOptions::B4096, "4096");
});
});
ui.separator();
});
}

Expand Down Expand Up @@ -283,6 +300,7 @@ fn start_button(app: &mut MyApp, _ctx: &egui::Context, ui: &mut egui::Ui) {

let mut run_args = infuse_decoder::RunArgs {
device_id: app.device_id,
block_size: app.block_size as usize,
input_files: files,
output_folder: app.output_folder.clone(),
output_prefix: app.output_prefix.clone(),
Expand Down
9 changes: 9 additions & 0 deletions tdf/src/decoders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,15 @@ pub fn tdf_read_into_str(tdf_id: &u16, size: u8, cursor: &mut Cursor<&[u8]>) ->
};
let cursor_end = cursor.position();
let cursor_read = cursor_end - cursor_start;

if (size as u64) < cursor_read {
// Hande read overflow (more data read than specified)
return Result::Err(Error::new(
ErrorKind::InvalidData,
"Read overflow, corrupt data/metadata",
));
}

let underflow = size as u64 - cursor_read;

// Handle read underflow (more data specified than expected)
Expand Down
Loading