diff options
author | ILYA Khlopotov <iilyak@apache.org> | 2018-11-22 20:25:58 +0000 |
---|---|---|
committer | ILYA Khlopotov <iilyak@apache.org> | 2018-11-23 14:11:13 +0000 |
commit | 14f0e53795108b55a2621da419ce6802d346ee0d (patch) | |
tree | 20182ac1691543630e7054430560b8129416b9b0 | |
parent | bae96cd40be5d952b2a35a39caa3f308bbe9d0b5 (diff) | |
download | couchdb-14f0e53795108b55a2621da419ce6802d346ee0d.tar.gz |
Replace erl_parse based parser with our own
-rw-r--r-- | src/couch/src/couch_flags_config.erl | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/src/couch/src/couch_flags_config.erl b/src/couch/src/couch_flags_config.erl index 2d4532a88..513a8154f 100644 --- a/src/couch/src/couch_flags_config.erl +++ b/src/couch/src/couch_flags_config.erl @@ -21,6 +21,7 @@ ]). -define(DATA_INTERVAL, 1000). +-define(MAX_FLAG_NAME_LENGTH, 256). -type pattern() :: binary(). %% non empty binary which optionally can end with * @@ -120,14 +121,32 @@ parse_flags(_Tokens, _) -> [flag_id()] | {error, Reason :: term()}. parse_flags_term(FlagsBin) -> - case couch_util:parse_term(<<"[", FlagsBin/binary, "]">>) of - {ok, Flags} -> - lists:usort(Flags); - Term -> - {error, { - "Flags should be list of atoms (got \"~s\"): ~p", - [FlagsBin, Term] - }} + {Flags, Errors} = lists:splitwith(fun erlang:is_atom/1, + [parse_flag(F) || F <- split_by_comma(FlagsBin)]), + case Errors of + [] -> + lists:usort(Flags); + _ -> + {error, { + "Cannot parse list of tags: ~n~p", + Errors + }} + end. + +split_by_comma(Binary) -> + case binary:split(Binary, <<",">>, [global]) of + [<<>>] -> []; + Tokens -> Tokens + end. + +parse_flag(FlagName) when size(FlagName) > ?MAX_FLAG_NAME_LENGTH -> + {too_long, FlagName}; +parse_flag(FlagName) -> + FlagNameS = string:strip(binary_to_list(FlagName)), + try + list_to_existing_atom(FlagNameS) + catch + _:_ -> {invalid_flag, FlagName} end. -spec parse_pattern(Pattern :: binary()) -> parse_pattern(). @@ -337,4 +356,19 @@ test_config() -> {"flag_bar||shards/test/exact", "true"} ]. +parse_flags_term_test_() -> + LongBinary = binary:copy(<<"a">>, ?MAX_FLAG_NAME_LENGTH + 1), + ExpectedError = {error, {"Cannot parse list of tags: ~n~p", + [{too_long, LongBinary}]}}, + ExpectedUnknownError = {error,{"Cannot parse list of tags: ~n~p", + [{invalid_flag,<<"dddddddd">>}]}}, + [ + {"empty binary", ?_assertEqual([], parse_flags_term(<<>>))}, + {"single flag", ?_assertEqual([fff], parse_flags_term(<<"fff">>))}, + {"sorted", ?_assertEqual([aaa,bbb,fff], parse_flags_term(<<"fff,aaa,bbb">>))}, + {"whitespace", ?_assertEqual([aaa,bbb,fff], parse_flags_term(<<"fff , aaa, bbb ">>))}, + {"error", ?_assertEqual(ExpectedError, parse_flags_term(LongBinary))}, + {"unknown_flag", ?_assertEqual(ExpectedUnknownError, parse_flags_term(<<"dddddddd">>))} + ]. + -endif. |