JSON#unsafe_load
# File tmp/rubies/ruby-4.0.0/ext/json/lib/json/common.rb, line 683
def unsafe_load(source, proc = nil, options = nil)
opts = if options.nil?
if proc && proc.is_a?(Hash)
options, proc = proc, nil
options
else
_unsafe_load_default_options
end
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
if proc
opts = opts.dup
opts[:on_load] = proc.to_proc
end
parse(source, opts)
end
Returns the Ruby objects created by parsing the given source.
BEWARE: This method is meant to serialise data from trusted user input, like from your own database server or clients under your control, it could be dangerous to allow untrusted users to pass JSON sources into it.
-
Argument
sourcemust be, or be convertible to, a String:-
If
sourceresponds to instance methodto_str,source.to_strbecomes the source. -
If
sourceresponds to instance methodto_io,source.to_io.readbecomes the source. -
If
sourceresponds to instance methodread,source.readbecomes the source. -
If both of the following are true, source becomes the String
'null':-
Option
allow_blankspecifies a truthy value. -
The source, as defined above, is
nilor the empty String''.
-
-
Otherwise,
sourceremains the source.
-
-
Argument
proc, if given, must be a Proc that accepts one argument. It will be called recursively with each result (depth-first order). See details below. -
Argument
opts, if given, contains a Hash of options for the parsing. See Parsing Options. The default options can be changed via method JSON.unsafe_load_default_options=.
When no proc is given, modifies source as above and returns the result of parse(source, opts); see parse.
Source for following examples:
source = <<~JSON { "name": "Dave", "age" :40, "hats": [ "Cattleman's", "Panama", "Tophat" ] } JSON
Load a String:
ruby = JSON.unsafe_load(source) ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
Load an IO object:
require 'stringio' object = JSON.unsafe_load(StringIO.new(source)) object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
Load a File object:
path = 't.json' File.write(path, source) File.open(path) do |file| JSON.unsafe_load(file) end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
When proc is given:
-
Modifies
sourceas above. -
Gets the
resultfrom callingparse(source, opts). -
Recursively calls
proc(result). -
Returns the final result.
Example:
require 'json' # Some classes for the example. class Base def initialize(attributes) @attributes = attributes end end class User < Base; end class Account < Base; end class Admin < Base; end # The JSON source. json = <<-EOF { "users": [ {"type": "User", "username": "jane", "email": "[email protected]"}, {"type": "User", "username": "john", "email": "[email protected]"} ], "accounts": [ {"account": {"type": "Account", "paid": true, "account_id": "1234"}}, {"account": {"type": "Account", "paid": false, "account_id": "1235"}} ], "admins": {"type": "Admin", "password": "0wn3d"} } EOF # Deserializer method. def deserialize_obj(obj, safe_types = %w(User Account Admin)) type = obj.is_a?(Hash) && obj["type"] safe_types.include?(type) ? Object.const_get(type).new(obj) : obj end # Call to JSON.unsafe_load ruby = JSON.unsafe_load(json, proc {|obj| case obj when Hash obj.each {|k, v| obj[k] = deserialize_obj v } when Array obj.map! {|v| deserialize_obj v } end obj }) pp ruby
Output:
{"users"=>
[#<User:0x00000000064c4c98
@attributes=
{"type"=>"User", "username"=>"jane", "email"=>"[email protected]"}>,
#<User:0x00000000064c4bd0
@attributes=
{"type"=>"User", "username"=>"john", "email"=>"[email protected]"}>],
"accounts"=>
[{"account"=>
#<Account:0x00000000064c4928
@attributes={"type"=>"Account", "paid"=>true, "account_id"=>"1234"}>},
{"account"=>
#<Account:0x00000000064c4680
@attributes={"type"=>"Account", "paid"=>false, "account_id"=>"1235"}>}],
"admins"=>
#<Admin:0x00000000064c41f8
@attributes={"type"=>"Admin", "password"=>"0wn3d"}>}