Skip to content

Commit 6ebb39e

Browse files
committed
Implement return value modification
1 parent 3dac9f9 commit 6ebb39e

File tree

11 files changed

+396
-128
lines changed

11 files changed

+396
-128
lines changed

instrumentation-wasm/Cargo.lock

Lines changed: 32 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

instrumentation-wasm/Cargo.toml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ name = "node_code_instrumentation"
1010
crate-type = ["cdylib", "rlib"]
1111

1212
[dependencies]
13-
oxc_allocator = "0.72.0"
14-
oxc_ast = "0.72.0"
15-
oxc_codegen = "0.72.0"
16-
oxc_parser = "0.72.0"
17-
oxc_semantic = "0.72.0"
18-
oxc_span = "0.72.0"
19-
oxc_traverse = "0.72.0"
13+
oxc_allocator = "0.72.2"
14+
oxc_ast = "0.72.2"
15+
oxc_codegen = "0.72.2"
16+
oxc_parser = "0.72.2"
17+
oxc_semantic = "0.72.2"
18+
oxc_span = "0.72.2"
19+
oxc_traverse = "0.72.2"
2020
serde = "1.0.219"
2121
serde_json = "1.0.140"
2222
wasm-bindgen = "0.2.100"

instrumentation-wasm/src/js_transformer/helpers/get_import_code_str.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use oxc_span::SourceType;
33
pub fn get_import_code_str(source_type: &SourceType, has_module_syntax: bool) -> &'static str {
44
// Todo maybe import only needed functions, not sure if it is worth it
55
if source_type.is_script() || source_type.is_unambiguous() && !has_module_syntax {
6-
return "const { __instrumentInspectArgs, __instrumentModifyArgs } = require('@aikidosec/firewall/instrument/internals');";
6+
return "const { __instrumentInspectArgs, __instrumentModifyArgs, __instrumentModifyReturnValue } = require('@aikidosec/firewall/instrument/internals');";
77
}
88

9-
"import { __instrumentInspectArgs, __instrumentModifyArgs } from '@aikidosec/firewall/instrument/internals';"
9+
"import { __instrumentInspectArgs, __instrumentModifyArgs, __instrumentModifyReturnValue } from '@aikidosec/firewall/instrument/internals';"
1010
}

instrumentation-wasm/src/js_transformer/helpers/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ pub mod get_name_str_for_member_expr;
44
pub mod insert_code;
55
pub mod parse_js_code_to_statements;
66
pub mod select_sourcetype_based_on_enum;
7+
pub mod transform_return_statements;

instrumentation-wasm/src/js_transformer/helpers/parse_js_code_to_statements.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use oxc_ast::ast::Statement;
33
use oxc_parser::{ParseOptions, Parser};
44
use oxc_span::SourceType;
55

6+
// Todo replace with AstBuilder in the future, most likely better performance
67
pub fn parse_js_code_to_statements<'a>(
78
allocator: &'a Allocator,
89
source_text: &'a str,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use oxc_allocator::{Allocator, Box, Vec};
2+
use oxc_ast::{
3+
ast::{Argument, FunctionBody, Statement},
4+
AstBuilder, NONE,
5+
};
6+
use oxc_span::SPAN;
7+
8+
pub fn transform_return_statements<'a>(
9+
allocator: &'a Allocator,
10+
identifier: &str,
11+
body: &mut Box<'a, FunctionBody<'a>>,
12+
) {
13+
// Iterate through the statements in the function body
14+
for statement in &mut body.statements {
15+
let builder = AstBuilder::new(&allocator);
16+
17+
match statement {
18+
Statement::ReturnStatement(return_stmt) => {
19+
let mut instrument_args: Vec<'a, Argument<'a>> = builder.vec_with_capacity(2);
20+
21+
// Add the identifier to the arguments
22+
instrument_args.push(Argument::StringLiteral(builder.alloc_string_literal(
23+
SPAN,
24+
allocator.alloc_str(identifier),
25+
None,
26+
)));
27+
// Add original return value as the second argument
28+
let arg_expr = return_stmt
29+
.argument
30+
.take()
31+
.unwrap_or_else(|| builder.expression_identifier(SPAN, "undefined"));
32+
instrument_args.push(arg_expr.into());
33+
34+
let new_call_expr = builder.expression_call(
35+
SPAN,
36+
builder.expression_identifier(SPAN, "__instrumentModifyReturnValue"),
37+
NONE,
38+
instrument_args,
39+
false,
40+
);
41+
42+
// Replace the return statement with a call to the identifier
43+
return_stmt.argument = Some(new_call_expr);
44+
}
45+
_ => {
46+
// Ignore
47+
continue;
48+
}
49+
}
50+
}
51+
}

instrumentation-wasm/src/js_transformer/transformer_impl.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use super::helpers::{
77
get_arg_names::get_method_arg_names,
88
get_name_str_for_member_expr::get_name_str_for_member_expr,
99
insert_code::{insert_inspect_args, insert_modify_args},
10+
transform_return_statements::transform_return_statements,
1011
};
1112
use super::instructions::FileInstructions;
1213

@@ -74,7 +75,9 @@ impl<'a> Traverse<'a> for Transformer<'a> {
7475
);
7576
}
7677

77-
// Todo support return value modification
78+
if instruction.modify_return_value {
79+
transform_return_statements(self.allocator, &instruction.identifier, body);
80+
}
7881
}
7982

8083
fn enter_assignment_expression(
@@ -148,6 +151,8 @@ impl<'a> Traverse<'a> for Transformer<'a> {
148151
);
149152
}
150153

151-
// Todo support return value modification
154+
if instruction.modify_return_value {
155+
transform_return_statements(self.allocator, &instruction.identifier, body);
156+
}
152157
}
153158
}

0 commit comments

Comments
 (0)