Compare commits

...

7 Commits

Author SHA1 Message Date
51c3af2bbe Version 3.4.4 2025-11-26 19:33:00 -07:00
LagoLunatic
d0b8b449d9 Ignore hidden symbols when diffing data sections (#291) 2025-11-26 18:49:36 -07:00
LagoLunatic
32f5f202f7 Update outdated extab test snapshot (#292) 2025-11-26 17:56:32 -05:00
LagoLunatic
481dbc185a Support more string encodings and allow copying unescaped strings (#288)
* Copy strings without escape sequences in them

* Add support for more encodings from encoding_rs

Also use encoding_rs instead of CStr for UTF-8.
2025-11-22 19:36:41 -07:00
26a4cc79cf Version 3.4.3 2025-11-22 12:47:03 -07:00
5c96c2ee51 Update cwextab 2025-11-22 12:45:58 -07:00
d162fe847e Remove --mapping, --selecting-{left,right} from CLI 2025-11-21 23:55:26 -07:00
10 changed files with 41 additions and 55 deletions

12
Cargo.lock generated
View File

@@ -1000,9 +1000,9 @@ checksum = "c2e06f9bce634a3c898eb1e5cb949ff63133cbb218af93cc9b38b31d6f3ea285"
[[package]]
name = "cwextab"
version = "1.1.6"
version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d21b94648643c61e1b5cef71e8d3a9f89350397ac2b0fe42890edbc94757b18"
checksum = "e23dadbc8945746c361e3967336075be7281a5455c06f5c5a17fddca4e7d2175"
dependencies = [
"thiserror 2.0.17",
]
@@ -3491,7 +3491,7 @@ dependencies = [
[[package]]
name = "objdiff-cli"
version = "3.4.2"
version = "3.4.4"
dependencies = [
"anyhow",
"argp",
@@ -3514,7 +3514,7 @@ dependencies = [
[[package]]
name = "objdiff-core"
version = "3.4.2"
version = "3.4.4"
dependencies = [
"anyhow",
"arm-attr",
@@ -3570,7 +3570,7 @@ dependencies = [
[[package]]
name = "objdiff-gui"
version = "3.4.2"
version = "3.4.4"
dependencies = [
"anyhow",
"argp",
@@ -3608,7 +3608,7 @@ dependencies = [
[[package]]
name = "objdiff-wasm"
version = "3.4.2"
version = "3.4.4"
dependencies = [
"log",
"objdiff-core",

View File

@@ -14,7 +14,7 @@ default-members = [
resolver = "3"
[workspace.package]
version = "3.4.2"
version = "3.4.4"
authors = ["Luke Street <luke@street.dev>"]
edition = "2024"
license = "MIT OR Apache-2.0"

View File

@@ -66,15 +66,6 @@ pub struct Args {
#[argp(option, short = 'c')]
/// Configuration property (key=value)
config: Vec<String>,
#[argp(option, short = 'm')]
/// Symbol mapping (target=base)
mapping: Vec<String>,
#[argp(option)]
/// Left symbol name for selection
selecting_left: Option<String>,
#[argp(option)]
/// Right symbol name for selection
selecting_right: Option<String>,
}
pub fn run(args: Args) -> Result<()> {
@@ -183,17 +174,7 @@ fn build_config_from_args(
apply_project_options(&mut diff_config, options)?;
}
apply_config_args(&mut diff_config, &args.config)?;
let mut mapping_config = MappingConfig {
mappings: Default::default(),
selecting_left: args.selecting_left.clone(),
selecting_right: args.selecting_right.clone(),
};
for mapping in &args.mapping {
let (target, base) =
mapping.split_once('=').context("--mapping expects \"target=base\"")?;
mapping_config.mappings.insert(target.to_string(), base.to_string());
}
Ok((diff_config, mapping_config))
Ok((diff_config, MappingConfig::default()))
}
pub struct AppState {

View File

@@ -7,12 +7,10 @@ use alloc::{
};
use core::{
any::Any,
ffi::CStr,
fmt::{self, Debug},
};
use anyhow::{Result, bail};
use encoding_rs::SHIFT_JIS;
use object::Endian as _;
use crate::{
@@ -44,6 +42,16 @@ pub mod x86;
pub const OPCODE_INVALID: u16 = u16::MAX;
pub const OPCODE_DATA: u16 = u16::MAX - 1;
const SUPPORTED_ENCODINGS: [(&encoding_rs::Encoding, &str); 7] = [
(encoding_rs::UTF_8, "UTF-8"),
(encoding_rs::SHIFT_JIS, "Shift JIS"),
(encoding_rs::UTF_16BE, "UTF-16BE"),
(encoding_rs::UTF_16LE, "UTF-16LE"),
(encoding_rs::WINDOWS_1252, "Windows-1252"),
(encoding_rs::EUC_JP, "EUC-JP"),
(encoding_rs::BIG5, "Big5"),
];
/// Represents the type of data associated with an instruction
#[derive(PartialEq)]
pub enum DataType {
@@ -77,7 +85,7 @@ impl DataType {
let mut strs = Vec::new();
for (literal, label_override) in self.display_literals(endian, bytes) {
let label = label_override.unwrap_or_else(|| self.to_string());
strs.push(format!("{label}: {literal}"))
strs.push(format!("{label}: {literal:?}"))
}
strs
}
@@ -164,16 +172,18 @@ impl DataType {
strs.push((format!("{bytes:#?}"), None));
}
DataType::String => {
if let Ok(cstr) = CStr::from_bytes_until_nul(bytes) {
strs.push((format!("{cstr:?}"), None));
}
if let Some(nul_idx) = bytes.iter().position(|&c| c == b'\0') {
let (cow, _, had_errors) = SHIFT_JIS.decode(&bytes[..nul_idx]);
if !had_errors {
let str = format!("{cow:?}");
// Only add the Shift JIS string if it's different from the ASCII string.
if !strs.iter().any(|x| x.0 == str) {
strs.push((str, Some("Shift JIS".into())));
let str_bytes = &bytes[..nul_idx];
// Special case to display (ASCII) as the label for ASCII-only strings.
let (cow, _, had_errors) = encoding_rs::UTF_8.decode(str_bytes);
if !had_errors && cow.is_ascii() {
strs.push((format!("{cow}"), Some("ASCII".into())));
}
for (encoding, encoding_name) in SUPPORTED_ENCODINGS {
let (cow, _, had_errors) = encoding.decode(str_bytes);
// Avoid showing ASCII-only strings more than once if the encoding is ASCII-compatible.
if !had_errors && (!encoding.is_ascii_compatible() || !cow.is_ascii()) {
strs.push((format!("{cow}"), Some(encoding_name.into())));
}
}
}

View File

@@ -588,6 +588,7 @@ fn symbols_matching_section(
s.section == Some(section_idx)
&& s.kind != SymbolKind::Section
&& s.size > 0
&& !s.flags.contains(SymbolFlag::Hidden)
&& !s.flags.contains(SymbolFlag::Ignored)
})
}

View File

@@ -668,7 +668,7 @@ pub fn instruction_hover(
for (literal, label_override) in literals {
out.push(HoverItem::Text {
label: label_override.unwrap_or_else(|| ty.to_string()),
value: literal,
value: format!("{literal:?}"),
color: HoverItemColor::Normal,
});
}

View File

@@ -69,19 +69,19 @@ Object {
action_param: 0,
has_end_bit: true,
bytes: [
130,
0,
0,
8,
0,
0,
0,
0,
],
},
],
relocations: [
Relocation {
offset: 18,
address: 524288,
offset: 20,
address: 0,
},
],
},

View File

@@ -871,19 +871,13 @@ pub fn context_menu_items_ui(
match item {
ContextItem::Copy { value, label } => {
let mut job = LayoutJob::default();
write_text("Copy ", appearance.text_color, &mut job, appearance.code_font.clone());
write_text(
"Copy \"",
appearance.text_color,
&mut job,
appearance.code_font.clone(),
);
write_text(
&value,
&format!("{value:?}"),
appearance.highlight_color,
&mut job,
appearance.code_font.clone(),
);
write_text("\"", appearance.text_color, &mut job, appearance.code_font.clone());
if let Some(label) = label {
write_text(" (", appearance.text_color, &mut job, appearance.code_font.clone());
write_text(

View File

@@ -1,12 +1,12 @@
{
"name": "objdiff-wasm",
"version": "3.4.2",
"version": "3.4.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "objdiff-wasm",
"version": "3.4.2",
"version": "3.4.4",
"license": "MIT OR Apache-2.0",
"devDependencies": {
"@biomejs/biome": "^1.9.3",

View File

@@ -1,6 +1,6 @@
{
"name": "objdiff-wasm",
"version": "3.4.2",
"version": "3.4.4",
"description": "A local diffing tool for decompilation projects.",
"author": {
"name": "Luke Street",