检查符号是否可以安全评估 [英] Check whether a symbol can be safely evaluated

查看:88
本文介绍了检查符号是否可以安全评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个字符串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 evaling 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 evaling 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆