diff --git a/c_src/exml.cpp b/c_src/exml.cpp index 56d188c..ab64b18 100644 --- a/c_src/exml.cpp +++ b/c_src/exml.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -551,6 +552,13 @@ static ERL_NIF_TERM parse_next(ErlNifEnv *env, int argc, enif_make_string(env, result.error_message.c_str(), ERL_NIF_LATIN1)); } + // Raise an exception when null character is found. + std::size_t rest_size = &Parser::buffer.back() - result.rest; + if (std::strlen(reinterpret_cast(result.rest)) != rest_size) + return enif_make_tuple2( + env, atom_error, + enif_make_string(env, "null character found in buffer", ERL_NIF_LATIN1)); + return enif_make_tuple3( env, atom_ok, element, enif_make_uint64(env, result.rest - Parser::buffer.data())); diff --git a/test/exml_stream_tests.erl b/test/exml_stream_tests.erl index 5420f3a..99b8e0a 100644 --- a/test/exml_stream_tests.erl +++ b/test/exml_stream_tests.erl @@ -191,18 +191,24 @@ stream_max_child_size_test() -> infinite_stream_partial_chunk_test() -> {ok, Parser0} = exml_stream:new_parser([{infinite_stream, true}, {autoreset, true}]), - {ok, Parser1, Open} = exml_stream:parse(Parser0, <<"">>), + {ok, Parser1, Open} = exml_stream:parse(Parser0, <<"">>), ?assertEqual( [#xmlel{name = <<"open">>, - attrs = [{<<"xmlns">>, <<"urn:ietf:params:xml:ns:xmpp-framing">>}, - {<<"to">>, <<"i.am.banana.com">>}, - {<<"version">>, <<"1.0">>}]}], + attrs = [{<<"xmlns">>, <<"urn:ietf:params:xml:ns:xmpp-framing">>}, + {<<"to">>, <<"i.am.banana.com">>}, + {<<"version">>, <<"1.0">>}]}], Open), {ok, Parser2, A} = exml_stream:parse(Parser1, <<"">>), - ?assertEqual([#xmlel{name = <<"a">>, attrs = []}], A), - {ok, Parser3, Empty0} = exml_stream:parse(Parser2, <<" ">>), - ?assertEqual([], Empty0), - {ok, Parser4, Empty1} = exml_stream:parse(Parser3, <<">), - ?assertEqual([], Empty1), - {ok, _Parser5, B} = exml_stream:parse(Parser4, <<">">>), - ?assertEqual([#xmlel{name = <<"b">>, attrs = []}], B). + ?assertEqual([#xmlel{name = <<"a">>, attrs = []}], A), + {ok, Parser3, Empty0} = exml_stream:parse(Parser2, <<" ">>), + ?assertEqual([], Empty0), + {ok, Parser4, Empty1} = exml_stream:parse(Parser3, <<">), + ?assertEqual([], Empty1), + {ok, _Parser5, B} = exml_stream:parse(Parser4, <<">">>), + ?assertEqual([#xmlel{name = <<"b">>, attrs = []}], B). + +null_character_test() -> + {ok, P1} = exml_stream:new_parser(), + ?assertMatch({error, _}, exml_stream:parse(P1, <<"\0">>)), + {ok, P2} = exml_stream:new_parser(), + ?assertMatch({error, _}, exml_stream:parse(P2, <<"\0">>)).