module JSON
def unsafe_load(source, proc = nil, options = nil)
@attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
#
@attributes={"type"=>"Account", "paid"=>false, "account_id"=>"1235"}>}],
#
@attributes={"type"=>"Account", "paid"=>true, "account_id"=>"1234"}>},
#
"accounts"=>
{"type"=>"User", "username"=>"john", "email"=>"john@example.com"}>],
@attributes=
#
@attributes=
[#
Output:
pp ruby
})
end
obj.map! {|v| deserialize_obj v }
when Array
obj.each {|k, v| obj[k] = deserialize_obj v }
when Hash
case obj
ruby = JSON.unsafe_load(json, proc {|obj|
# Call to JSON.unsafe_load
end
safe_types.include?(type) ? Object.const_get(type).new(obj) : obj
type = obj.is_a?(Hash) && obj["type"]
def deserialize_obj(obj, safe_types = %w(User Account Admin))
# Deserializer method.
EOF
}
"admins": {"type": "Admin", "password": "0wn3d"}
],
{"account": {"type": "Account", "paid": false, "account_id": "1235"}}
{"account": {"type": "Account", "paid": true, "account_id": "1234"}},
"accounts": [
],
{"type": "User", "username": "john", "email": "john@example.com"}
{"type": "User", "username": "jane", "email": "jane@example.com"},
"users": [
{
json = <<-EOF
# The JSON source.
class Admin < Base; end
class Account < Base; end
class User < Base; end
end
end
@attributes = attributes
def initialize(attributes)
class Base
# Some classes for the example.
require 'json'
Example:
- Returns the final result.
- Recursively calls proc(result).
- Gets the +result+ from calling parse(source, opts).
- Modifies +source+ as above.
When +proc+ is given:
---
end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
JSON.unsafe_load(file)
File.open(path) do |file|
File.write(path, source)
path = 't.json'
Load a \File object:
object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
object = JSON.unsafe_load(StringIO.new(source))
require 'stringio'
Load an \IO object:
ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
ruby = JSON.unsafe_load(source)
Load a \String:
JSON
}
]
"Tophat"
"Panama",
"Cattleman's",
"hats": [
"age" :40,
"name": "Dave",
{
source = <<~JSON
Source for following examples:
parse(source, opts); see #parse.
When no +proc+ is given, modifies +source+ as above and returns the result of
---
The default options can be changed via method JSON.unsafe_load_default_options=.
See {Parsing Options}[#module-JSON-label-Parsing+Options].
- Argument +opts+, if given, contains a \Hash of options for the parsing.
See details below.
It will be called recursively with each result (depth-first order).
- Argument +proc+, if given, must be a \Proc that accepts one argument.
- Otherwise, +source+ remains the source.
- The source, as defined above, is +nil+ or the empty \String ''.
- Option +allow_blank+ specifies a truthy value.
- If both of the following are true, source becomes the \String 'null':
source.read becomes the source.
- If +source+ responds to instance method +read+,
source.to_io.read becomes the source.
- If +source+ responds to instance method +to_io+,
source.to_str becomes the source.
- If +source+ responds to instance method +to_str+,
- Argument +source+ must be, or be convertible to, a \String:
be dangerous to allow untrusted users to pass JSON sources into it.
like from your own database server or clients under your control, it could
BEWARE: This method is meant to serialise data from trusted user input,
Returns the Ruby objects created by parsing the given +source+.
JSON.unsafe_load(source, proc = nil, options = {}) -> object
:call-seq:
def unsafe_load(source, proc = nil, options = nil) opts = if options.nil? _unsafe_load_default_options else _unsafe_load_default_options.merge(options) end unless source.is_a?(String) if source.respond_to? :to_str source = source.to_str elsif source.respond_to? :to_io source = source.to_io.read elsif source.respond_to?(:read) source = source.read end end if opts[:allow_blank] && (source.nil? || source.empty?) source = 'null' end result = parse(source, opts) recurse_proc(result, &proc) if proc result end