diff --git a/CHANGELOG.md b/CHANGELOG.md index 30eb163..cea6ceb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 3.1.0 + - Add decode_size_limit_bytes option to limit the maximum size of JSON document that can be parsed + ## 3.0.2 - Relax constraint on logstash-core-plugin-api to >= 1.60 <= 2.99 diff --git a/lib/logstash/codecs/json_lines.rb b/lib/logstash/codecs/json_lines.rb index 8801c39..ae9255a 100644 --- a/lib/logstash/codecs/json_lines.rb +++ b/lib/logstash/codecs/json_lines.rb @@ -28,10 +28,15 @@ class LogStash::Codecs::JSONLines < LogStash::Codecs::Base # Change the delimiter that separates lines config :delimiter, :validate => :string, :default => "\n" + # Maximum number of bytes for a single line before a fatal exception is raised + # which will stop Logsash. + # The default is 20MB which is quite large for a JSON document + config :decode_size_limit_bytes, :validate => :number, :default => 20 * (1024 * 1024) # 20MB + public def register - @buffer = FileWatch::BufferedTokenizer.new(@delimiter) + @buffer = FileWatch::BufferedTokenizer.new(@delimiter, @decode_size_limit_bytes) @converter = LogStash::Util::Charset.new(@charset) @converter.logger = @logger end diff --git a/logstash-codec-json_lines.gemspec b/logstash-codec-json_lines.gemspec index e06aeb5..e57ba7d 100644 --- a/logstash-codec-json_lines.gemspec +++ b/logstash-codec-json_lines.gemspec @@ -1,7 +1,7 @@ Gem::Specification.new do |s| s.name = 'logstash-codec-json_lines' - s.version = '3.0.2' + s.version = '3.1.0' s.licenses = ['Apache License (2.0)'] s.summary = "This codec will decode streamed JSON that is newline delimited." s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program" diff --git a/spec/codecs/json_lines_spec.rb b/spec/codecs/json_lines_spec.rb index ecb018b..6be4e37 100644 --- a/spec/codecs/json_lines_spec.rb +++ b/spec/codecs/json_lines_spec.rb @@ -117,6 +117,22 @@ end end + describe "decode_size_limits_bytes" do + let(:maximum_payload) { "a" * subject.decode_size_limit_bytes } + + it "should not raise an error if the number of bytes is not exceeded" do + expect { + subject.decode(maximum_payload) + }.not_to raise_error + end + + it "should raise an error if the max bytes are exceeded" do + expect { + subject.decode(maximum_payload << "z") + }.to raise_error(RuntimeError, "input buffer full") + end + end + end context "#encode" do