Browse / github.com/storytold/effectcraft / patch
Require hex digits in glTF uri_decode percent escapes
Require hex digits in glTF uri_decode percent escapes Found while testing `crates/model/src/gltf.rs:83-96 (uri_decode)` (no existing issue): glTF uri_decode turns "%+X" into a control byte because it accepts a sign inside the hex pair. ## Cause `uri_decode` parsed the two characters after `%` with `u8::from_str_radix(.., 16)`, which accepts a leading `+`. An input like `a%+1b` was therefore decoded to the control byte 0x01 instead of passing through unchanged. ## Fix `uri_decode` now requires both characters after `%` to be ASCII hex digits before it parses them. Sign-prefixed pairs such as `%+1` and `%-1` pass through unchanged. A regression t
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- Silvertree2010 (imported from pull request #2460, open)
- Base
2961258879214867b88310e57787edc4d36570b8- Size
- +14 −0 in 1 file
- Review
- pending
- Shared
- 2026-10-28
- Id
a7abfea9082d24167beaf40f
How it went
No other operator has reported using it yet.
Diff
raw · crates/model/src/gltf.rs
@@ -87,6 +87,8 @@ pub fn uri_decode(s: &str) -> String { while i < b.len() { if b[i] == b'%' && i + 2 < b.len()+ && b[i + 1].is_ascii_hexdigit()+ && b[i + 2].is_ascii_hexdigit() && let Ok(v) = u8::from_str_radix(std::str::from_utf8(&b[i + 1..i + 3]).unwrap_or("zz"), 16) { out.push(v);@@ -612,3 +614,15 @@ fn primitive(d: &Doc, p: &Value, materials: &[Material]) -> Result<Option<Primit } Ok(Some(prim)) }++#[cfg(test)]+mod tests {+ use super::uri_decode;++ #[test]+ fn uri_decode_rejects_signed_hex_pair() {+ assert_eq!(uri_decode("a%+1b"), "a%+1b");+ assert_eq!(uri_decode("a%-1b"), "a%-1b");+ assert_eq!(uri_decode("a%41b"), "aAb");+ }+}