-
Notifications
You must be signed in to change notification settings - Fork 29.1k
Initial MCP implementation #81770
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial MCP implementation #81770
Changes from all commits
cd98bbf
7f59fb3
aea6cf6
27c6f10
3fd17f5
b3353b8
198b792
72e3f29
f546d5a
6e82f59
2774be3
a1ce1e2
a80b467
4f133ae
2403784
7549f95
684940b
17481c1
1c9d2b2
6368312
c98260f
dc2c534
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
pub mod endpoint; | ||
pub mod module_graph; | ||
pub mod project; | ||
pub mod turbopack_ctx; | ||
pub mod utils; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
use next_api::module_graph_snapshot::{ModuleGraphSnapshot, ModuleInfo, ModuleReference}; | ||
use turbo_rcstr::RcStr; | ||
use turbopack_core::chunk::ChunkingType; | ||
|
||
#[napi(object)] | ||
pub struct NapiModuleReference { | ||
/// The index of the referenced/referencing module in the modules list. | ||
pub index: u32, | ||
/// The export used in the module reference. | ||
pub export: String, | ||
/// The type of chunking for the module reference. | ||
pub chunking_type: String, | ||
} | ||
|
||
impl From<&ModuleReference> for NapiModuleReference { | ||
fn from(reference: &ModuleReference) -> Self { | ||
Self { | ||
index: reference.index as u32, | ||
export: reference.export.to_string(), | ||
chunking_type: match &reference.chunking_type { | ||
ChunkingType::Parallel { hoisted: true, .. } => "hoisted".to_string(), | ||
ChunkingType::Parallel { hoisted: false, .. } => "sync".to_string(), | ||
ChunkingType::Async => "async".to_string(), | ||
ChunkingType::Isolated { | ||
merge_tag: None, .. | ||
} => "isolated".to_string(), | ||
ChunkingType::Isolated { | ||
merge_tag: Some(name), | ||
.. | ||
} => format!("isolated {name}"), | ||
ChunkingType::Shared { | ||
merge_tag: None, .. | ||
} => "shared".to_string(), | ||
ChunkingType::Shared { | ||
merge_tag: Some(name), | ||
.. | ||
} => format!("shared {name}"), | ||
ChunkingType::Traced => "traced".to_string(), | ||
}, | ||
} | ||
} | ||
} | ||
|
||
#[napi(object)] | ||
pub struct NapiModuleInfo { | ||
pub ident: RcStr, | ||
pub path: RcStr, | ||
pub depth: u32, | ||
pub size: u32, | ||
pub retained_size: u32, | ||
pub references: Vec<NapiModuleReference>, | ||
pub incoming_references: Vec<NapiModuleReference>, | ||
} | ||
|
||
impl From<&ModuleInfo> for NapiModuleInfo { | ||
fn from(info: &ModuleInfo) -> Self { | ||
Self { | ||
ident: info.ident.clone(), | ||
path: info.path.clone(), | ||
depth: info.depth, | ||
size: info.size, | ||
retained_size: info.retained_size, | ||
references: info | ||
.references | ||
.iter() | ||
.map(NapiModuleReference::from) | ||
.collect(), | ||
incoming_references: info | ||
.incoming_references | ||
.iter() | ||
.map(NapiModuleReference::from) | ||
.collect(), | ||
} | ||
} | ||
} | ||
|
||
#[napi(object)] | ||
#[derive(Default)] | ||
pub struct NapiModuleGraphSnapshot { | ||
pub modules: Vec<NapiModuleInfo>, | ||
pub entries: Vec<u32>, | ||
} | ||
|
||
impl From<&ModuleGraphSnapshot> for NapiModuleGraphSnapshot { | ||
fn from(snapshot: &ModuleGraphSnapshot) -> Self { | ||
Self { | ||
modules: snapshot.modules.iter().map(NapiModuleInfo::from).collect(), | ||
entries: snapshot | ||
.entries | ||
.iter() | ||
.map(|&i| { | ||
// If you have more that 4294967295 entries, you probably have other problems... | ||
i.try_into().unwrap() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential panic due to integer overflow when converting module entry indices from usize to u32. View DetailsAnalysisThe code converts The RecommendationReplace .map(|&i| {
i.try_into().unwrap_or_else(|_| {
// Log error and use max value as fallback
tracing::warn!("Module entry index {} exceeds u32::MAX, using u32::MAX", i);
u32::MAX
})
}) Or consider changing the NAPI interface to use larger integer types if needed. 👍 or 👎 to improve Vade. |
||
}) | ||
.collect(), | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Silent integer truncation when converting module reference indices from usize to u32.
View Details
Analysis
The code uses an
as
cast to convertreference.index
fromusize
tou32
. This will silently truncate values larger thanu32::MAX
on 64-bit systems, potentially causing incorrect module references and broken module graph relationships.The
ModuleReference.index
field isusize
butNapiModuleReference.index
isu32
. When the index exceedsu32::MAX
, the cast will wrap around, leading to incorrect array access patterns in the JavaScript layer.Recommendation
Replace the
as
cast with a checked conversion:This ensures the issue is logged when it occurs and provides a safer fallback value.
👍 or 👎 to improve Vade.