检查符号是否可以安全评估 [英] Check whether a symbol can be safely evaluated
问题描述
我有一个字符串x
.我认为x
是类型的字符串表示形式,是Number
的子类型.例如,x
可能取值为"Float64"
.我可以使用以下方法进行检查:
I have a string x
. I think that x
is a string representation of a type that is a subtype of Number
. For example, x
might take the value "Float64"
. I could check this using:
eval(parse(x)) <: Number
但是,x
可能包含一些危险的东西,例如"rm(something_important)"
上的某些变体,因此在我确定x
是安全的之前,使用eval
是个坏主意.
However, it is possible that x
contains something dangerous, like some variant on "rm(something_important)"
, so using eval
is a bad idea until I'm sure x
is safe.
有什么办法可以安全地检查x
是否是Number
子类型的字符串表示形式?
Is there any way I can safely check whether x
is a string representation of a subtype of Number
?
(除了构建Number
所有可能的子类型的字符串数组并进行比较...)
(other than building an array of strings of all possible sub-types of Number
and comparing...)
推荐答案
HDF5.jl 包必须处理这个. 它通过解析字符串来解决然后检查结果之前 eval
.如果解析的字符串是它认为是 valid_type_expression
然后知道在Main
命名空间中进行评估应该是安全的.这样,它就可以从Main名称空间中提取自定义类型,而这些自定义类型在baremodule
中是不可用的.
The HDF5.jl package has to deal with this. It tackles it by parsing the string and then inspecting the result before eval
ing it. If the parsed string is what it considers to be a valid_type_expression
then it knows that it should be safe to evaluate in the Main
namespace. This allows it to pickup custom types from the Main namespace that wouldn't be available from within a baremodule
.
更多详细信息:解析任意字符串后,您可以检查返回的对象以查看其是否安全"以进行评估:
More details: After you parse an arbitrary string, you can inspect the returned object to see if it's "safe" to evaluate:
julia> dump(parse("Int"))
Symbol Int
julia> dump(parse("Vector{Int}"))
Expr
head: Symbol curly
args: Array(Any,(2,))
1: Symbol Vector
2: Symbol Int
typ: Any
julia> dump(parse("""rm("/")"""))
Expr
head: Symbol call
args: Array(Any,(2,))
1: Symbol rm
2: ASCIIString "/"
typ: Any
我们要确保我们永远不会eval
一个可以调用任意行为的表达式.根据要完全支持类型语法的方式,您的解决方案可能非常简单,也可能与我上面链接的HDF5解决方案一样复杂.如果您只是追求简单的,非参数化的类型,那么我们可以大大简化事情:
We want to ensure that we never eval
an expression that could call arbitrary behaviors. Depending on how thoroughly you want to support the type syntax, your solution could be quite simple or it could be as complicated as the HDF5 solution I linked above. If you're just after simple, unparameterized types we can simplify things substantially:
is_valid_type_expression(ex::Symbol) = true
is_valid_type_expression(ex) = false
function julia_type(string)
ex = parse(string)
if is_valid_type_expression(ex)
try
typ = eval(Main, ex)
isa(typ, Type) && typ <: Number && return typ
end
end
error("unsupported type: $string")
end
julia> julia_type("String")
ERROR: unsupported type: String
in julia_type at none:9
julia> julia_type("Int")
Int64
julia> julia_type("""rm("/")""")
ERROR: unsupported type: rm("/")
in julia_type at none:9
请注意,不允许对任何比符号复杂的内容进行eval
编辑.在eval
表达式之后,我们检查以确保类型是Type,并且它是Number
的子类型.除了内置的子类型外,这还将允许Number
的自定义子类型,因为我们正在Main
命名空间中对其进行评估.
Note that anything more complicated than a symbol isn't allowed to be eval
'ed. And after eval
ing the expression, we check to ensure that the type is a Type and that it's a subtype of Number
. This will also allow custom subtypes of Number
in addition to the builtin ones, since we're evaluating it in the Main
namespace.
这篇关于检查符号是否可以安全评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!