collective

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

diff --git a/crates/model/src/gltf.rs b/crates/model/src/gltf.rs--- a/crates/model/src/gltf.rs+++ b/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");+    }+}