Reject subclasses of marshallable types (int, float, complex, tuple, etc.). Recursively check that no code objects are present.
(obj: &PyObjectRef, vm: &VirtualMachine)
| 552 | /// Reject subclasses of marshallable types (int, float, complex, tuple, etc.). |
| 553 | /// Recursively check that no code objects are present. |
| 554 | fn check_no_code(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { |
| 555 | if obj.downcast_ref::<PyCode>().is_some() { |
| 556 | return Err(vm.new_value_error("unmarshalling code objects is disallowed".to_string())); |
| 557 | } |
| 558 | if let Some(tup) = obj.downcast_ref::<PyTuple>() { |
| 559 | for elem in tup.as_slice() { |
| 560 | check_no_code(elem, vm)?; |
| 561 | } |
| 562 | } else if let Some(list) = obj.downcast_ref::<PyList>() { |
| 563 | for elem in list.borrow_vec().iter() { |
| 564 | check_no_code(elem, vm)?; |
| 565 | } |
| 566 | } else if let Some(set) = obj.downcast_ref::<PySet>() { |
| 567 | for elem in set.elements() { |
| 568 | check_no_code(&elem, vm)?; |
| 569 | } |
| 570 | } else if let Some(fset) = obj.downcast_ref::<PyFrozenSet>() { |
| 571 | for elem in fset.elements() { |
| 572 | check_no_code(&elem, vm)?; |
| 573 | } |
| 574 | } else if let Some(dict) = obj.downcast_ref::<PyDict>() { |
| 575 | for (k, v) in dict.into_iter() { |
| 576 | check_no_code(&k, vm)?; |
| 577 | check_no_code(&v, vm)?; |
| 578 | } |
| 579 | } |
| 580 | Ok(()) |
| 581 | } |
| 582 | |
| 583 | fn check_exact_type(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { |
| 584 | let cls = obj.class(); |