简体   繁体   English

长生不老药用毒药解码

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM