| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info ⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: 559dbb75-ba64-4411-a89f-38b8ef83c027 📥 CommitsReviewing files that changed from the base of the PR and between 4241c83 and 9530575. 📒 Files selected for processing (1)
📝 Walkthrough WalkthroughThis PR adds four new C-ABI exported functions (PyObject_Call, PyObject_CallNoArgs, PyObject_Vectorcall, PyObject_VectorcallMethod) to RustPython's C-API layer. These functions enable external C code to invoke Python objects with various calling conventions, converting raw C pointers and argument arrays into VM-compatible argument structures before dispatching through the Rust VM. ChangesC-API object calling
Sequence DiagramsequenceDiagram
participant CCaller as External C Code
participant CallVec as PyObject_Vectorcall
participant CallMethod as PyObject_VectorcallMethod
participant VM as Rust VM
CCaller->>CallVec: callable, args_ptr, nargsf, kwnames
CallVec->>CallVec: extract pos_count from nargsf (nargsf - offset)
CallVec->>CallVec: optionally decode kwnames into keyword slice
CallVec->>CallVec: materialize args_ptr into Rust vector
CallVec->>VM: vectorcall(callable, posargs, kwnames)
VM-->>CallVec: PyObject* result
CallVec-->>CCaller: result
CCaller->>CallMethod: name, args_ptr, nargsf, kwnames
CallMethod->>CallMethod: validate args_len > 0 (receiver present)
CallMethod->>CallMethod: extract receiver from args[0]
CallMethod->>CallMethod: resolve attribute by name to callable
CallMethod->>CallVec: call with receiver removed from args
CallVec->>VM: vectorcall(method, adjusted_args, kwnames)
VM-->>CallVec: PyObject* result
CallVec-->>CallMethod: result
CallMethod-->>CCaller: result
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested Reviewers
Poem🚥 Pre-merge checks | ✅ 4 | ❌ 1 ❌ Failed checks (1 warning)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches 🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. ❤️ ShareComment @coderabbitai help to get the list of available commands and usage tips. |
Sorry, something went wrong.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agentsVerify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. Inline comments: In `@crates/capi/src/abstract_.rs`: - Around line 50-54: The code constructs a slice from a potentially NULL pointer when computing args: change the logic in the vectorcall handler so that if args_len == 0 you directly return an empty Vec, otherwise call unsafe slice::from_raw_parts(args, args_len) and map/collect as before; specifically update the block that references args_len, num_positional_args, kwnames and args to short-circuit on args_len == 0 (mirror the pattern used by PyObject_VectorcallMethod) to avoid undefined behavior from slice::from_raw_parts on a NULL pointer.
Fix all unresolved CodeRabbit comments on this PR:
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 3028c37c-9c9d-4595-9896-6b445ccdc4cf
📥 CommitsReviewing files that changed from the base of the PR and between ae3804f and a07d3dd.
📒 Files selected for processing (2)
Sorry, something went wrong.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)crates/capi/src/abstract_.rs (1)91-101: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win
Missing keyword argument value count in args_len calculation causes out-of-bounds read.
The args_len at line 91 extracts only the positional argument count (nargsf & !PY_VECTORCALL_ARGUMENTS_OFFSET), but per the vectorcall protocol, the raw args array contains both positional arguments and keyword argument values in sequence: [receiver, pos_arg_1, ..., pos_arg_N, kwarg_val_1, ..., kwarg_val_M].
Creating the slice with only the positional count omits the keyword argument values. When the slice pointer is passed to PyObject_Vectorcall along with the original kwnames, that function attempts to read keyword argument values beyond the slice boundary, causing undefined behavior.
The fix is to compute args_len to include both positional and keyword argument value counts, mirroring the calculation in PyObject_Vectorcall at line 68.
Proposed fix: include kwarg values in args_len🤖 Prompt for AI Agents- let args_len = nargsf & !PY_VECTORCALL_ARGUMENTS_OFFSET; + let num_positional_args = nargsf & !PY_VECTORCALL_ARGUMENTS_OFFSET; + + let kwnames_len = unsafe { + kwnames + .as_ref() + .map(|tuple| tuple.try_downcast_ref::<PyTuple>(vm).map(|t| t.len())) + .transpose()? + .unwrap_or(0) + }; + + let args_len = num_positional_args + kwnames_len;Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/capi/src/abstract_.rs` around lines 91 - 101, The slice length calculation for args_len wrongly uses only positional count (nargsf & !PY_VECTORCALL_ARGUMENTS_OFFSET), which omits keyword argument values and can cause out-of-bounds reads when PyObject_Vectorcall expects them; update the args_len computation to add the keyword value count when kwnames is non-null (mirror the same calculation used by PyObject_Vectorcall), i.e. derive the keyword count from nargsf (using PY_VECTORCALL_ARGUMENTS_OFFSET mask) and include it in args_len before creating the slice for receiver/args so the full [receiver, pos..., kw_vals...] region is covered.
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. Outside diff comments: In `@crates/capi/src/abstract_.rs`: - Around line 91-101: The slice length calculation for args_len wrongly uses only positional count (nargsf & !PY_VECTORCALL_ARGUMENTS_OFFSET), which omits keyword argument values and can cause out-of-bounds reads when PyObject_Vectorcall expects them; update the args_len computation to add the keyword value count when kwnames is non-null (mirror the same calculation used by PyObject_Vectorcall), i.e. derive the keyword count from nargsf (using PY_VECTORCALL_ARGUMENTS_OFFSET mask) and include it in args_len before creating the slice for receiver/args so the full [receiver, pos..., kw_vals...] region is covered.
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: ae630f7a-1a5a-4707-8032-1e0a144ef418
📥 CommitsReviewing files that changed from the base of the PR and between 6d47176 and 4241c83.
📒 Files selected for processing (2)
Sorry, something went wrong.
|
@coderabbitai your last comment is not correct. Because the pointer to pos_arg_1 points to the start of the array, and the array still contains the keywords arguments after it. It does not patter we do not count the kwargs in the slice. |
Sorry, something went wrong.
|
Tip For best results, initiate chat on the files or code changes. 🏁 Script executed: #!/bin/bash cat crates/capi/src/abstract_.rs Length of output: 5025 @bschoenmaeckers You're absolutely right, and I apologize for the incorrect comment. Looking at the code again: In PyObject_VectorcallMethod, the slice is only created over the positional-arg count in order to call .split_first() and peel off the receiver: let (receiver, args) = unsafe { slice::from_raw_parts(args, args_len) }
.split_first()
.expect("args_len > 0 should guarantee a receiver");The resulting args.as_ptr() still points into the original contiguous buffer — keyword argument values are sitting right after the positional ones in that same allocation (as mandated by the vectorcall convention). When that pointer is forwarded to PyObject_Vectorcall, it recomputes the full length as num_positional_args + kwnames.len() and reads the complete buffer (positional + kwarg values) correctly. The intermediate short slice is only ever used for the split, so nothing is lost. The code is correct as written. (ミ・ω・ミ) ✏️ Learnings added Learnt from: bschoenmaeckers URL: https://github.com/RustPython/RustPython/pull/7937 Timestamp: 2026-05-20T14:27:24.682Z Learning: In RustPython's C-API vectorcall implementation (`crates/capi/src/abstract_.rs`), `PyObject_VectorcallMethod` creates a slice over only the positional-argument count solely to extract the receiver via `split_first()`. The resulting pointer (`args.as_ptr()`) still addresses the full contiguous buffer (positional + kwarg values). When forwarded to `PyObject_Vectorcall`, the full `args_len` (positional + kwnames count) is recomputed there and the complete buffer is read correctly. The short intermediate slice is intentional and correct.
|
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Summary by CodeRabbit