Skip to content

Commit

Permalink
fix: ignore unknown opcodes in source maps (#764)
Browse files Browse the repository at this point in the history
* fix: ignore unknown opcodes in source maps

* Create chatty-roses-itch.md

* Stop decoding instructions after finding an invalid opcode

* Drop write lock immediately after using it

* Qualify log::debug instead of importing it
  • Loading branch information
fvictorio authored Jan 13, 2025
1 parent 2c999f4 commit 4ffb4f6
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/chatty-roses-itch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nomicfoundation/edr": patch
---

fix: ignore unknown opcodes in source maps
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/edr_solidity/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ alloy-sol-types = { version = "0.7.4", default-features = false, features = ["st
edr_eth = { version = "0.3.5", path = "../edr_eth" }
edr_evm = { version = "0.3.5", path = "../edr_evm" }
indexmap = { version = "2", features = ["serde"] }
log = { version = "0.4.17", default-features = false }
parking_lot = { version = "0.12.1", default-features = false }
serde = { version = "1.0.158", default-features = false, features = ["std"] }
serde_json = { version = "1.0.89", features = ["preserve_order"] }
Expand Down
26 changes: 15 additions & 11 deletions crates/edr_solidity/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,19 +709,23 @@ fn decode_bytecodes(
for contract in build_model.contract_id_to_contract.values() {
let contract_rc = contract.clone();

let mut contract = contract.write();

let contract_file = &contract.location.file().read().source_name.clone();
let contract_evm_output = &compiler_output.contracts[contract_file][&contract.name].evm;
let contract_abi_output = &compiler_output.contracts[contract_file][&contract.name].abi;

for item in contract_abi_output {
if item.r#type.as_deref() == Some("error") {
if let Ok(custom_error) = CustomError::from_abi(item.clone()) {
contract.add_custom_error(custom_error);
let contract_evm_output = {
let mut contract = contract.write();

let contract_file = &contract.location.file().read().source_name.clone();
let contract_evm_output = &compiler_output.contracts[contract_file][&contract.name].evm;
let contract_abi_output = &compiler_output.contracts[contract_file][&contract.name].abi;

for item in contract_abi_output {
if item.r#type.as_deref() == Some("error") {
if let Ok(custom_error) = CustomError::from_abi(item.clone()) {
contract.add_custom_error(custom_error);
}
}
}
}

contract_evm_output
};

// This is an abstract contract
if contract_evm_output.bytecode.object.is_empty() {
Expand Down
11 changes: 10 additions & 1 deletion crates/edr_solidity/src/source_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,16 @@ pub fn decode_instructions(
let source_map = &source_maps[instructions.len()];

let pc = bytes_index;
let opcode = OpCode::new(bytecode[pc]).expect("Invalid opcode");
let opcode = if let Some(opcode) = OpCode::new(bytecode[pc]) {
opcode
} else {
log::debug!("Invalid opcode {} at pc: {}", bytecode[pc], pc);

// We assume this happens because the source maps point to the metadata region
// of the bytecode. That means that the actual instructions have
// already been decoded and we can stop here.
return instructions;
};

let push_data = if opcode.is_push() {
let push_data = &bytecode[bytes_index..][..1 + opcode.info().immediate_size() as usize];
Expand Down

0 comments on commit 4ffb4f6

Please sign in to comment.