Class: RJR::JSONParser
Overview
Provides utilities / helpers to parse json in a sane/safe manner
Class Method Summary collapse
-
.extract_json_from(data) ⇒ Object
Extract and return a single json message from a data string.
-
.invalid_json_class?(jc) ⇒ Boolean
Return bool indicating if json class is invalid in context of rjr & cannot be parsed.
-
.parse(js) ⇒ Object
Two stage json parser.
- .validate_json_array(ja) ⇒ Object
- .validate_json_hash(jh) ⇒ Object
Class Method Details
.extract_json_from(data) ⇒ Object
Extract and return a single json message from a data string.
Returns the message and remaining portion of the data string, if message is found, else nil
TODO efficiency can probably be optimized in the case closing ‘}’ hasn’t arrived yet
FIXME if uneven brackets appears in string data (such as in params) this will break, detect when in string and ignore in counts
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/rjr/util/json_parser.rb', line 24 def self.extract_json_from(data) return nil if data.nil? || data.empty? start = 0 start += 1 until start == data.length || data[start].chr == '{' on = mi = 0 start.upto(data.length - 1).each { |i| if data[i].chr == '{' on += 1 elsif data[i].chr == '}' on -= 1 end if on == 0 mi = i break end } return nil if mi == 0 return data[start..mi], data[(mi+1)..-1] end |
.invalid_json_class?(jc) ⇒ Boolean
Return bool indicating if json class is invalid in context of rjr & cannot be parsed.
An invalid class is one not on whitelist if enabled or one not in ruby class heirachy.
Implements a safe mechanism which to validate json data to parse
54 55 56 57 58 |
# File 'lib/rjr/util/json_parser.rb', line 54 def self.invalid_json_class?(jc) Class.whitelist_json_classes ||= false Class.whitelist_json_classes ? !Class.permitted_json_classes.include?(jc) : jc.to_s.to_class.nil? end |
.parse(js) ⇒ Object
Two stage json parser. For more details why this is required see json issue:
https://github.com/flori/json/issues/179
FIXME this will only work for json >= 1.7.6 where create_additions is defined
88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/rjr/util/json_parser.rb', line 88 def self.parse(js) jp = ::JSON.parse js, :create_additions => false if jp.is_a?(Array) validate_json_array(jp) elsif jp.is_a?(Hash) validate_json_hash(jp) else return jp end ::JSON.parse js, :create_additions => true end |
.validate_json_array(ja) ⇒ Object
72 73 74 75 76 77 78 79 80 |
# File 'lib/rjr/util/json_parser.rb', line 72 def self.validate_json_array(ja) ja.each { |jai| if jai.is_a?(Array) validate_json_array(jai) elsif jai.is_a?(Hash) validate_json_hash(jai) end } end |
.validate_json_hash(jh) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/rjr/util/json_parser.rb', line 60 def self.validate_json_hash(jh) jh.each { |k,v| if k == ::JSON.create_id && invalid_json_class?(v) raise ArgumentError, "can't create json class #{v}" elsif v.is_a?(Array) validate_json_array(v) elsif v.is_a?(Hash) validate_json_hash(v) end } end |