Skip to content

fix: resolve the input path against the root before making it virtual - #1

Closed
msallin wants to merge 1 commit into
developfrom
fix/input-path-virtualize
Closed

fix: resolve the input path against the root before making it virtual#1
msallin wants to merge 1 commit into
developfrom
fix/input-path-virtualize

Conversation

@msallin

@msallin msallin commented Sep 4, 2026

Copy link
Copy Markdown
Member

Problem

A Typst virtual path only accepts forward slashes. SystemWorld::new handed the caller's input path to VirtualPath::new verbatim and unwrapped the result, so on Windows an ordinary relative path such as templates\letter.typ failed to convert and panicked.

The panic happens inside create_compiler, which is extern "C" and has no unwind guard. A panic cannot unwind out of an extern "C" frame, so the process aborts rather than the call failing. Running the new tests against develop:

13: create_compiler
14: input_path::compiler_for_file
thread caused non-unwinding panic. aborting.
process didn't exit successfully (signal: 6, SIGABRT: process abort signal)

For a service on Windows, or any layout that sets an explicit root and keeps templates in a subfolder, this terminates the host process on the first compile with no managed exception. A .. component in the path does the same.

Change

Relative paths are joined onto the project root, then converted with VirtualPath::virtualize, which splits on the platform separator and performs the root containment check itself. A path that escapes the root now returns an error through the existing channel instead of panicking.

The manual to_str UTF-8 check is dropped because virtualize reports that case as VirtualizeError::Utf8. The <main> unwrap becomes an expect naming the invariant.

This does not add an unwind guard to create_compiler; that is a separate concern and other panic sources remain.

Tests

New src/typst_core/tests/input_path.rs covers a nested relative path, the equivalent absolute path, a relative path escaping the root, and an absolute path outside the root. New tests in Tests.cs cover the same cases through the managed API.

All four Rust tests abort the test binary against develop and pass with the change.

cargo test --release    7 passed
dotnet test            48 passed

A Typst virtual path only accepts forward slashes, and `VirtualPath::new`
was handed the caller's path verbatim. On Windows an ordinary relative path
such as `templates\letter.typ` therefore failed to convert, and the `unwrap`
turned that into a panic inside `create_compiler`. That function is
`extern "C"` and has no unwind guard, so the panic aborted the whole host
process rather than failing the single call.

Relative paths are now joined onto the project root and converted with
`VirtualPath::virtualize`, which splits on the platform separator and does
the root containment check itself. A path that genuinely escapes the root
reports an error through the existing channel instead of panicking, and the
manual UTF-8 check is no longer needed because `virtualize` covers it.
@msallin
msallin force-pushed the fix/input-path-virtualize branch from fbe3674 to c66c2df Compare September 4, 2026 11:19
@msallin

msallin commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

Superseded by evolvedlight#37; the fix belongs upstream.

@msallin msallin closed this Sep 4, 2026
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.

1 participant