make pipeline grammars more accurately capture field references

Certain malformed field reference literals (e.g., those containing a series of
multiple open-brackets `[[`) were propagated undetected by the parser, only to
create a crashing error when used.

Starting Logstash with the `--config.test_and_exit` flag (or `-t` shorthand)
would validate the config, even though it could not be used in practice.

By updating the grammar(s) to exclude the use of an open square bracket (`[`),
we more closely match the formal grammar and ensure these malformed literals
are rejected closer to the source.

NOTE: this PR only affects field reference _literals_, and does not resolve
a similar issue with field references in quoted format strings.

Resolves: https://github.com/elastic/logstash/issues/11022

Fixes #11195
This commit is contained in:
Ry Biesemeyer 2019-10-07 23:20:57 +00:00
parent 138e1f91e5
commit 08fd76ab30
5 changed files with 14 additions and 6 deletions

View file

@ -3528,11 +3528,11 @@ module LogStashCompilerLSCLGrammar
if r1
s2, i2 = [], index
loop do
if has_terminal?(@regexps[gr = '\A[^\\],]'] ||= Regexp.new(gr), :regexp, index)
if has_terminal?(@regexps[gr = '\A[^\\]\\[,]'] ||= Regexp.new(gr), :regexp, index)
r3 = true
@index += 1
else
terminal_parse_failure('[^\\],]')
terminal_parse_failure('[^\\]\\[,]')
r3 = nil
end
if r3

View file

@ -234,7 +234,7 @@ grammar LogStashCompilerLSCLGrammar
end
rule selector_element
"[" [^\],]+ "]"
"[" [^\]\[,]+ "]"
<LogStash::Compiler::LSCL::AST::SelectorElement>
end

View file

@ -3528,11 +3528,11 @@ module LogStashConfig
if r1
s2, i2 = [], index
loop do
if has_terminal?(@regexps[gr = '\A[^\\],]'] ||= Regexp.new(gr), :regexp, index)
if has_terminal?(@regexps[gr = '\A[^\\]\\[,]'] ||= Regexp.new(gr), :regexp, index)
r3 = true
@index += 1
else
terminal_parse_failure('[^\\],]')
terminal_parse_failure('[^\\]\\[,]')
r3 = nil
end
if r3

View file

@ -234,7 +234,7 @@ grammar LogStashConfig
end
rule selector_element
"[" [^\],]+ "]"
"[" [^\]\[,]+ "]"
<LogStash::Config::AST::SelectorElement>
end

View file

@ -147,6 +147,14 @@ describe LogStash::Runner do
expect(subject.run(args)).to eq(1)
end
end
context "with invalid field reference literal" do
let(:pipeline_string) { "input { } output { if [[f[[[oo] == [bar] { } }" }
it "should fail by returning a bad exit code" do
expect(logger).to receive(:fatal)
expect(subject.run(args)).to eq(1)
end
end
end
describe "pipeline settings" do
let(:pipeline_string) { "input { stdin {} } output { stdout {} }" }