Skip to content

Commit

Permalink
print code report in mxsc.json
Browse files Browse the repository at this point in the history
  • Loading branch information
BiancaIalangi committed Jun 3, 2024
1 parent 7b839c6 commit 9a1119c
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 13 deletions.
30 changes: 30 additions & 0 deletions framework/meta-lib/src/code_report_json.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use serde::{Deserialize, Serialize};

use crate::tools::report_creator::ReportCreator;

#[derive(Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct CodeReportJson {
#[serde(default)]
pub path: String,

#[serde(default)]
pub size: usize,

#[serde(default)]
pub has_allocator: bool,

#[serde(default)]
pub has_panic: String,
}

impl CodeReportJson {
pub fn new(report: &ReportCreator, size: usize) -> CodeReportJson {
CodeReportJson {
path: report.path.clone(),
size,
has_allocator: report.has_allocator,
has_panic: report.has_panic.clone(),
}
}
}
3 changes: 1 addition & 2 deletions framework/meta-lib/src/contract/sc_config/wasm_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,10 @@ impl ContractVariant {
let mut abi = ContractAbiJson::from(&self.abi);
let build_info = core::mem::take(&mut abi.build_info).unwrap();
let ei_check_json = EiCheckJson::new(&self.settings.check_ei, wasm_info.ei_check);
let report = ReportInfoJson::new(&wasm_info, ei_check_json);
let report = ReportInfoJson::new(&wasm_info, ei_check_json, compiled_bytes.len());
let mxsc_file_json = MxscFileJson {
build_info,
abi,
size: compiled_bytes.len(),
code: hex::encode(compiled_bytes),
report,
};
Expand Down
1 change: 1 addition & 0 deletions framework/meta-lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod abi_json;
pub mod cargo_toml_contents;
pub mod cli;
mod code_report_json;
pub mod contract;
pub mod ei;
pub mod ei_check_json;
Expand Down
1 change: 0 additions & 1 deletion framework/meta-lib/src/mxsc_file_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use crate::{
pub struct MxscFileJson {
pub build_info: BuildInfoAbiJson,
pub abi: ContractAbiJson,
pub size: usize,
pub code: String,
pub report: ReportInfoJson,
}
Expand Down
12 changes: 6 additions & 6 deletions framework/meta-lib/src/report_info_json.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};

use crate::{ei_check_json::EiCheckJson, tools::WasmInfo};
use crate::{code_report_json::CodeReportJson, ei_check_json::EiCheckJson, tools::WasmInfo};

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
Expand All @@ -9,19 +9,19 @@ pub struct ReportInfoJson {
#[serde(skip_serializing_if = "Vec::is_empty")]
pub imports: Vec<String>,

#[serde(default)]
pub memory_allocation_error: bool,

#[serde(default)]
pub is_mem_grow: bool,

#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub ei_check: Option<EiCheckJson>,

#[serde(default)]
pub code_report: CodeReportJson,
}

impl ReportInfoJson {
pub fn new(wasm_info: &WasmInfo, ei_check_info: Option<EiCheckJson>) -> Self {
pub fn new(wasm_info: &WasmInfo, ei_check_info: Option<EiCheckJson>, size: usize) -> Self {
let ei_check = if wasm_info.imports.is_empty() {
None
} else {
Expand All @@ -30,9 +30,9 @@ impl ReportInfoJson {

ReportInfoJson {
imports: wasm_info.imports.iter().map(|i| i.to_string()).collect(),
memory_allocation_error: wasm_info.allocator_trigger,
is_mem_grow: wasm_info.memory_grow_flag,
ei_check,
code_report: CodeReportJson::new(&wasm_info.report, size),
}
}
}
1 change: 1 addition & 0 deletions framework/meta-lib/src/tools.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod find_workspace;
mod git_describe;
pub(crate) mod report_creator;
pub mod twiggy;
mod wasm_extractor;
mod wasm_opt;
Expand Down
10 changes: 10 additions & 0 deletions framework/meta-lib/src/tools/report_creator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
pub const WITH_MESSAGE: &str = "with message";
pub const WITHOUT_MESSAGE: &str = "without message";

pub struct ReportCreator {
pub path: String,
pub has_allocator: bool,
pub has_panic: String,
}

impl ReportCreator {}
60 changes: 56 additions & 4 deletions framework/meta-lib/src/tools/wasm_extractor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ use wasmparser::{

use crate::ei::EIVersion;

use super::report_creator::{ReportCreator, WITHOUT_MESSAGE, WITH_MESSAGE};

const PANIC_WITH_MESSAGE: &[u8; 16] = b"panic occurred: ";
const PANIC_WITHOUT_MESSAGE: &[u8; 14] = b"panic occurred";
const ERROR_FAIL_ALLOCATOR: &[u8; 27] = b"memory allocation forbidden";
const MEMORY_GROW_OPCODE: u8 = 0x40;

pub struct WasmInfo {
pub imports: Vec<String>,
pub allocator_trigger: bool,
pub ei_check: bool,
pub memory_grow_flag: bool,
pub has_format: bool,
pub report: ReportCreator,
}

impl WasmInfo {
Expand All @@ -25,11 +30,17 @@ impl WasmInfo {
let wasm_data = fs::read(output_wasm_path)
.expect("error occured while extracting information from .wasm: file not found");

populate_wasm_info(wasm_data, extract_imports_enabled, check_ei)
populate_wasm_info(
output_wasm_path.to_string(),
wasm_data,
extract_imports_enabled,
check_ei,
)
}
}

fn populate_wasm_info(
path: String,
wasm_data: Vec<u8>,
extract_imports_enabled: bool,
check_ei: &Option<EIVersion>,
Expand All @@ -38,6 +49,7 @@ fn populate_wasm_info(
let mut allocator_trigger = false;
let mut ei_check = false;
let mut memory_grow_flag = false;
let mut has_panic = "none";

let parser = Parser::new(0);
for payload in parser.parse_all(&wasm_data) {
Expand All @@ -47,7 +59,12 @@ fn populate_wasm_info(
ei_check = is_ei_valid(imports.clone(), check_ei);
},
Payload::DataSection(data_section) => {
allocator_trigger = is_fail_allocator_triggered(data_section);
allocator_trigger = is_fail_allocator_triggered(data_section.clone());
if is_panic_with_message_triggered(data_section.clone()) {
has_panic = WITH_MESSAGE;
} else if is_panic_without_message_triggered(data_section) {
has_panic = WITHOUT_MESSAGE;
}
},
Payload::CodeSectionEntry(code_section) => {
memory_grow_flag = is_mem_grow(code_section);
Expand All @@ -56,11 +73,18 @@ fn populate_wasm_info(
}
}

let report = ReportCreator {
path,
has_allocator: allocator_trigger,
has_panic: has_panic.to_string(),
};

Ok(WasmInfo {
imports,
allocator_trigger,
ei_check,
memory_grow_flag,
has_format: true,
report,
})
}

Expand All @@ -85,6 +109,34 @@ fn is_fail_allocator_triggered(data_section: DataSectionReader) -> bool {
false
}

fn is_panic_with_message_triggered(data_section: DataSectionReader) -> bool {
for data_fragment in data_section.into_iter().flatten() {
if data_fragment
.data
.windows(PANIC_WITH_MESSAGE.len())
.any(|data| data == PANIC_WITH_MESSAGE)
{
return true;
}
}

false
}

fn is_panic_without_message_triggered(data_section: DataSectionReader) -> bool {
for data_fragment in data_section.into_iter().flatten() {
if data_fragment
.data
.windows(PANIC_WITHOUT_MESSAGE.len())
.any(|data| data == PANIC_WITHOUT_MESSAGE)
{
return true;
}
}

false
}

pub fn extract_imports(
import_section: ImportSectionReader,
import_extraction_enabled: bool,
Expand Down

0 comments on commit 9a1119c

Please sign in to comment.