[英]Elixir decode with Poison
I'm getting this string as query result from my database: 我从数据库中获取此字符串作为查询结果:
"%Sample.Struct{list: [], total: \"0.00\", day: 6, id: \"8vfts6\"}"
Is there any way to convert this one back to map? 有什么办法可以将此地图转换回地图吗? I'm getting this error decoding it with poison 我正在用毒药解码此错误
** (Poison.SyntaxError) Unexpected token: %
(poison) lib/poison/parser.ex:56: Poison.Parser.parse!/2
(poison) lib/poison.ex:83: Poison.decode!/2
I can't fix the way data is being added to database, i must find a proper way for a key/value route to easily retrive data from that. 我无法确定将数据添加到数据库的方式,我必须找到一种适当的方法来使键/值路由轻松地从中检索数据。 (this is just a sample for a more complex result) (这只是一个更复杂结果的示例)
As it was mentioned in comments, you should not use Code.eval_string
. 正如评论中提到的那样,您不应使用Code.eval_string
。 But, there is a way to safely convert your code to Elixir struct, using Code
module: 但是,有一种方法可以使用Code
模块将您的代码安全地转换为Elixir结构:
ex(1)> encoded = "%Sample.Struct{list: [], total: \"0.00\", day: 6, id: \"8vfts6\"}"
"%Sample.Struct{list: [], total: \"0.00\", day: 6, id: \"8vfts6\"}"
First, get the AST from the string, but use the pattern matching to ensure it is a struct you are looking for ( {:__aliases__, _, [:Sample, :Struct]}
). 首先,从字符串中获取AST,但使用模式匹配来确保它是您要查找的结构( {:__aliases__, _, [:Sample, :Struct]}
)。 All other (potentially malicious) code will fail this match: 所有其他(可能是恶意的)代码都将失败此匹配:
iex(2)> {:ok, {:%, _, [{:__aliases__, _, [:Sample, :Struct]}, {:%{}, _, keymap}]} = ast} = Code.string_to_quoted(encoded)
{:ok,
{:%, [line: 1],
[{:__aliases__, [line: 1], [:Sample, :Struct]},
{:%{}, [line: 1], [list: [], total: "0.00", day: 6, id: "8vfts6"]}]}}
Here you have the full ast
for you struct, and the keymap
. 在这里,您ast
完整的ast
结构和keymap
。 You may now be tempted to use eval_quoted
with the AST, to get the struct you needed: 您现在可能会想在AST中使用eval_quoted
来获取所需的结构:
iex(3)> {struct, _} = Code.eval_quoted(ast)
{%Sample.Struct{day: 6, id: "8vfts6", list: [], total: "0.00"}, []}
iex(4)> struct
%Sample.Struct{day: 6, id: "8vfts6", list: [], total: "0.00"}
But it is still not safe! 但这仍然不安全! Someone may put a function causing side effect into the string, like "%Sample.Struct{list: IO.puts \\"Something\\"}"
, which will be executed during the evaluation. 有人可能会在字符串中放入引起副作用的函数,例如"%Sample.Struct{list: IO.puts \\"Something\\"}"
,该"%Sample.Struct{list: IO.puts \\"Something\\"}"
将在评估期间执行。 So you will need to check the keymap
firsts, if it contain safe data . 因此, 您将需要首先检查keymap
(如果其中包含安全数据) 。
Or you may just use keymap
directly, without evaluating anyting: 或者,您可以直接使用keymap
,而不进行任何评估:
iex(5)> struct(Sample.Struct, keymap)
%Sample.Struct{day: 6, id: "8vfts6", list: [], total: "0.00"}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.