Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix a tail recursion bug #9463

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions lib/xmerl/src/xmerl_eventp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -314,16 +314,16 @@ cont(F, Exception, S) ->


cont2(F, Exception, Sofar, Fd, Fname, T, S) ->
case catch read_chunk(Fd, Fname, Sofar) of
{ok, Bin} ->
find_good_split(list_to_binary([Sofar,Bin]),
case read_chunk(Fd, Fname, Sofar) of
{ok, Bin} ->
find_good_split(list_to_binary([Sofar,Bin]),
F,Exception,Fd,Fname,T,S);
eof ->
ok = file:close(Fd),
NewS = xmerl_scan:cont_state([{Fname, eof}|T], S),
F(binary_to_list(Sofar), NewS);
Error ->
exit(Error)
Error ->
exit(Error)
end.

read_chunk(Fd, _Fname, _Sofar) ->
Expand Down Expand Up @@ -468,11 +468,12 @@ rules_read(Context, Name, #xmerl_scanner{rules = T}) ->
%%% Generic helper functions

scanner_options([H|T], Opts) ->
case catch keyreplace(H, 1, Opts) of
false ->
scanner_options(T, [H|Opts]);
NewOpts ->
try keyreplace(H, 1, Opts) of
NewOpts ->
scanner_options(T, NewOpts)
catch
throw:false ->
scanner_options(T, [H|Opts])
end;
scanner_options([], Opts) ->
Opts.
Expand Down
11 changes: 7 additions & 4 deletions lib/xmerl/src/xmerl_regexp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,13 @@ sh_special_char(_C) -> false.
%% Parse the regexp described in the string RegExp.

parse(S) ->
case catch reg(S, 0) of
{R,Sc,[]} -> {ok,{regexp,{R,Sc}}};
{_R,_Sc,[C|_]} -> {error,{illegal,[C]}};
{error,E} -> {error,E}
try reg(S, 0) of
{R,Sc,[]} ->
{ok,{regexp,{R,Sc}}};
{_R,_Sc,[C|_]} ->
{error,{illegal,[C]}}
catch
throw:{error,E} -> {error,E}
end.

%% format_error(Error) -> String.
Expand Down
303 changes: 132 additions & 171 deletions lib/xmerl/src/xmerl_sax_parser_base.erlsrc

Large diffs are not rendered by default.

31 changes: 15 additions & 16 deletions lib/xmerl/src/xmerl_scan.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1510,7 +1510,7 @@ check_notations(Tab,S) ->
end.

check_elements(Tab,S) ->
case catch ets:match(Tab,{{elem_def,'_'},'$2'},10) of
try ets:match(Tab,{{elem_def,'_'},'$2'},10) of
{_,_}=M ->
Fun = fun({Match,'$end_of_table'},_F) ->
lists:foreach(fun(X)->check_elements2(X,S) end,
Expand All @@ -1524,8 +1524,9 @@ check_elements(Tab,S) ->
F(ets:match(Cont),F)
end,
Fun(M,Fun);
'$end_of_table' -> ok;
Err -> ?fatal({error_missing_declaration_in_DTD,Err},S)
'$end_of_table' -> ok
catch
_:Err -> ?fatal({error_missing_declaration_in_DTD,Err},S)
end.

% it is not an error to declare attributes for an element that is not
Expand Down Expand Up @@ -2881,11 +2882,11 @@ scan_reference("#" ++ T, S0) ->
?fatal(invalid_char_ref, S)
end;
scan_reference(T, S) ->
case catch scan_entity_ref(T, S) of
{'EXIT', _} ->
?fatal(error_scanning_entity_ref,S);
Other ->
Other
try
scan_entity_ref(T, S)
catch
exit:_ ->
?fatal(error_scanning_entity_ref,S)
Comment on lines +2888 to +2889
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an exit, double checked the code.

end.


Expand Down Expand Up @@ -3939,17 +3940,15 @@ predefined_entity(_) -> false.
check_entity_recursion(EName,
S=#xmerl_scanner{entity_references=EntityRefList}) ->
Set = sofs:family(EntityRefList),
case catch sofs:family_to_digraph(Set, [acyclic]) of
{'EXIT',{cyclic,_}} ->
?fatal({illegal_recursion_in_Entity, EName}, S);
DG ->
try sofs:family_to_digraph(Set, [acyclic]) of
DG ->
digraph:delete(DG),
ok
ok
catch
error:{cyclic,_} ->
?fatal({illegal_recursion_in_Entity, EName}, S)
end.




%%%%%%% [15] Comment
scan_comment(Str, S) ->
scan_comment(Str, S, _Pos = undefined, _Parents = [], _Lang = []).
Expand Down
9 changes: 5 additions & 4 deletions lib/xmerl/src/xmerl_simple.erl
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@ scanner_options(Opts) ->
{close_fun, fun close/1}]).

scanner_options([H|T], Opts) ->
case catch keyreplace(H, 1, Opts) of
false ->
scanner_options(T, [H|Opts]);
NewOpts ->
try keyreplace(H, 1, Opts) of
NewOpts ->
scanner_options(T, NewOpts)
catch
throw:false ->
scanner_options(T, [H|Opts])
end;
scanner_options([], Opts) ->
Opts.
Expand Down
27 changes: 18 additions & 9 deletions lib/xmerl/src/xmerl_validate.erl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ validate(#xmerl_scanner{doctype_name=DTName,doctype_DTD=OpProv},
{error, {mismatched_root_element,Name,DTName}};
validate(#xmerl_scanner{rules=Rules}=S,
XML=#xmlElement{name=Name})->
catch do_validation(read_rules(Rules,Name),XML,Rules,S);
try
do_validation(read_rules(Rules,Name),XML,Rules,S)
catch
%% Just to make it compatible with old catch result
error:Reason:StackTrace -> {'EXIT', {Reason,StackTrace}};
exit:Reason -> {'EXIT', Reason}
end;
validate(_, XML) ->
{error, {no_xml_element, XML}}.

Expand All @@ -47,12 +53,8 @@ validate(_, XML) ->
do_validation(undefined,#xmlElement{name=Name}, _Rules,_S) ->
{error,{unknown_element,Name}};
do_validation(El_Rule,XML,Rules,S)->
case catch valid_attributes(El_Rule#xmlElement.attributes,
XML#xmlElement.attributes,S) of
{'EXIT',Reason} ->
{error,Reason};
{error,Reason} ->
{error,Reason};
try valid_attributes(El_Rule#xmlElement.attributes,
XML#xmlElement.attributes,S) of
Attr_2->
% XML_=XML#xmlElement{attributes=Attr_2},
El_Rule_Cont = El_Rule#xmlElement.content,
Expand All @@ -69,6 +71,11 @@ do_validation(El_Rule,XML,Rules,S)->
XMLS ->
XML#xmlElement{attributes=Attr_2,content=XMLS}
end
catch
exit:Reason ->
{error,Reason};
throw:{error,Reason} ->
{error,Reason}
end.

check_direct_ws_SDD(XML,always_preserve) ->
Expand Down Expand Up @@ -451,9 +458,11 @@ parse(El_Name, [#xmlElement{name=El_Name} = XML |T], Rules, _WSaction, S)
{[XML_], T}
end;
parse(any, Cont, Rules, _WSaction, S) ->
case catch parse_any(Cont, Rules, S) of
Err = {error, _} -> Err;
try parse_any(Cont, Rules, S) of
ValidContents -> {ValidContents, []}
catch
throw:{error, _} = Err ->
Err
end;
parse(El_Name, [#xmlElement{name=Name} |_T] = XMLS, _Rules, _WSa, _S) when is_atom(El_Name) ->
{error,
Expand Down
42 changes: 22 additions & 20 deletions lib/xmerl/src/xmerl_xpath_pred.erl
Original file line number Diff line number Diff line change
Expand Up @@ -788,28 +788,30 @@ normalize([], _S, Acc) ->
scan_number([H|T]) when ?whitespace(H) ->
scan_number(T);
scan_number("-" ++ T) ->
case catch xmerl_xpath_scan:scan_number(T) of
{{number, N}, Tail} ->
case is_all_white(Tail) of
true ->
N;
false ->
'NaN'
end;
_Other ->
'NaN'
try
{{number, _, N}, Tail} = xmerl_xpath_scan:scan_number(T),
case is_all_white(Tail) of
true ->
N;
false ->
'NaN'
end
catch
_:_ ->
'NaN'
end;
scan_number(T) ->
case catch xmerl_xpath_scan:scan_number(T) of
{{number, N}, Tail} ->
case is_all_white(Tail) of
true ->
N;
false ->
'NaN'
end;
_Other ->
'NaN'
try
{{number, _, N}, Tail} = xmerl_xpath_scan:scan_number(T),
case is_all_white(Tail) of
true ->
N;
false ->
'NaN'
end
catch
_:_ ->
'NaN'
end.

is_all_white([H|T]) when ?whitespace(H) ->
Expand Down
Loading
Loading