From d794566363e12a86488a18f2eef9980cbe157b04 Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Fri, 23 Aug 2019 14:45:15 +0200 Subject: [PATCH] Fix check for no maps in keys --- quickcheck/aeb_fate_encoding_tests.erl | 1 + quickcheck/aefate_eqc.erl | 24 ++++++++++++++++++++++++ src/aeb_fate_encoding.erl | 6 ++++++ 3 files changed, 31 insertions(+) diff --git a/quickcheck/aeb_fate_encoding_tests.erl b/quickcheck/aeb_fate_encoding_tests.erl index 1bd8e1e..63993cc 100644 --- a/quickcheck/aeb_fate_encoding_tests.erl +++ b/quickcheck/aeb_fate_encoding_tests.erl @@ -22,5 +22,6 @@ quickcheck_test_() -> {setup, fun() -> eqc:start() end, [ ?EQC_EUNIT(aefate_type_eqc, prop_roundtrip, 1000), ?EQC_EUNIT(aefate_eqc, prop_serializes, 1000), + ?EQC_EUNIT(aefate_eqc, prop_no_maps_in_keys, 1000), ?EQC_EUNIT(aefate_eqc, prop_idempotent, 1000) ]}. diff --git a/quickcheck/aefate_eqc.erl b/quickcheck/aefate_eqc.erl index 6b6db82..e9368fd 100644 --- a/quickcheck/aefate_eqc.erl +++ b/quickcheck/aefate_eqc.erl @@ -10,6 +10,7 @@ -module(aefate_eqc). -include_lib("eqc/include/eqc.hrl"). +-include("../include/aeb_fate_data.hrl"). -compile([export_all, nowarn_export_all]). @@ -43,6 +44,18 @@ prop_serializes() -> {size, size(Binary) < 500000}])) end)). +prop_no_maps_in_keys() -> + ?FORALL(FateData, fate_bad_map(), %% may contain a map in its keys + begin + HasMapInKeys = lists:any(fun(K) -> has_map(K) end, maps:keys(FateData)), + try aeb_fate_encoding:serialize(FateData), + ?WHENFAIL(eqc:format("Should not serialize, contains a map in key\n", []), + not HasMapInKeys) + catch error:Reason -> + ?WHENFAIL(eqc:format("(~p) Should serialize\n", [Reason]), HasMapInKeys) + end + end). + prop_fuzz() -> in_parallel( ?FORALL(Binary, ?LET(FateData, ?SIZED(Size, resize(Size div 4, fate_data())), aeb_fate_encoding:serialize(FateData)), @@ -167,3 +180,14 @@ injection(Binary) -> is_empty(L) -> ?WHENFAIL(eqc:format("~p\n", [L]), L == []). + +has_map(L) when is_list(L) -> + lists:any(fun(V) -> has_map(V) end, L); +has_map(T) when is_tuple(T) -> + has_map(tuple_to_list(T)); +has_map(M) when is_map(M) -> + true; +has_map(?FATE_STORE_MAP(_, _)) -> + true; +has_map(_) -> + false. diff --git a/src/aeb_fate_encoding.erl b/src/aeb_fate_encoding.erl index 3706322..1dcf8c8 100644 --- a/src/aeb_fate_encoding.erl +++ b/src/aeb_fate_encoding.erl @@ -487,5 +487,11 @@ sort(KVList) -> valid_key_type(K) when ?IS_FATE_MAP(K) -> error({map_as_key_in_map, K}); +valid_key_type(?FATE_STORE_MAP(_, _) = K) -> + error({map_as_key_in_map, K}); +valid_key_type(K) when is_list(K) -> + lists:all(fun(E) -> valid_key_type(E) end, K); +valid_key_type(K) when is_tuple(K) -> + lists:all(fun(E) -> valid_key_type(E) end, tuple_to_list(K)); valid_key_type(_K) -> true.