Skip to content

Commit 94a60ab

Browse files
feat(rust): make PyO3 optional to fix Python 3.14 fuzz linking (#270)
* feat(rust): make PyO3 optional to fix Python 3.14 fuzz linking - Make pyo3 dependency optional behind 'python' feature flag - Add rlib crate-type to support both cdylib (Python) and rlib (fuzzing) - Gate all Python-specific code with #[cfg(feature = "python")] - Make pure Rust functions (escape_xml, wrap_cdata, etc.) public for fuzzing - Add comprehensive unit tests for XML utility functions Fixes linker error with Python 3.14 where PyUnicode_DATA and PyUnicode_KIND symbols are now inline macros, not exported functions. Fuzz targets can now build without linking against Python. Amp-Thread-ID: https://ampcode.com/threads/T-019c0425-ac62-76d8-9d59-4d6aba3edf45 Co-authored-by: Amp <[email protected]> * ci: add Rust unit tests to CI workflow Amp-Thread-ID: https://ampcode.com/threads/T-019c0425-ac62-76d8-9d59-4d6aba3edf45 Co-authored-by: Amp <[email protected]> * refactor: reformat code with rust fmt * fix: improve fuzz test assertion for make_attr_string Use more specific pattern matching (` key="`) instead of just checking if key exists as substring. This avoids false positives with overlapping keys (e.g. 'a' vs 'aa') or malformed attribute formatting. Suggested-by: sourcery-ai Amp-Thread-ID: https://ampcode.com/threads/T-019c0425-ac62-76d8-9d59-4d6aba3edf45 Co-authored-by: Amp <[email protected]> --------- Co-authored-by: Amp <[email protected]>
1 parent d346999 commit 94a60ab

17 files changed

+471
-7
lines changed

.github/workflows/rust-ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ jobs:
3838
working-directory: rust
3939
run: cargo clippy --all-targets --all-features -- -D warnings
4040

41+
- name: Run Rust unit tests
42+
working-directory: rust
43+
run: cargo test --no-default-features
44+
4145
rust-test:
4246
name: Build & Test (${{ matrix.os }}, Python ${{ matrix.python-version }})
4347
runs-on: ${{ matrix.os }}

rust/Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@ license = "Apache-2.0"
77

88
[lib]
99
name = "json2xml_rs"
10-
crate-type = ["cdylib"]
10+
crate-type = ["cdylib", "rlib"]
11+
12+
[features]
13+
default = ["python"]
14+
python = ["pyo3/extension-module", "dep:pyo3"]
1115

1216
[dependencies]
13-
pyo3 = { version = "0.27", features = ["extension-module"] }
17+
pyo3 = { version = "0.27", optional = true }
1418

1519
[profile.release]
1620
lto = true

rust/fuzz/Cargo.toml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
[package]
2+
name = "json2xml_rs-fuzz"
3+
version = "0.0.0"
4+
publish = false
5+
edition = "2021"
6+
7+
[package.metadata]
8+
cargo-fuzz = true
9+
10+
[dependencies]
11+
libfuzzer-sys = "0.4"
12+
arbitrary = { version = "1", features = ["derive"] }
13+
14+
[dependencies.json2xml_rs]
15+
path = ".."
16+
default-features = false
17+
18+
[[bin]]
19+
name = "fuzz_escape_xml"
20+
path = "fuzz_targets/fuzz_escape_xml.rs"
21+
test = false
22+
doc = false
23+
bench = false
24+
25+
[[bin]]
26+
name = "fuzz_wrap_cdata"
27+
path = "fuzz_targets/fuzz_wrap_cdata.rs"
28+
test = false
29+
doc = false
30+
bench = false
31+
32+
[[bin]]
33+
name = "fuzz_is_valid_xml_name"
34+
path = "fuzz_targets/fuzz_is_valid_xml_name.rs"
35+
test = false
36+
doc = false
37+
bench = false
38+
39+
[[bin]]
40+
name = "fuzz_make_valid_xml_name"
41+
path = "fuzz_targets/fuzz_make_valid_xml_name.rs"
42+
test = false
43+
doc = false
44+
bench = false
45+
46+
[[bin]]
47+
name = "fuzz_make_attr_string"
48+
path = "fuzz_targets/fuzz_make_attr_string.rs"
49+
test = false
50+
doc = false
51+
bench = false
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
]I]]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
����
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
]]J(
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
]](
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
]J(

0 commit comments

Comments
 (0)