Skip to content

Commit 46bfb04

Browse files
fnandomootz12
andauthored
Fix xdr_to_json panic when output type is Val. (#2474)
### What Handle other types when printing values using xdr_to_json. ### Why Fix #2469. ### Known limitations [TODO or N/A] --------- Co-authored-by: mootz12 <38118608+mootz12@users.noreply.github.com>
1 parent ceb34a6 commit 46bfb04

File tree

1 file changed

+64
-0
lines changed
  • cmd/crates/soroban-spec-tools/src

1 file changed

+64
-0
lines changed

cmd/crates/soroban-spec-tools/src/lib.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,11 @@ impl Spec {
585585
(val, ScType::Result(inner)) => self.xdr_to_json(val, &inner.ok_type)?,
586586

587587
(val, ScType::Option(inner)) => self.xdr_to_json(val, &inner.value_type)?,
588+
589+
// ScType::Val is the generic Soroban value type that can hold any ScVal.
590+
// Delegate to to_json which handles all ScVal variants without type info.
591+
(val, ScType::Val) => to_json(val)?,
592+
588593
(ScVal::Map(Some(_)) | ScVal::Vec(Some(_)) | ScVal::U32(_), type_) => {
589594
self.sc_object_to_json(val, type_)?
590595
}
@@ -2450,4 +2455,63 @@ mod tests {
24502455
let json = spec.sc_map_to_json(&sc_map, &map_type).unwrap();
24512456
assert_eq!(json.to_string(), r#"{"foo":2}"#);
24522457
}
2458+
2459+
#[test]
2460+
fn test_xdr_to_json_bytes_with_val_type() {
2461+
// Regression test for https://github.com/stellar/stellar-cli/issues/2469
2462+
// When a contract function returns ScType::Val and the runtime value is
2463+
// ScVal::Bytes (e.g. BytesN<32>), xdr_to_json should succeed instead of
2464+
// panicking with "doesn't have a matching Val".
2465+
let spec = Spec(None);
2466+
let bytes_val = ScVal::Bytes(ScBytes(
2467+
vec![
2468+
0x05, 0x5e, 0xf8, 0x16, 0x22, 0x3e, 0xe5, 0x21, 0x6b, 0x18, 0xc2, 0xdf, 0x00, 0xd6,
2469+
0x15, 0xee, 0x08, 0x9a, 0x8e, 0xf1, 0x1b, 0x92, 0x7a, 0x76, 0x4e, 0x4f, 0x5d, 0x6c,
2470+
0x0c, 0xb4, 0xf4, 0xc7,
2471+
]
2472+
.try_into()
2473+
.unwrap(),
2474+
));
2475+
let result = spec.xdr_to_json(&bytes_val, &ScType::Val);
2476+
assert_eq!(
2477+
result.unwrap(),
2478+
Value::String(
2479+
"055ef816223ee5216b18c2df00d615ee089a8ef11b927a764e4f5d6c0cb4f4c7".to_string()
2480+
)
2481+
);
2482+
}
2483+
2484+
#[test]
2485+
fn test_xdr_to_json_map_with_val_type() {
2486+
// ScVal::Map with ScType::Val should delegate to to_json, not sc_object_to_json.
2487+
let spec = Spec(None);
2488+
let map_val = ScVal::Map(Some(
2489+
ScMap::sorted_from(vec![ScMapEntry {
2490+
key: ScVal::Symbol(ScSymbol("key".try_into().unwrap())),
2491+
val: ScVal::U32(42),
2492+
}])
2493+
.unwrap(),
2494+
));
2495+
let result = spec.xdr_to_json(&map_val, &ScType::Val);
2496+
assert!(result.is_ok(), "Map with ScType::Val should not error");
2497+
}
2498+
2499+
#[test]
2500+
fn test_xdr_to_json_vec_with_val_type() {
2501+
// ScVal::Vec with ScType::Val should delegate to to_json, not sc_object_to_json.
2502+
let spec = Spec(None);
2503+
let vec_val = ScVal::Vec(Some(
2504+
ScVec::try_from(vec![ScVal::U32(1), ScVal::U32(2)]).unwrap(),
2505+
));
2506+
let result = spec.xdr_to_json(&vec_val, &ScType::Val);
2507+
assert!(result.is_ok(), "Vec with ScType::Val should not error");
2508+
}
2509+
2510+
#[test]
2511+
fn test_xdr_to_json_u32_with_val_type() {
2512+
// ScVal::U32 with ScType::Val should delegate to to_json, not sc_object_to_json.
2513+
let spec = Spec(None);
2514+
let result = spec.xdr_to_json(&ScVal::U32(100), &ScType::Val);
2515+
assert_eq!(result.unwrap(), Value::Number(100.into()));
2516+
}
24532517
}

0 commit comments

Comments
 (0)