Skip to content

Unify nul errors#8339

Open
joshuamegnauth54 wants to merge 1 commit into
RustPython:mainfrom
joshuamegnauth54:unify-nul-errors
Open

Unify nul errors#8339
joshuamegnauth54 wants to merge 1 commit into
RustPython:mainfrom
joshuamegnauth54:unify-nul-errors

Conversation

@joshuamegnauth54

@joshuamegnauth54 joshuamegnauth54 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Part of #8245 to reduce the amount of work needed to review. I simplified the embedded nul errors by forwarding to the implementations in vm::exceptions.

Summary

Summary by CodeRabbit

  • Bug Fixes
    • Standardized Python exceptions for embedded NUL characters and NUL bytes across path handling, codecs, text I/O, environment/process APIs, multiprocessing semaphores, and system/OS calls.
    • Added dedicated NUL-focused error types and improved ValueError vs TypeError behavior for NUL-containing inputs (including SSL/TLS hostname/cipher/curve handling).
    • Improved error propagation in time and sound operations by preserving the underlying failure details instead of using generic embedded-NUL messages.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: c122977b-9578-4efd-970a-62f9d4f7e9ed

📥 Commits

Reviewing files that changed from the base of the PR and between 07d6c70 and d127606.

📒 Files selected for processing (16)
  • crates/stdlib/src/grp.rs
  • crates/stdlib/src/multiprocessing.rs
  • crates/stdlib/src/openssl.rs
  • crates/stdlib/src/ssl.rs
  • crates/vm/src/buffer.rs
  • crates/vm/src/exceptions.rs
  • crates/vm/src/function/fspath.rs
  • crates/vm/src/stdlib/_codecs.rs
  • crates/vm/src/stdlib/_io.rs
  • crates/vm/src/stdlib/_winapi.rs
  • crates/vm/src/stdlib/nt.rs
  • crates/vm/src/stdlib/os.rs
  • crates/vm/src/stdlib/pwd.rs
  • crates/vm/src/stdlib/time.rs
  • crates/vm/src/stdlib/winsound.rs
  • crates/vm/src/utils.rs
🚧 Files skipped from review as they are similar to previous changes (13)
  • crates/vm/src/function/fspath.rs
  • crates/vm/src/stdlib/nt.rs
  • crates/vm/src/stdlib/pwd.rs
  • crates/vm/src/stdlib/_io.rs
  • crates/stdlib/src/grp.rs
  • crates/vm/src/stdlib/time.rs
  • crates/stdlib/src/ssl.rs
  • crates/vm/src/buffer.rs
  • crates/vm/src/stdlib/_codecs.rs
  • crates/stdlib/src/openssl.rs
  • crates/vm/src/exceptions.rs
  • crates/stdlib/src/multiprocessing.rs
  • crates/vm/src/stdlib/winsound.rs

📝 Walkthrough

Walkthrough

The change introduces shared embedded-NUL error types and helpers, updates Rust error conversions, and replaces hard-coded or generic NUL-related exceptions across VM and standard-library paths.

Changes

Embedded-NUL exception standardization

Layer / File(s) Summary
Centralized NUL error contract
crates/vm/src/exceptions.rs, crates/vm/src/buffer.rs
Adds NulError, character/byte error helpers, updated ToPyException mappings, and standardized buffer-format parsing errors.
VM NUL validation paths
crates/vm/src/function/fspath.rs, crates/vm/src/stdlib/*, crates/vm/src/utils.rs
Routes NUL validation and Rust conversion failures through standardized character or byte exceptions.
Standard-library NUL validation paths
crates/stdlib/src/grp.rs, crates/stdlib/src/multiprocessing.rs, crates/stdlib/src/openssl.rs, crates/stdlib/src/ssl.rs
Updates group, semaphore, OpenSSL, and SSL hostname handling to use standardized NUL exceptions.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: shaharnaveh, youknowone

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.62% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main change: standardizing NUL-related errors across the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ShaharNaveh ShaharNaveh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't realized it duplicated like that. tysm!

@joshuamegnauth54
joshuamegnauth54 marked this pull request as draft July 20, 2026 19:34

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
crates/vm/src/stdlib/time.rs (1)

571-578: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use a helper closure to deduplicate the ASCII buffer flush logic.

The logic for flushing ascii to out is duplicated three times. Consider extracting it into a closure to improve maintainability.

♻️ Proposed refactor
         let mut out = Wtf8Buf::new();
         let mut ascii = String::new();
 
+        let mut flush_ascii = |ascii: &mut String, out: &mut Wtf8Buf| -> PyResult<()> {
+            if !ascii.is_empty() {
+                let part =
+                    host_time::strftime_ascii(ascii, &tm).map_err(|e| e.to_pyexception(vm))?;
+                out.extend(part.chars());
+                ascii.clear();
+            }
+            Ok(())
+        };
+
         for codepoint in format.as_wtf8().code_points() {
             if codepoint.to_u32() == 0 {
-                if !ascii.is_empty() {
-                    let part =
-                        host_time::strftime_ascii(&ascii, &tm).map_err(|e| e.to_pyexception(vm))?;
-                    out.extend(part.chars());
-                    ascii.clear();
-                }
+                flush_ascii(&mut ascii, &mut out)?;
                 out.push(codepoint);
                 continue;
             }
             if let Some(ch) = codepoint.to_char()
                 && ch.is_ascii()
             {
                 ascii.push(ch);
                 continue;
             }
 
-            if !ascii.is_empty() {
-                let part =
-                    host_time::strftime_ascii(&ascii, &tm).map_err(|e| e.to_pyexception(vm))?;
-                out.extend(part.chars());
-                ascii.clear();
-            }
+            flush_ascii(&mut ascii, &mut out)?;
             out.push(codepoint);
         }
-        if !ascii.is_empty() {
-            let part = host_time::strftime_ascii(&ascii, &tm).map_err(|e| e.to_pyexception(vm))?;
-            out.extend(part.chars());
-        }
+        flush_ascii(&mut ascii, &mut out)?;
         Ok(out.to_pyobject(vm))

Also applies to: 589-598

🤖 Prompt for AI Agents
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/vm/src/stdlib/time.rs` around lines 571 - 578, In the time-formatting
loop, extract the repeated non-empty `ascii` buffer flush into a local helper
closure that calls `host_time::strftime_ascii`, extends `out`, and clears
`ascii`; replace all three duplicated flush blocks with this closure while
preserving error propagation and existing output behavior.
🤖 Prompt for all review comments with AI agents
Verify 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/vm/src/stdlib/nt.rs`:
- Line 555: Update the error return in the null-character handling path to call
nul_char_error through its fully qualified exceptions module path and pass the
in-scope vm argument.

In `@crates/vm/src/stdlib/winsound.rs`:
- Line 145: Update the error return in the winsound function to reference the
exceptions module through its fully qualified path, preserving the existing
nul_char_error(vm) behavior without adding an import.

---

Nitpick comments:
In `@crates/vm/src/stdlib/time.rs`:
- Around line 571-578: In the time-formatting loop, extract the repeated
non-empty `ascii` buffer flush into a local helper closure that calls
`host_time::strftime_ascii`, extends `out`, and clears `ascii`; replace all
three duplicated flush blocks with this closure while preserving error
propagation and existing output behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 9bbc6a49-f35c-4f0b-b376-cd49a5c8e422

📥 Commits

Reviewing files that changed from the base of the PR and between cc30cd5 and 31b6e13.

📒 Files selected for processing (15)
  • crates/stdlib/src/grp.rs
  • crates/stdlib/src/multiprocessing.rs
  • crates/stdlib/src/openssl.rs
  • crates/stdlib/src/ssl.rs
  • crates/vm/src/buffer.rs
  • crates/vm/src/exceptions.rs
  • crates/vm/src/function/fspath.rs
  • crates/vm/src/stdlib/_codecs.rs
  • crates/vm/src/stdlib/_io.rs
  • crates/vm/src/stdlib/nt.rs
  • crates/vm/src/stdlib/os.rs
  • crates/vm/src/stdlib/pwd.rs
  • crates/vm/src/stdlib/time.rs
  • crates/vm/src/stdlib/winsound.rs
  • crates/vm/src/utils.rs

Comment thread crates/vm/src/stdlib/nt.rs Outdated
Comment thread crates/vm/src/stdlib/winsound.rs
@joshuamegnauth54
joshuamegnauth54 marked this pull request as ready for review July 21, 2026 01:19
@joshuamegnauth54

Copy link
Copy Markdown
Contributor Author

Additionally, MissingNulTerminator now raises an exception with the correct message. The original message was "embedded null character," but the error is for byte slices that lack any NULs.

Part of RustPython#8245 to reduce the amount of work needed to review. I
simplified the embedded nul errors by forwarding to the implementations
in `vm::exceptions`.
@joshuamegnauth54

Copy link
Copy Markdown
Contributor Author

See #8343 for info on the Ubuntu failure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants