Skip to content

Commit

Permalink
Merge pull request #1775 from multiversx/wasm-extractor-fix
Browse files Browse the repository at this point in the history
wasm extractor - fix report parameters
  • Loading branch information
BiancaIalangi authored Sep 30, 2024
2 parents 288dd73 + c88c59d commit e41b2a3
Show file tree
Hide file tree
Showing 8 changed files with 444 additions and 51 deletions.
44 changes: 44 additions & 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 framework/meta-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ hex = "0.4"
wasmparser = "0.216"
wasmprinter = "0.216"
semver = "1.0.20"
wat = "1.217.0"

[dependencies.multiversx-sc]
version = "=0.53.0"
Expand Down
2 changes: 1 addition & 1 deletion framework/meta-lib/src/code_report_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl CodeReportJson {
path: report.path.clone(),
size,
has_allocator: report.has_allocator,
has_panic: report.has_panic.clone(),
has_panic: report.has_panic.to_string(),
}
}
}
2 changes: 2 additions & 0 deletions framework/meta-lib/src/tools.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
mod find_workspace;
mod git_describe;
pub(crate) mod panic_report;
pub(crate) mod report_creator;
pub mod twiggy;
mod wasm_extractor;
mod wasm_extractor_test;
mod wasm_opt;
mod wasm_to_wat;

Expand Down
80 changes: 80 additions & 0 deletions framework/meta-lib/src/tools/panic_report.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use std::fmt::Display;

use wasmparser::DataSectionReader;
const PANIC_WITH_MESSAGE: &[u8; 16] = b"panic occurred: ";
const PANIC_WITHOUT_MESSAGE: &[u8; 14] = b"panic occurred";

#[derive(Default, PartialEq, Clone)]
pub enum PanicReport {
#[default]
None,
WithoutMessage,
WithMessage,
}

impl Display for PanicReport {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let panic_status = match self {
PanicReport::None => "None",
PanicReport::WithoutMessage => "without message",
PanicReport::WithMessage => "with message",
};
write!(f, "{}", panic_status)
}
}

impl PanicReport {
pub fn data_section_severity(&self, data_section: DataSectionReader) -> Self {
if is_panic_with_message_triggered(data_section.clone()) {
return Self::WithMessage;
}

if is_panic_without_message_triggered(data_section) {
println!("here");
return Self::WithoutMessage;
}

Self::None
}

pub fn max_severity(&mut self, data_section: DataSectionReader) {
if *self == PanicReport::WithMessage {
return;
}

let panic_report = self.data_section_severity(data_section);
if panic_report == PanicReport::None {
return;
}

*self = panic_report;
}
}

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
}
5 changes: 2 additions & 3 deletions framework/meta-lib/src/tools/report_creator.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
pub const WITH_MESSAGE: &str = "with message";
pub const WITHOUT_MESSAGE: &str = "without message";
use super::panic_report::PanicReport;

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

impl ReportCreator {}
64 changes: 17 additions & 47 deletions framework/meta-lib/src/tools/wasm_extractor.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
use colored::Colorize;
use std::fs;
use wasmparser::{
BinaryReaderError, DataSectionReader, FunctionBody, ImportSectionReader, Parser, Payload,
BinaryReaderError, DataSectionReader, FunctionBody, ImportSectionReader, Operator, Parser,
Payload,
};

use crate::ei::EIVersion;

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

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>,
Expand Down Expand Up @@ -39,7 +37,7 @@ impl WasmInfo {
}
}

fn populate_wasm_info(
pub(crate) fn populate_wasm_info(
path: String,
wasm_data: Vec<u8>,
extract_imports_enabled: bool,
Expand All @@ -49,25 +47,21 @@ 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 mut has_panic: PanicReport = PanicReport::default();

let parser = Parser::new(0);
for payload in parser.parse_all(&wasm_data) {
match payload? {
Payload::ImportSection(import_section) => {
imports = extract_imports(import_section, extract_imports_enabled);
ei_check = is_ei_valid(imports.clone(), check_ei);
ei_check |= is_ei_valid(imports.clone(), check_ei);
},
Payload::DataSection(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;
}
allocator_trigger |= is_fail_allocator_triggered(data_section.clone());
has_panic.max_severity(data_section);
},
Payload::CodeSectionEntry(code_section) => {
memory_grow_flag = is_mem_grow(code_section);
memory_grow_flag |= is_mem_grow(code_section);
},
_ => (),
}
Expand All @@ -76,7 +70,7 @@ fn populate_wasm_info(
let report = ReportCreator {
path,
has_allocator: allocator_trigger,
has_panic: has_panic.to_string(),
has_panic,
};

Ok(WasmInfo {
Expand Down Expand Up @@ -109,34 +103,6 @@ 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 Expand Up @@ -173,11 +139,15 @@ fn is_ei_valid(imports: Vec<String>, check_ei: &Option<EIVersion>) -> bool {
}

fn is_mem_grow(code_section: FunctionBody) -> bool {
let mut code = code_section.get_binary_reader();
while code.bytes_remaining() > 0 {
if code.read_u8().unwrap() == MEMORY_GROW_OPCODE {
let mut instructions_reader = code_section
.get_operators_reader()
.expect("Failed to get operators reader");

while let Ok(op) = instructions_reader.read() {
if let Operator::MemoryGrow { mem: _ } = op {
return true;
}
}

false
}
Loading

0 comments on commit e41b2a3

Please sign in to comment.