mirror of
https://github.com/valitydev/yamerl.git
synced 2024-11-06 02:45:23 +00:00
yamerl_parser: Fix an infinite loop
... with document/directive end markers not terminated by a whitespace or a newline. Thanks to Barry Allard for the bug report and testcases. Fixes #18.
This commit is contained in:
parent
a12e146d8c
commit
4bc4fa0278
@ -723,6 +723,9 @@ determine_token_type([$-, $-, $-, C | _] = Chars, Line, 1 = Col, Delta,
|
||||
when ?IS_NEWLINE(C) orelse ?IS_SPACE(C) orelse
|
||||
(Version == {1,1} andalso ?IS_NEWLINE_11(C)) ->
|
||||
parse_document_sep(Chars, Line, Col, Delta, Parser, directives_end);
|
||||
determine_token_type([$-, $-, $-] = Chars, Line, 1 = Col, Delta,
|
||||
#yamerl_parser{raw_eos = true} = Parser) ->
|
||||
parse_document_sep(Chars, Line, Col, Delta, Parser, directives_end);
|
||||
|
||||
%% Document end indicator.
|
||||
determine_token_type([$., $., $., C | _] = Chars, Line, 1 = Col, Delta,
|
||||
@ -730,6 +733,9 @@ determine_token_type([$., $., $., C | _] = Chars, Line, 1 = Col, Delta,
|
||||
when ?IS_NEWLINE(C) orelse ?IS_SPACE(C) orelse
|
||||
(Version == {1,1} andalso ?IS_NEWLINE_11(C)) ->
|
||||
parse_document_sep(Chars, Line, Col, Delta, Parser, document_end);
|
||||
determine_token_type([$., $., $.] = Chars, Line, 1 = Col, Delta,
|
||||
#yamerl_parser{raw_eos = true} = Parser) ->
|
||||
parse_document_sep(Chars, Line, Col, Delta, Parser, document_end);
|
||||
|
||||
%% Directive indicator.
|
||||
determine_token_type([$% | _] = Chars, Line, 1 = Col, Delta,
|
||||
|
62
test/construction/document_delimiters.erl
Normal file
62
test/construction/document_delimiters.erl
Normal file
@ -0,0 +1,62 @@
|
||||
-module(document_delimiters).
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
%% This file contains testcases provided by Barry Allard when he
|
||||
%% reported #18. Before the bugfix, they would trigger an infinite loop
|
||||
%% in the parser.
|
||||
%%
|
||||
%% FIXME: It's still unclear if the returned values are correct for the
|
||||
%% given documents.
|
||||
|
||||
setup() ->
|
||||
application:start(yamerl).
|
||||
|
||||
parse_blank_string_test_() ->
|
||||
{setup,
|
||||
fun setup/0,
|
||||
[
|
||||
?_assertEqual([], yamerl_constr:string(""))
|
||||
]
|
||||
}.
|
||||
|
||||
parse_empty_json_map_test_() ->
|
||||
{setup,
|
||||
fun setup/0,
|
||||
[
|
||||
?_assertEqual([[]], yamerl_constr:string("{}"))
|
||||
]
|
||||
}.
|
||||
|
||||
parse_dos_vuln_string_test_() ->
|
||||
%% TODO: Consider fuzzing using QuickCheck Mini, PropEr, etc.
|
||||
{setup,
|
||||
fun setup/0,
|
||||
[
|
||||
?_assertEqual([null], yamerl_constr:string("---")),
|
||||
?_assertEqual([], yamerl_constr:string("...")),
|
||||
?_assertEqual([null], yamerl_constr:string("\n---")),
|
||||
?_assertEqual([null], yamerl_constr:string("\r---")),
|
||||
?_assertEqual([null], yamerl_constr:string("\r\n---")),
|
||||
?_assertEqual([null, null], yamerl_constr:string("\n---\n---")),
|
||||
?_assertEqual([null, null], yamerl_constr:string(" \n---\n---")),
|
||||
?_assertEqual([null, null], yamerl_constr:string("\n---\n---\n...")),
|
||||
?_assertEqual(["anything", null], yamerl_constr:string("anything\n---"))
|
||||
]
|
||||
}.
|
||||
|
||||
parse_dos_vuln_bad_string_1_test_() ->
|
||||
{setup,
|
||||
fun setup/0,
|
||||
[
|
||||
?_assertEqual(["--"], yamerl_constr:string("--"))
|
||||
]
|
||||
}.
|
||||
|
||||
parse_dos_vuln_bad_string_2_test_() ->
|
||||
{setup,
|
||||
fun setup/0,
|
||||
[
|
||||
?_assertEqual(["----"], yamerl_constr:string("----"))
|
||||
]
|
||||
}.
|
55
test/parsing/directives_end_alone.erl
Normal file
55
test/parsing/directives_end_alone.erl
Normal file
@ -0,0 +1,55 @@
|
||||
-module('directives_end_alone').
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
single_test_() ->
|
||||
?_assertMatch(
|
||||
{yamerl_parser,
|
||||
string,
|
||||
[],
|
||||
<<>>,
|
||||
3,
|
||||
true,
|
||||
[],
|
||||
0,
|
||||
4,
|
||||
1,
|
||||
4,
|
||||
false,
|
||||
1,
|
||||
4,
|
||||
utf8,
|
||||
false,
|
||||
undefined,
|
||||
_,
|
||||
_,
|
||||
[],
|
||||
{bcoll,root,0,-1,1,1,-1,1,1},
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
[{impl_key,false,false,undefined,undefined,1,1}],
|
||||
false,
|
||||
false,
|
||||
_,
|
||||
[],
|
||||
0,
|
||||
6,
|
||||
5,
|
||||
undefined,
|
||||
undefined,
|
||||
_,
|
||||
false,
|
||||
[],
|
||||
[
|
||||
{yamerl_stream_end,1,4},
|
||||
{yamerl_doc_end,1,4},
|
||||
{yamerl_scalar,1,4,
|
||||
{yamerl_tag,1,4,{non_specific,"?"}},
|
||||
flow,plain,""},
|
||||
{yamerl_doc_start,1,1,{1,2},_},
|
||||
{yamerl_stream_start,1,1,utf8}
|
||||
]
|
||||
},
|
||||
yamerl_parser:string("---")
|
||||
).
|
50
test/parsing/document_end_alone.erl
Normal file
50
test/parsing/document_end_alone.erl
Normal file
@ -0,0 +1,50 @@
|
||||
-module('document_end_alone').
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
single_test_() ->
|
||||
?_assertMatch(
|
||||
{yamerl_parser,
|
||||
string,
|
||||
[],
|
||||
<<>>,
|
||||
3,
|
||||
true,
|
||||
[],
|
||||
0,
|
||||
4,
|
||||
1,
|
||||
4,
|
||||
false,
|
||||
1,
|
||||
4,
|
||||
utf8,
|
||||
false,
|
||||
undefined,
|
||||
_,
|
||||
_,
|
||||
[],
|
||||
{bcoll,root,0,-1,1,1,-1,1,1},
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
[{impl_key,false,false,undefined,undefined,1,1}],
|
||||
false,
|
||||
false,
|
||||
_,
|
||||
[],
|
||||
0,
|
||||
3,
|
||||
2,
|
||||
undefined,
|
||||
undefined,
|
||||
_,
|
||||
false,
|
||||
[],
|
||||
[
|
||||
{yamerl_stream_end,1,4},
|
||||
{yamerl_stream_start,1,1,utf8}
|
||||
]
|
||||
},
|
||||
yamerl_parser:string("...")
|
||||
).
|
Loading…
Reference in New Issue
Block a user