Class: Protocol::Content::JSONParser

Inherits:
Object
  • Object
show all
Defined in:
lib/protocol/content/json_parser.rb

Overview

Parses JSON content with bounded input size and nesting depth.

Constant Summary collapse

MEDIA_TYPE =
"application/json"
SIZE_LIMIT =

The encoded JSON document size limit.

2 * 1024 * 1024
DEPTH_LIMIT =

The JSON document nesting depth limit.

32

Instance Method Summary collapse

Constructor Details

#initialize(size_limit: SIZE_LIMIT, depth_limit: DEPTH_LIMIT, **options) ⇒ JSONParser

Initialize the JSON parser.



26
27
28
29
30
# File 'lib/protocol/content/json_parser.rb', line 26

def initialize(size_limit: SIZE_LIMIT, depth_limit: DEPTH_LIMIT, **options)
	@size_limit = size_limit
	options[:max_nesting] = depth_limit || false
	@options = options
end

Instance Method Details

#parse(input) ⇒ Object

Parse JSON content.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/protocol/content/json_parser.rb', line 35

def parse(input)
	if @size_limit
		buffer = String.new.b
		
		# Read up to the size limit, allowing for partial reads:
		while buffer.bytesize < @size_limit
			chunk = input.read(@size_limit - buffer.bytesize)
			break unless chunk
			# An empty chunk cannot make progress, so stop reading:
			break if chunk.empty?
			
			buffer << chunk
		end
		
		if buffer.bytesize == @size_limit && input.read(1)
			raise ContentTooLargeError, "JSON content size exceeded limit of #{@size_limit}!"
		end
	else
		buffer = input.read
	end
	
	return JSON.parse(buffer, **@options)
rescue JSON::NestingError
	raise ContentTooLargeError
end