serialization :: SafeDeserializer
Deserialization engine limiting which types can be deserializedserialization :: safe $ Deserializer
Abstract deserialization serviceserialization :: safe $ Deserializer
Abstract deserialization serviceserialization $ SafeDeserializer
Deserialization engine limiting which types can be deserializedSerializable::inspect
to show more useful information
serialization :: serialization_core
Abstract services to serialize Nit objects to different formatscore :: union_find
union–find algorithm using an efficient disjoint-set data structuredeserialize_json
and JsonDeserializer
app::http_request
main service AsyncHttpRequest
mpi :: mpi_simple
app.nit
on Android using a custom Java entry point
restful
annotation documented at lib/nitcorn/restful.nit
# Services for safer deserialization engines
module safe
import poset
import serialization
private import engine_tools
# Deserialization engine limiting which types can be deserialized
class SafeDeserializer
super Deserializer
# Accepted parameterized classes to deserialize
#
# If `whitelist.empty`, all types are accepted.
#
# ~~~
# import json
#
# class MyClass
# serialize
# end
#
# var json_string = """
# {"__class": "MyClass"}
# """
#
# var deserializer = new JsonDeserializer(json_string)
# var obj = deserializer.deserialize
# assert deserializer.errors.is_empty
# assert obj isa MyClass
#
# deserializer = new JsonDeserializer(json_string)
# deserializer.whitelist.add "Array[String]"
# deserializer.whitelist.add "AnotherAcceptedClass"
# obj = deserializer.deserialize
# assert deserializer.errors.length == 1
# assert obj == null
# ~~~
var whitelist = new Array[Text]
# Should objects be checked if they a subtype of the static type before deserialization?
#
# Defaults to `true`, as it should always be activated.
# It can be turned off to implement the subtype check itself.
var check_subtypes = true is writable
# Should `self` accept to deserialize an instance of `dynamic_type` for an attribute wuth `static_type`?
#
# Uses `whitelist` if not empty...
# Check correct inheritance if `check_subtypes`...
fun accept(dynamic_type: Text, static_type: nullable Text): Bool
do
if whitelist.not_empty and not whitelist.has(dynamic_type) then
errors.add new Error("Deserialization Error: '{dynamic_type}' not in whitelist")
return false
end
if static_type != null and check_subtypes then
var static_class = static_type.strip_nullable_and_params.to_s
var dynamic_class = dynamic_type.strip_nullable_and_params.to_s
if not class_inheritance_metamodel.has_edge(dynamic_class, static_class) then
errors.add new Error("Deserialization Error: `{dynamic_type}` is not a subtype of the static type `{static_type}`")
return false
end
end
return true
end
end
redef class Sys
# Class inheritance graph, implemented by the `json` package
#
# ~~~
# import json
#
# var hierarchy = class_inheritance_metamodel
# assert hierarchy.has_edge("String", "Object")
# assert not hierarchy.has_edge("Object", "String")
# ~~~
fun class_inheritance_metamodel: POSet[String] is abstract
end
redef class Deserializer
redef fun deserialize_class(name)
do
if name == "POSet[String]" then return new POSet[String].from_deserializer(self)
if name == "POSetElement[String]" then return new POSetElement[String].from_deserializer(self)
if name == "HashSet[String]" then return new HashSet[String].from_deserializer(self)
if name == "HashMap[String, POSetElement[String]]" then return new HashMap[String, POSetElement[String]].from_deserializer(self)
return super
end
end
lib/serialization/safe.nit:15,1--109,3